TESTING / DEVELOPMENTappendix-g-implementation-status.md
Status dokumen bukan klaim bahwa fiturnya sudah tersedia.

RFC dan proposal mencatat rancangan. Untuk kemampuan yang benar-benar dapat dipakai, lihat matriks kapabilitas runtime dan catatan rilis.

Appendix G implementation status

Appendix G is a design specification for a layered YAZA application. Its sample code describes desired language and library APIs; it is not directly executable in the current compiler. This document tracks implemented behavior separately from planned syntax and examples.

Current implementation

  • 2026-10-28 — Descriptor-pressure recovery and empty-request EOF: accept() now exposes the saturating yaza_http_accept_backoffs_total counter when real EMFILE/ENFILE errors pause listener readiness for one second. A macOS loopback integration lowers RLIMIT_NOFILE, forces EMFILE, frees descriptors, verifies the backoff counter and listener recovery, and confirms a queued client that closed before sending bytes does not produce a false HTTP 400. Raw-TCP checks also prove a complete half-closed GET still receives 200, incomplete headers and bodies receive 400, those status metrics and access logs are correct, and closed clients release their connection slots. The API concurrency harness passes normally, under ASan/UBSan, and under ThreadSanitizer. System-wide ENFILE and Linux remain unverified.

  • 2026-10-28 — Observable HTTP connection-capacity rejection: When the configured connection table is full, the event loop closes each excess accepted TCP connection without parsing it or sending an HTTP response, and increments the saturating Prometheus counter yaza_http_connections_rejected_total. A loopback regression holds the only configured slot, confirms an extra client is closed, confirms the active connection still serves /metrics, checks the counter, releases the slot, and confirms the listener accepts a new health request. The API concurrency harness passes normally, under ASan/UBSan, and under ThreadSanitizer on macOS. Linux epoll behavior remains unverified.

  • 2026-10-28 — Bounded net_read buffer lifetime: Successful reads now shrink their owned allocation to the number of bytes received; EOF and every error path release the temporary buffer. A runtime harness checks that a four-byte short read retains four bytes, 64 repeated 1 MiB timeouts retain under 16 KiB of arena memory (error values only), EOF retains zero bytes, and cancellation releases the 1 MiB buffer. Normal, ASan/UBSan, and ThreadSanitizer runs pass on macOS. This validates YAZA allocator accounting for the tested native paths, not process RSS or every TLS provider.

  • 2026-10-28 — API socket waits observe request cancellation: Native YAZA TCP/TLS readiness waits now poll active API cancellation in slices of at most 50 ms. net_read and net_write return a fixed cancellation error promptly when the request is cancelled; the route worker then follows its existing cancellation/deadline completion path. The network-transport harness verifies a blocked socket read exits within 500 ms after cancellation; normal, ASan/UBSan, and ThreadSanitizer runs pass on macOS. This is cancellation-aware blocking I/O, not language-level async or readiness-driven PostgreSQL. Synchronous DNS lookup remains non-cancellable.

  • 2026-10-28 — PostgreSQL pool waits observe API cancellation: A worker waiting for a lease now checks its request cancellation flag before each pool scan and after timed condition-variable waits. Since pool waits are sliced to at most 50 ms, cancelled or expired API work stops waiting within one slice instead of occupying a worker for the entire pool-acquisition timeout. The PostgreSQL pool harness passes normally, under ASan/UBSan, and under ThreadSanitizer on macOS. This does not interrupt a query or connection operation already in progress; those still depend on database/socket timeouts and cooperative handler behavior.

  • 2026-10-28 — Independently bounded API worker admission: YAZA_API_MAX_IN_FLIGHT now configures the combined number of queued, executing, and completed-but-not-yet-delivered handler jobs, from 1 through the configured connection capacity. It defaults to the connection capacity, preserving existing behavior. Invalid values fail startup before listening. Saturated controller/readiness submissions receive a fixed HTTP 503 overload response and increment the rejection metric; health and metrics remain event-loop-served. The concurrency harness verifies two active handlers plus one queued job, rejection of the next job, healthy operational endpoints, and the counters; normal, ASan/UBSan, and ThreadSanitizer harness runs passed on macOS. Linux and live PostgreSQL saturation remain unverified.

  • 2026-10-28 — Shared Bearer token overlap rotation: API startup accepts a primary YAZA_API_TOKEN and an optional, distinct YAZA_API_TOKEN_SECONDARY; both must be 32–1,024 valid Bearer-token bytes. A secondary without a primary, a duplicate token, or an invalid token fails startup without exposing values. With both configured, each authentication attempt performs fixed-width comparisons against both slots. The API route-auth smoke passes normally and under ASan/UBSan, checking acceptance through both slots plus invalid configurations. The complete API HTTP CRUD smoke passes on the same runtime change, and the dotenv-loader smoke confirms the secondary variable is accepted from a private .env. A fresh yaza new --api smoke generated the starter and verified that .env.example contains the secondary key; the macOS bootstrap now asserts this output. The API starter documents a rolling-deployment sequence. This is overlap, not central revocation or per-user credential lifecycle.

  • 2026-10-28 — HTTP HEAD and 405 Allow: Every registered GET route also serves HEAD through the same handler and inherited auth, rate-limit, and CORS policy. It reports the GET representation's Content-Length and other headers while transmitting no response body; /healthz, /readyz, and /metrics also support HEAD. Allow responses include HEAD wherever GET is available. OpenAPI and Postman generation emit a bodyless HEAD operation/request for each GET route. The complete API HTTP smoke verifies route/auth behavior, header parity, zero transmitted body bytes, CORS and Allow; generation smoke verifies both generated formats. Normal and ASan/UBSan checks pass on macOS. Linux behavior and maximum header-size boundaries remain unverified.

  • 2026-10-28 — Automatic HTTP OPTIONS: A registered route or operational path now answers ordinary OPTIONS with 204, an empty body, and a path-specific Allow header including implicit HEAD for GET and OPTIONS itself. OPTIONS * reports the server-wide method set; unknown paths remain 404. When route methods carry different authentication metadata, the discovery request uses the most restrictive matching policy; JWT-only paths therefore still require a valid JWT. CORS preflight remains a separate strict path and validates the requested method and headers; an OPTIONS request with an allowed Origin but no Access-Control-Request-Method is handled as ordinary OPTIONS. The complete API smoke passes normally, and the route-auth smoke passes normally and under ASan/UBSan on macOS. Linux remains unverified.

  • 2026-10-28 — Explicit child-process environment: The native standard-library surface now includes process_env and process_timeout_env alongside process_capture_env. These variants pass exactly the supplied NAME=value entries, reject dynamic-loader variables, require explicit PATH directories to be absolute and traversal-free, and cap argument/environment lists at 256 entries, 8 KiB per entry, and 128 KiB aggregate bytes per list. The process environment test covers exact child variables, ambient-secret exclusion, loader/PATH and list-size rejection, successful launch, and timeout termination; normal and ASan/UBSan tests plus the runnable example pass on macOS arm64. Legacy process functions continue to inherit the parent environment, and command allowlists, cancellation, OS sandboxing, and Linux verification remain incomplete.

  • 2026-10-28 — Typed scalar-list API responses: Zero-argument API handlers now return List[Number], List[Int32], List[Float64], List[Boolean], or List[Text], and the runtime serializes each with type-checked bounded JSON encoding. Option[List[T]] maps none to 404 and serializes present values; Result[List[T], E] serializes successful values while retaining safe generic error handling. OpenAPI derives each array item schema from the handler's declared element type. The complete API fixture verifies all five scalar list types, optional and result forms, missing-value status, and generated schemas. The three-stage macOS self-host bootstrap passed, including normal and ASan/UBSan HTTP smokes, OpenAPI/Postman/Swagger generation, and all 43 language tests. Arbitrary nested/general collection codecs remain incomplete.

  • 2026-10-28 — Bounded process-local TTL cache: use "std/cache/ttl" exposes ttl_cache_get, ttl_cache_set, ttl_cache_remove, and ttl_cache_clear. The runtime holds at most 128 fixed-storage entries; keys are capped at 255 bytes, values at 4095 bytes, and TTL at seven days. Expiry uses monotonic time, concurrent access is mutex-protected, full-table writes evict the least-recently-used live entry, and removed/replaced/expired/cleared/shutdown entries are wiped. The language test covers set/get/replace/remove/clear and invalid TTLs; a runtime C harness covers expiry, LRU eviction, bounds, and concurrent callers in normal and ASan/UBSan builds. The cache is process-local and volatile; it is not suitable for secrets or authorization decisions and does not provide cross-process invalidation.

  • 2026-10-28 — Indexed validation paths for typed request arrays: Invalid elements in TextList, List[Shape], and primitive typed-array request fields now report their exact zero-based index, for example lines[1].quantity or labels[0]. Error-path validation and OpenAPI schemas accept only canonical indexes from 0 through 63, reject leading-zero and out-of-range indexes, and continue to enforce the 128-byte path cap. The API smoke covers first/second shape items, TextList and each primitive typed-array item type, indexed ApiError.InvalidInput/ValidationFailed, and rejection of unsafe indexes; generation smoke checks accepted and rejected path forms. The three-stage macOS bootstrap, all 42 language tests, OpenAPI/Postman/Swagger generation checks, and normal plus ASan/UBSan API HTTP smokes pass. Array-level errors such as malformed containers and item-count bounds report the field without an item index.

  • 2026-10-28 — Route-scoped JWT authentication and verified claim access: API routes and nested groups now accept auth jwt. The runtime verifies compact JWS tokens using only HS256 and a configured 32–4096-byte secret, requires typ: JWT, rejects unknown JOSE headers and non-canonical/padded base64url, validates the signature before reading claims, and requires exact configured iss and an aud string or non-empty string array containing the configured audience, plus an integer exp; optional integer nbf and iat are checked against the system clock. A verified expired token returns the safe TokenExpired 401 code. During a successfully authenticated JWT route handler, http_auth_claim_text("name") -> Option[Text] reads top-level string claims from a request-scoped copy of the verified payload; absent/non-string claims return none, decoded text is bounded to 1023 UTF-8 bytes, and the payload copy is wiped after request dispatch. Public and shared-Bearer routes cannot use a forged header to supply claims. JWT-only non-loopback mode requires at least one JWT route and an explicit auth policy on every declared route. OpenAPI marks JWT routes with bearer security and x-yaza-authentication: jwt-hs256; Postman generates Bearer auth. The API route middleware smoke covers valid, missing, expired, future, forged, wrong-algorithm, wrong-issuer, wrong-audience, matching and rejected string/array audience forms, and absent-config cases, JWT claim access including Unicode escapes and optional subject, spoofed-identity rejection, and JWT-only/no-static-token operation. The full macOS bootstrap passed the three-stage self-host build and 42/42 language tests. Token issuance, typed principal/role policy, ownership checks, revocation/key rotation, asymmetric algorithms, and TLS remain incomplete.

  • 2026-10-28 — Nested API route groups: route files now support indentation-scoped group "/prefix" [auth required|auth public|auth jwt] [rate_limit REQUESTS per WINDOW_MS] [cors "https://origin"]: blocks, nested static prefixes, and a "/" member route that resolves to the group base path. The compiler expands groups to final paths before controller-parameter validation, route-conflict detection, server-table generation, OpenAPI, and Postman generation. Group auth, rate-limit, and CORS policies inherit through nested groups; a route-level declaration overrides its inherited policy of the same kind. The layered API template and complete API fixture use grouped route declarations. OpenAPI/Postman generation, the complete loopback HTTP smoke, and the nested route-auth smoke pass; generation smoke rejects traversal (..) prefixes. The self-hosted compiler rebuild passes three stages with identical generated C and all 42 language tests. Group prefixes are intentionally static normalized paths; arbitrary group-scoped middleware remains open.

  • 2026-10-28 — Route-group rate-limit middleware: route groups and individual routes can declare rate_limit REQUESTS per WINDOW_MS; groups accept this alongside auth, and the policy inherits into nested groups unless a route supplies its own. Each policy has an IPv4-client token bucket scoped to the group path; separate groups have independent buckets, while the optional global limiter remains available and can be combined. Both policies run before auth; health, readiness, metrics, and CORS preflight retain their operational bypass. OpenAPI describes route limits through x-yaza-rateLimit; the runtime returns the safe 429 envelope and calculated Retry-After. The nested route-auth smoke proves limits shared across nested routes, 429 behavior, the header, OpenAPI output, and an unaffected route in another group. The bucket harness passes normally and under ASan/UBSan; the full macOS bootstrap passed three identical self-host stages and all 42 language tests. This is a bounded built-in middleware policy, not a general user-defined middleware chain or distributed quota service.

  • 2026-10-28 — Route- and group-scoped CORS origins: route declarations accept cors "https://origin"; route groups accept the same modifier and inherit it through nested groups, while a route declaration overrides the inherited origin. Origins are exact HTTP(S) origins without paths, and a scoped origin takes precedence over the global YAZA_CORS_ORIGIN for that route. The runtime applies the policy to actual responses and preflight, retaining declared-header validation; startup reports route-specific policies. OpenAPI records the effective origin as x-yaza-corsOrigin. The route middleware smoke verifies nested inheritance, an explicit override, denied origins, preflight headers, and generated documentation. General middleware composition and multi-origin lists remain incomplete.

  • 2026-10-27 — Typed-list iteration in the language core: for item in values: now accepts both TextList and supported concrete List[T] values, including primitive and declared-shape elements. The compiler evaluates the collection once, captures its starting length, and gives the loop variable the checked element type; appends made inside the loop are deferred until a later loop. tests/typed_list.test.yz covers primitive and shape iteration plus this fixed-length behavior, and examples/list_safe_access.yz demonstrates a list sum. All 42 language tests pass, and the three-stage self-host build emitted identical compiler C. This does not add generic functions, slicing, or a general collection library.

  • 2026-10-27 — Primitive typed arrays in API request and response shapes: API request shapes now decode List[Number], List[Int32], List[Float64], List[Boolean], and List[Text], including nullable Option[List[T]]. Each array is bounded to 64 items, checks each JSON element's kind and numeric range, and supports min_items/max_items; typed response serialization and OpenAPI/Postman generation preserve the declared element type. The API fixture covers successful round trips, omitted/null optional arrays, invalid element kinds and overflow, list bounds, generated schemas, and an absolute Postman URL. The full macOS bootstrap passed three self-hosted stages, all 42 language tests, normal and ASan/UBSan API HTTP smokes, and OpenAPI/Postman/Swagger generation checks. General collection codecs beyond these primitive arrays and declared-shape arrays remain incomplete.

  • 2026-10-27 — Typed arrays of shapes in API request bodies: http_body_shape decodes required List[DeclaredShape] and nullable Option[List[DeclaredShape]] fields. Each JSON array is capped at 64 items; every item must be an object satisfying its declared shape, nested scalar validation runs before controller dispatch, and min_items/max_items constraints are checked. OpenAPI describes item properties, required fields, nullable arrays, and item bounds; Postman includes the controller's JSON example. The api-complete loopback smoke checks success, absent/null optional lists, malformed array/item types, nested field validation, and item bounds. For List[Shape] items, nested validation paths include bounded canonical indexes from 0 through 63, such as lines[0].quantity; primitive-array element errors still identify the array field only. Primitive-array support was added in the following implementation update above.

  • 2026-10-27 — Bounded multi-error compiler checks: yaza check --format json first runs a normal compiler subprocess; when it fails on an eligible import-free, non-API source, it isolates each top-level function and the start: body by replacing unrelated bodies with type-correct stubs. The report collects up to three diagnostics per independent scope when it can safely repair prior errors, preserves the original source path and line/statement range, and continues to use the first-error report whenever isolation is unsupported. Across at most three probes, it repairs a mismatched explicitly typed let/var initializer using a supported default, a supported function return mismatch using its return default, or a non-Boolean assert with assert true; the repair keeps declaration names and line positions and exists only in the child source. Other errors stop that scope. Files are currently bounded to 96 KiB, 4,096 lines, and 32 functions; a shared budget caps isolated probes at 128. Supported stub returns are Number, Text, Boolean, Int32, Float64, TextList, and Option. tests/check-diagnostics.sh covers three typed initializer errors with a later use of the first binding, a return mismatch followed by a separate return-placement error, and an assert error followed by a typed initializer error. API sources, imported modules, malformed global declarations, unsupported return types, and other same-scope recovery remain incomplete.

  • 2026-10-27 — Conditional return-path checking: Non-void functions may end with a complete block or inline if/elif/else chain whose every branch returns; nested complete chains work as well. The compiler rejects a missing path return and does not let a return match nested under a conditional falsely satisfy an outer path. Sequential early returns followed by a fallback and direct exhaustive match returns remain supported. Mutable-label assignment with var label and set label = ... remains supported in conditional branches; it is distinct from returning a value. tests/return_flow.test.yz covers boundary behavior, nested branches, inline branches, sequential early returns, and a nested Option match; tests/elif.test.yz covers label assignment; two negative fixtures cover fallthrough and nested-match false positives. The macOS bootstrap passed three self-hosted compiler stages with byte-identical generated C, all 41 language tests, API smokes, and the return-flow ASan/UBSan build. Loops do not count as guaranteed returns because they may not execute. This is return-path checking for the supported constructs, not a general control-flow graph or unreachable-code analysis.

  • 2026-10-27 — Statement-range compiler diagnostics: Errors raised while compiling a source statement now include zero-based UTF-8 byte offsets spanning the non-indentation portion of that line. The VS Code extension translates the byte offsets to UTF-16 editor positions; its smoke covers an unsaved buffer containing a non-ASCII trailing comment. tests/check-diagnostics.sh, the VS Code extension suite, and the three-stage macOS bootstrap pass. These are statement-line ranges, not token-exact spans; failures before statement compilation may still have line-only ranges, multi-error aggregation can report up to three errors in each eligible function or start: scope when each encountered error before the bound is a supported typed initializer, return mismatch, or non-Boolean assert; unsupported contexts retain fatal-first behavior.

  • 2026-10-27 — Typed Product delete outcome: The Product repository and service now return Result[ProductDeleteOutcome, ApiError] for delete. The outcome is parsed as a shape, while the route's declared HTTP 204 still suppresses the response body as required. The API smoke confirms bodyless 204 behavior after successful typed deletion; OpenAPI contains no response content for 204. Typed collection results were still incomplete at that milestone; the following update adds Product list arrays.

  • 2026-10-27 — Typed Product collection results: Product list now returns Result[List[ProductRecord], ApiError] through controller, service, repository interface, and implementation. The repository converts its bounded JSON result with json_shape_list(Text); the native API dispatcher serializes the typed list as a JSON array, and OpenAPI derives array/items: ProductRecord from the declared result type. The API smoke verifies an array response and CRUD pagination; generation smoke verifies the matching OpenAPI schema; API layer conformance and the three-stage macOS bootstrap pass. This is a concrete typed collection path, not general typed repository code generation or runtime-polymorphic trait dispatch.

  • 2026-10-27 — Typed Product write results: Product create, replace, and patch now return Result[ProductRecord, ApiError] through controller, service, repository interface, and implementation. The shared repository adapter decodes bounded JSON with json_shape(Text) before returning a typed shape, while preserving the same JSON response fields on the wire. OpenAPI now derives ProductRecord schemas for GET, POST, PUT, and PATCH; generation and HTTP smoke verify these contracts and actual response bodies. The full macOS bootstrap passes three self-hosted compiler stages, 40/40 language tests, API layer/generation checks, and normal plus ASan/UBSan HTTP smokes. At that milestone, Product list had not yet acquired typed collection results; the later collection and handler updates below supersede that limitation.

  • 2026-10-27 — Initial typed Product lookup: json_shape(text) converts bounded JSON into a declared YAZA shape, including nested shapes and optional fields; malformed JSON, missing/extra keys, wrong types, overflow, and oversized payloads fail as none. Product GET /api/products/{id} first returned Result[ProductRecord, ApiError] through the controller, service, repository interface, and implementation, and OpenAPI derived the response schema from ProductRecord. The typed read/write updates above expand this slice; list typed collections and generalized typed repository/code generation remain incomplete.

  • 2026-10-27 — Maximum-size typed validation error responses: ApiError::ValidationFailed accepts at most 64 safe field paths, each at most 128 bytes. The response serializer now sizes its bounded output buffer from those limits instead of the previous fixed 4 KiB allocation, so a valid maximum-size error retains every field instead of silently falling back to an envelope without details. The HTTP smoke checks 64 paths at exactly 128 bytes and a serialized body larger than 4 KiB; normal and ASan/UBSan runs pass.

  • 2026-10-27 — OpenAPI numeric schema alignment: Typed API path/query parameters, scalar request bodies, nested request shapes, and shape responses now describe runtime values consistently: Number is a signed 64-bit integer, Int32 is a bounded 32-bit integer, and Float64 is a number. validate <field> integer on Float64 retains the IEEE-754 safe-integer interval. Generated schemas compose intrinsic ranges and user constraints with allOf rather than duplicate keywords. Generator smoke checks the response, path, query, and nested-body schemas; the full three-stage macOS bootstrap passed with 39/39 language tests and normal/sanitized API HTTP smokes.

  • 2026-10-27 — Single-line conditional chains: if condition: statement, elif condition: statement, and else: statement now compose into one scoped conditional chain. Single-line bodies use the same type checks, mutable-variable rules, loop-control checks, and block cleanup as indented bodies; following statements close the chain at the correct indentation. tests/elif.test.yz exercises early-return and var/set label styles across boundary values, including mixed inline/block branches, and examples/match-forms.yz includes a runnable chain. The full macOS bootstrap passed three self-hosted compiler stages with byte-identical generated C, all 39/39 language tests, API layer/generation checks, and normal plus ASan/UBSan HTTP smokes. This does not add conditional expressions or permit multiple statements on one physical line.

  • 2026-10-27 — Bounded integer validation for Float64 API fields: shape declarations accept validate <field> integer. The decoder checks the original decimal spelling, so Float64 rounding cannot turn a fractional input into an accepted integer. Whole-valued inputs in the IEEE-754 safe integer interval [-9007199254740991, 9007199254740991] pass; fractions and out-of-range values return a safe integer validation error before controller dispatch. Optional omitted/null fields skip the rule. OpenAPI emits nullable/required integer schemas with matching bounds and includes the error code. The api-complete fixture tests integer, exponent, fractional values that would round to whole Float64 values, both range boundaries, invalid field types, and generated schema; full bootstrap passed 39/39 language tests, API HTTP smoke normally and under ASan/UBSan, and generation smoke. This is API shape validation; it does not add a distinct language-level Int64 type.

  • 2026-10-27 — Typed Product request DTO flow: Product path and body values are read at the controller boundary and assembled into the shared ProductInput shape. Create, replace, patch, find, and delete pass that value explicitly through service and repository functions; list keeps explicit typed pagination. The repository no longer reads ambient HTTP request accessors or sets the HTTP response status, and DELETE 204 is declared on the route. Compiler conformance now requires ProductInput on the five request-taking CRUD operations and verifies matching interface, layer, and implementation signatures. The macOS self-hosted bootstrap passed three compiler stages with byte-identical generated C, 39/39 language tests, API layer conformance, generation smoke, and normal plus ASan/UBSan HTTP smoke. This removes request-state coupling from the Product repository example; general DTO/code generation, runtime-polymorphic dispatch, model-typed repository results, and the full RFC acceptance criteria remain incomplete.

  • 2026-10-27 — YAZA in-memory Product repository path: without DATABASE_URL, the generated Product repository now calls the YAZA std/api/memory_records adapter for list/find/create/replace/patch/delete and returns Result[Text, Text] outcomes for mapping to ApiError. The native boundary mutates the API's bounded in-memory resource table only; it no longer sends an HTTP response itself. The ordinary handler response path now serializes the repository result. Starter CRUD and the complete API HTTP fixture pass, including chunked JSON creation, and the self-hosted macOS bootstrap passes with 39/39 language tests and API smoke checks. This is still a demo store backed by a runtime-owned table, not general YAZA data structures, persistence, or runtime-polymorphic repository dispatch.

  • 2026-10-27 — Route-aware CORS request headers: CORS preflight now validates header names as HTTP tokens and permits common headers plus custom headers declared by the matched route's controller metadata. It returns the validated requested header list and varies cached preflight responses by origin, method, and requested headers. Undeclared custom headers are rejected. The full API HTTP smoke passes normally and under ASan/UBSan for a declared X-Client-Name header and a rejected undeclared header. The configured origin remains one exact origin for the whole server.

  • 2026-10-27 — Configurable HTTP deadlines: API projects can set YAZA_HTTP_REQUEST_TIMEOUT_MS from 1,000 to 300,000 ms, YAZA_HTTP_KEEP_ALIVE_TIMEOUT_MS from 1,000 to 60,000 ms, YAZA_HTTP_RESPONSE_WRITE_TIMEOUT_MS from 1,000 to 300,000 ms, and YAZA_HTTP_SHUTDOWN_GRACE_MS from 1,000 to 120,000 ms; defaults remain 5,000 ms. Startup validates and reports each effective value, and the Keep-Alive response header reflects its configured timeout rounded up to seconds. The full API smoke passes normally and under ASan/UBSan; it rejects out-of-range settings, verifies startup reporting and the keep-alive header, and confirms an incomplete request closes at a configured 1,000 ms deadline. The active-connection cap is configurable from 1 to 127 through YAZA_HTTP_MAX_CONNECTIONS (default 64), with one readiness-event slot reserved for the listener; shutdown grace covers queued HTTP responses, not background business work.

  • 2026-10-26 — Provider-neutral database value contract: std/db/core.yz now exposes DbValue cases for NULL, Boolean, Int32, Int64, Float64, Text, and Bytes; wrong-type accessors return none, preserving empty text separately from SQL NULL. DbCapabilities records explicit driver features and rejects invalid dependencies such as savepoints without transactions. Stable database error codes now include unavailable. std/db/postgres.yz maps shared values to typed PostgreSQL Bind parameters; SQL NULL requires a caller-supplied OID, while byte values retain binary contents through bytea encoding. Its result adapter decodes known integer, Boolean, bounded finite Float64, text, and bytea OIDs to DbValue, rejecting unsupported OIDs and malformed/out-of-range Float64 text. It returns fixed DbError categories/messages and does not forward server-provided text. Normal and ASan/UBSan database-core tests cover input/result mappings and error categories. Schema-to-shape mapping, provider-neutral connection lifecycle, pooling, and other engines remain absent.

  • 2026-10-26 — Structured database query slice: a native YAZA DbSelect value now holds a projection, one typed comparison, order, and page bounds. The PostgreSQL adapter generates the statement from validated and quoted identifiers, a closed operator variant, and separately bound non-NULL values. SQL NULL comparisons lower to IS NULL/IS NOT NULL; unsafe identifiers and invalid page/filter combinations fail closed. db_postgres_select executes the generated query and maps PostgreSQL failures to fixed database errors while exposing only validated SQLSTATEs. The focused query test passes under ASan/UBSan. A new live PostgreSQL smoke creates an isolated temporary relation, inserts bound values, executes a filtered/ordered/paged DbSelect, checks decoded rows, and confirms an injection-shaped filter value matches nothing. The PostgreSQL 18 container API smoke now runs this test and passed. The compiler's db.read ...: block, multiple conditions/joins, schema-backed identifier/type checks, and typed row-shape mapping are still missing.

  • 2026-10-26 — API graceful shutdown drain: SIGINT/SIGTERM now prevents further accepts, performs a zero-time readiness collection after an interrupted wait, completes requests already readable on accepted sockets, forces their response connection closed, and then closes incomplete/idle sockets. tests/http_shutdown.c drives a fragmented request, signals the server as the final bytes arrive, and requires the complete response, Connection: close, EOF, and a clean process exit. Normal and ASan/UBSan HTTP smokes cover this path. This drains only work already in the single-threaded runtime; the configurable response-drain grace does not cover background jobs or queued business work.

  • 2026-10-26 — Bearer credential parsing hardening: YAZA_API_TOKEN is now validated at startup as a bounded 1–1024 byte Bearer token using the RFC token character set; malformed values are rejected without echoing them. Authorization scheme matching is case-insensitive and accepts the standard space separator. Duplicate headers remain fail-closed. Candidate comparison scans a fixed 1024-byte padded buffer and wipes temporary comparison buffers. Normal and ASan/UBSan API HTTP smokes check invalid and oversized configuration, a wrong token of a different length, and a mixed-case bEaReR scheme with repeated spaces. The full macOS bootstrap passed three self-host stages with identical generated C and 33/33 language tests.

  • 2026-10-28 — Shared Bearer token minimum and generator: API startup now rejects YAZA_API_TOKEN shorter than 32 bytes while retaining the 1,024-byte maximum, RFC Bearer character validation, and fixed-width comparison. The complete API HTTP smoke passed with a short value rejected and an exact 32-byte test credential accepted; route-auth smoke passed normally and under ASan/UBSan. yaza secret token now generates 32 operating-system CSPRNG bytes, encodes them as 64 lowercase hexadecimal characters, and wipes the temporary random byte buffer before printing. Its smoke verifies format, length, uniqueness across two calls, and invalid usage. The three-stage macOS bootstrap passed with 44/44 language tests. The minimum-length check cannot measure entropy for manually chosen values; credential overlap, rotation, and revocation remain unimplemented.

  • 2026-10-26 — Argon2id password-hash standard-library slice: std/crypto/password.yz now exposes hashing, verification, and rehash detection through a statically linked Argon2 reference provider. Parameters are pinned to Argon2id v=19, 19 MiB, two iterations, one lane, with a 16-byte OS-random salt, a 32-byte digest, and a 1024-byte input limit. The runtime checks bounded PHC metadata before calling the provider and explicitly wipes temporary password/salt Bytes; immutable source Text is not erased. The full 32-test suite and three-stage self-host bootstrap passed; the latest password-hash test, including fresh-salt uniqueness and the over-limit rejection, passed normally and separately under ASan/UBSan. The macOS package payload includes the provider archive, header, and license, and a program compiled and ran against the extracted bundle; installation is not yet verified, and the managed host adds AppleDouble records. Linux and account/session flows remain incomplete.

  • 2026-10-26 — HTTP request correlation IDs: The shared HTTP response writer generates a 128-bit ID from an OS random stream for each request, includes it as X-Request-ID on success and error responses (including bodyless 204 responses), and records the same value in the structured http_request access event. CORS responses expose the header to browser code. The API smoke verifies the ID format, distinct IDs for separate requests, matching access-log correlation, and CORS exposure. This is correlation metadata only; trace propagation, spans, and async log sinks are not implemented.

  • 2026-10-26 — Pure-YAZA API startup and readiness: API declarations now accept startup <function> and readyz <function>. The compiler requires reachable, zero-argument Number and Boolean functions, respectively, and generated API builds no longer define YAZA_WITH_POSTGRES or link libpq. The API template uses its YAZA PostgreSQL client to configure statement/lock/idle-transaction timeouts, check the migrated record table, insert sample rows idempotently, and answer /readyz with a fresh bounded connection; each readiness operation has a 500 ms budget. Startup errors expose only a stable numeric code; database URLs and server messages stay private. Compiler conformance rejects absent, duplicate, parameterized, or wrong-type hooks. otool -L and undefined-symbol inspection show no libpq dependency; 32/32 language tests, 2/2 API template tests, 22 API layer/lifecycle conformance cases, generation smoke, and full no-database HTTP smoke pass. PostgreSQL URI/TLS-policy tests reject unsafe remote modes and non-numeric loopback plaintext. tests/api-postgres-container-smoke.sh provisions an isolated PostgreSQL 18.6 container, applies the migration, and runs the full database-configured API smoke. It verified startup seeding, CRUD, restart persistence, /readyz returning PostgreSQL-specific 503 in about 500 ms while the database was paused, recovery to 200 after it resumed, and a safe 503 when PostgreSQL was terminated during a create. With a fixed published loopback port, the same API process also returns /readyz 200 after PostgreSQL is restarted. This remains one local server version; remote TLS and automated live-database CI remain open. The interrupted create is not automatically retried and returns 503.

  • 2026-10-26 — Executable API interface bindings: Service and repository metadata require one bind <method> to <function> per interface method. yaza check requires each target to be declared in the matching implementation file and reachable from the executable application module graph. Method parameter counts and supported types, plus return types, must match exactly between interface metadata, layer metadata, and the bound YAZA implementation. The API template now passes typed limit and offset values through Product controller → service → repository signatures; it rejects invalid page bounds consistently as InvalidInput. Layer conformance accepts the template and rejects arity/type mismatches, bad call-chain edges, missing/duplicate bindings, unknown targets, and return mismatches. The targeted layer conformance, generation smoke, and HTTP smoke pass. The PostgreSQL 18 container smoke also passes migration, structured-query execution, paginated CRUD HTTP behavior, database pause/recovery, and restart recovery in the same API process. Invocation remains static function calls: runtime-polymorphic dispatch, generic trait resolution, and typed Product model results remain incomplete.

  • 2026-10-26 — PostgreSQL SQLSTATE to safe API errors: std/pg/errors.yz validates the SQLSTATE in the driver's fixed PostgreSQL error prefix and classifies unique constraints, other constraint failures, query cancellation/timeouts, connection failures, transaction conflicts, and other server errors. The Product API maps unique violations to AlreadyExists, other constraint failures to Conflict, and statement timeouts to Timeout; infrastructure and unclassified failures remain Unavailable. PostgreSQL messages and SQL text are not copied into HTTP responses. tests/pg_errors.test.yz covers recognized, malformed, and untrusted error strings; tests/api-postgres-container-smoke.sh installs trigger fixtures in disposable PostgreSQL 18.6 to produce SQLSTATE 23505, 23514, and 57014, verifying safe HTTP responses 409 already_exists, 409 conflict, and 504 timeout. It also stops PostgreSQL during a delayed active create and verifies the request returns safe 503 unavailable with Retry-After; server error details do not appear in responses. A fixed published host port lets the smoke restart PostgreSQL and prove that the same API process returns readiness 200 afterward. Automatic retry of a failed operation and live mapping coverage for other SQLSTATE classes remain outstanding.

  • 2026-10-26 — Typed email syntax validation for API shapes: validate email email is accepted only on Text/Option[Text] request fields and checked before controller dispatch. The bounded ASCII validator enforces a dot-atom local part (up to 64 bytes), one @, DNS-style domain labels (up to 63 bytes each), a multi-label domain, and a 254-byte overall limit. It deliberately does not claim mailbox existence, quoted local parts, or internationalized-address support. Invalid input returns the safe invalid_email field error; OpenAPI emits format: email. The native compiler rejects the rule on non-Text fields. Normal and ASan/UBSan HTTP smoke cover valid addresses, malformed dots/labels/domains, non-ASCII input, and optional null/omission; generation smoke checks the nullable OpenAPI email schema.

  • 2026-10-26 — Bounded pattern validation for API shapes: validate <field> pattern "^...$" now accepts a deliberately small anchored ASCII subset: literals, ., character classes/ranges/negation, escaped punctuation, and ?, *, +. Patterns are capped at 128 bytes and 64 atoms; request text is capped at 1023 UTF-8 bytes. Matching uses bounded dynamic programming with O(pattern atoms × input bytes) work and no backtracking. Groups, alternation, shorthand classes, backreferences, Unicode matching, and bounded quantifiers are rejected; | is reserved by the current metadata format. Mismatches return a safe pattern field error, and OpenAPI emits both the declared pattern and x-yaza-patternMode: anchored-ascii. The regex unit test, invalid-type/syntax compiler fixtures, API generation smoke, and full HTTP smoke passed; the API smoke also passed under ASan/UBSan.

  • 2026-10-26 — Canonical HTTP error envelope normalization: the shared HTTP response writer now converts runtime-generated legacy string errors for error status codes into a bounded nested error.type/error.code envelope. This covers generic HTTP status errors, legacy Option/Result handler bodies, and PostgreSQL CRUD failures; already-structured typed ApiError and field-validation envelopes remain intact. Authentication responses now use the same writer for content length, security headers, CORS, WWW-Authenticate, connection-close behavior, and request logging. Validation field paths and code tokens are checked before serialization. Normal and ASan/UBSan HTTP smoke verifies auth, duplicate headers, unknown route/method, typed errors, and optional-handler error responses. OpenAPI generation smoke verifies common status envelopes and auth/retry headers on each operation. One source-level typed error contract remains incomplete.

  • 2026-10-26 — Route-level success status contracts: API routes may declare status 200, 201, 202, or 204 between the path and handler/controller target. The compiler carries the declaration into route metadata and OpenAPI; runtime enforces the declared code over a conflicting http_set_status call. A 204 handler may return an empty value and emits no body, Content-Type, or Content-Length. The isolated fixture verifies GET and POST 202, setter precedence, OpenAPI output, and bodyless 204; it runs during macOS bootstrap. Other success codes and a unified typed response contract remain incomplete.

  • 2026-10-27 — API starter profiles and unified generated docs: yaza new --api remains the layered Product Catalog starter; yaza new --minimal-api adds a small project with routes directly in src/main.yz and no controller/service/repository scaffold. yaza generate writes Postman, OpenAPI 3.1, and Swagger-compatible JSON together under docs/api/; individual flags generate one artifact. Scalar request-body examples are synthesized from declared field types by default; optional example json {...} customizes generated clients/docs only (the earlier body json spelling remains a compatibility alias). Postman includes absolute URLs and path/query variables. API template and minimal-profile generation/build tests are included in the native bootstrap; the full database-backed API release profile remains incomplete.

  • 2026-10-27 — Numeric match assignment: guarded numeric match can now assign its selected result to an existing mutable variable with set label = match value:. The subject is evaluated once, else is mandatory, and every arm is checked against the variable's declared type. tests/numeric_match.test.yz covers assignment at negative, zero, and positive boundaries; the full macOS bootstrap passed three self-hosted compiler stages, emitted byte-identical generated C, and passed 38/38 language tests plus API smoke coverage. The feature does not add general variant/Option/Result match expressions or allow match inside arbitrary nested expressions.

  • 2026-10-27 — Match forms and sum-type results: variant, Option, and Result matches can return arm values or assign them to a previously declared mutable var with set. Combined with block if/elif/else, one-line if, early return, and numeric guarded matches, the compiler supports the three classification styles shown in the tutorial. tests/value_match.test.yz covers sum-type return/assignment and type/exhaustiveness failures; examples/match-forms.yz is the runnable overview. Bootstrap and the full 39/39 language suite passed. Match values in arbitrary expression positions such as a let initializer or nested call remain unsupported.

  • 2026-10-27 — Match declaration initializers: Exhaustive numeric and variant/Option/Result matches can now initialize typed let or var values. The declared name becomes visible only after the match closes, so arm payload bindings cannot read an uninitialized destination. tests/value_match.test.yz exercises numeric, variant, and Option initializers; the bootstrap rejects missing cases and incompatible arm types. The runnable examples/match-forms.yz covers conditional assignment, early return, direct match return, and a match initializer. The three-stage macOS bootstrap passed with byte-identical C, all 39 language tests, API smokes, and the new ASan/UBSan value-match harness. Nested matches inside calls/calculations and direct match arguments remain unsupported.

  • 2026-10-26 — Nonblocking HTTP response writes: API responses are now copied into bounded per-connection buffers and flushed through kqueue/epoll writable readiness, in 64 KiB event-loop quanta. Each response is capped at 16 MiB, all pending response buffers together at 64 MiB, and a response has a five-second absolute send deadline. Shutdown stops accepts, handles requests already readable, and drains queued responses for at most five seconds. tests/http_async_response.c proves a slow reader yields to a second client, resumes to completion, releases pending-memory accounting, and completes an already-queued response during shutdown. The official macOS bootstrap passed three self-hosted stages with identical generated C, 34/34 language tests, and normal plus ASan/UBSan HTTP smokes. Only macOS kqueue was exercised; Linux epoll remains source-only, and route handlers/PostgreSQL calls still run synchronously.

  • 2026-10-26 — Scheduled HTTP request readers: the native HTTP server now creates one bounded scheduler task per accepted connection. Each task incrementally reads/parses that connection's request and suspends through the kqueue/epoll readiness bridge until more bytes are available. The API loop still runs on one thread; route handlers and PostgreSQL work remain synchronous; response writes use the bounded nonblocking output path documented in the following history entry. The keep-alive fixture now sends a partial pipelined request, verifies an unrelated health request still succeeds, then sends the remaining bytes and verifies the original request resumes. sh scripts/bootstrap-macos-cli.sh passed, including three self-hosted compiler stages with identical generated C, 29/29 YAZA tests, API HTTP smoke, and the new fragmented-pipeline scenario. Only the macOS kqueue backend was exercised; this is not language-visible async or asynchronous business-handler support.

  • 2026-10-25 — Configurable per-client API rate limiting: the native HTTP runtime accepts YAZA_RATE_LIMIT_REQUESTS and optional YAZA_RATE_LIMIT_WINDOW_MS, validates their ranges before binding, and applies a bounded token bucket keyed by the TCP peer's IPv4 address before authentication. A fixed 1,024-entry table fails closed for new clients when full and recycles entries after the idle window; health, readiness, metrics, and CORS preflight bypass the limiter. Rejections close the connection, return the standard typed 429 envelope, and calculate Retry-After from refill time. tests/http_rate_limit.c covers independent clients, token refill, retry duration, table saturation/recovery, and independent policy scopes in normal and ASan/UBSan builds; the route-group HTTP smoke covers inherited scoped policy and OpenAPI metadata. The limiter remains process-local, IPv4-only, and non-distributed.

  • 2026-10-25 — Live PostgreSQL API verification: the pure-YAZA migration CLI applied the generated API migration to an isolated local PostgreSQL 17.6 database. The full HTTP smoke then passed with DATABASE_URL, exercising chunked JSON creation, list/get/create/replace/patch/delete, safe validation responses, DELETE 204, and persistence after an API restart. The disposable database and role were removed afterward. This proves one local PostgreSQL configuration, not remote TLS, broad version compatibility, pooling, failure recovery, or complete API release readiness. The full macOS bootstrap also passes 29/29 language tests, three compiler stages with identical generated C, and normal plus ASan/UBSan PostgreSQL protocol fixtures.

  • 2026-10-25 — YAZA PostgreSQL CRUD repository integration (historical snapshot, partly superseded): generated Product repository functions call std/pg/api_records.yz for list, find, create, replace, patch, and delete when DATABASE_URL is present. They return Result[Text, ApiError]; not-found, conflict, invalid input, and unavailable outcomes map through the safe handler dispatcher. At that milestone, the no-database repository used the native in-memory demo path and the PostgreSQL driver had no pool. The 2026-10-27 updates above record the later memory adapter and HTTP response-path changes. This slice did not finish G.8/G.11.

  • 2026-10-25 — API layer metadata conformance: yaza check now verifies that service/repository declaration headers match their names, interface file headers match the declared interface, method names are unique, methods follow the required header/interface order, and each interface signature has exactly one identical declaration in its implementing metadata. The API layer smoke check passes the valid template and rejects duplicate interface/repository methods, mismatched interface/service names, malformed method headers, out-of-order declarations, and a repository signature mismatch with both normal and ASan/UBSan CLI builds. The full HTTP API smoke was rerun with the rebuilt CLI and passed. This closes a metadata-validation hole only: declarations remain metadata, and runtime dispatch/results, typed implementation functions, and YAZA-owned repository storage are still incomplete.

  • 2026-10-25 — Non-loopback API authentication guard: the native API runtime now validates the configured IPv4 bind address before opening the listener and refuses any address outside 127.0.0.0/8 unless YAZA_API_TOKEN is non-empty. This preserves unauthenticated loopback development while preventing an accidental unauthenticated public bind. The HTTP smoke now checks this startup rejection and missing, incorrect, and duplicate bearer credentials. This does not add TLS, route-level auth policy, roles, or authorization.

  • 2026-10-26 — Route-level bearer policies: API route declarations now accept auth required and auth public; routes without an explicit policy keep the configured global bearer behavior. The runtime rejects startup when a required route has no YAZA_API_TOKEN, enforces required/public behavior per matched route, and preserves the non-loopback bind guard. OpenAPI marks required operations with bearer security and public operations with no security; Postman adds a token variable and bearer authorization to required and inherited-policy requests while public requests omit auth. The dedicated route-auth smoke verifies missing/wrong/correct tokens, public bypass, default policy, startup failure, OpenAPI, and Postman. This provides shared-token route gating only; users, roles, sessions, actor-aware authorization, TLS, and composable middleware remain incomplete.

Earlier implementation snapshots

The following bullets preserve milestones from the earlier implementation. The dated updates above and the G.1–G.20 status table below are authoritative when a later change has superseded an older statement.

  • 2026-10-24 — Layered Product CRUD dispatch (superseded): generated routes first gained controller → service → repository calls through http_repository_respond, a native boundary that directly emitted the HTTP response. The 2026-10-27 implementation above replaces that shortcut with repository results and the ordinary handler response path. Storage remains a bounded native in-memory table or the YAZA PostgreSQL adapter; product interfaces still use compile-time static bindings rather than runtime polymorphism.

  • On 2026-10-24, the project owner accepted the YAZA Pulse design for typed realtime sessions and durable topic/consumer-group streams. It remains a design direction only; WebSocket, SSE, WebTransport, and broker execution are not implemented.

  • The self-hosted macOS CLI can create API, web, fullstack, and mobile starter projects, check the supported source subset and declared architecture layer edges, build programs, run them, and generate Postman collections. The current compiler source passes consecutive native bootstrap stages with identical generated C. It also compiles and runs product shape values with built-in and nested fields, forward declarations, dependency-ordered layouts, positional constructors, checked field access, checked updates through mutable var values, imported declarations, and typed function parameters/returns, alongside checked Int32 conversions and arithmetic, Float64 decimal/scientific literals, built-in and shape-payload Option[T]/Result[T, E], exhaustive block matches for their variants, same-type and direct From-converted postfix ? propagation in let/var/set/return, nested elif, TextList loops, break, continue, nested early returns, OS-backed secure random bytes, provider-backed SHA-256/HMAC/PBKDF2, SCRAM-SHA-256, bounded TCP/TLS transport and PostgreSQL SSLRequest negotiation, structured logs with sensitive-field redaction, and typed HTTP path/query/body accessors plus nested request shapes with optional scalar and optional nested-shape fields. Multi-line architecture TOML passes; invalid Option/Result payload types, direct equality, non-exhaustive matches, duplicate match arms, duplicate From pairs, propagation without a matching or converted error type, ? outside a Result-returning function, invalid shape fields, shape constructor type/arity mismatches, cyclic by-value layouts, incompatible field updates, and updates through immutable values are rejected; runtime access to absent/wrong variants fails explicitly; malformed Float64 exponents, out-of-range Int32 conversions, Int32 overflow, and invalid secure-random lengths are rejected. The latest full suite passed 27/27 on 2026-10-24, including the new bounded HTML escaping test. The conversion test passed ASan/UBSan in an earlier run. TLS success handshakes remain untested. The generated macOS package remains provisional because the managed host adds AppleDouble provenance records to its payload.

  • User-defined tagged variants are now wired into the self-hosted compiler: unit and typed payload cases, imported declarations, checked constructors, exhaustive match arms with scoped bindings, and Option/Result payloads compile and run. The final two native compiler stages emitted identical C. The positive variant test and six negative compiler fixtures pass; the variant test also passes ASan/UBSan. This implementation remains a prototype slice and does not include general generics, traits, expression-valued matches, derives, or source-level ownership.

  • Concrete direct From[Source] for Target conversions now lower a single typed fn from(value: Source) -> Target method to an ordinary function and are called on the error branch of ?. Imported implementations work; duplicate source/target pairs fail compilation. The positive test covers let, var, set, and direct return propagation and passes ASan/UBSan. Generic traits, conversion chaining, and arbitrary nested ? remain unavailable.

  • Numeric for loops now support ascending half-open Number ranges using start..end; each bound is evaluated once, an empty descending range performs zero iterations, and break/continue work through the existing loop control. The test covers negative and empty ranges, plus string values containing ..; the loop test passes ASan/UBSan.

  • The API template has one root README that documents the project layers. Folder-specific README placeholders have been removed.

  • The native HTTP runtime supports static JSON routes and a sample resource with list, read, create, replace, partial update, and delete operations. It validates JSON syntax recursively, validates UTF-8 and surrogate pairs, decodes escaped object keys before duplicate checks, caps each object at 64 fields and values at a recursion depth of 128, checks primitive fields against the sample record, and bounds request size. Strict HTTP/1.1 chunked bodies are decoded with bounded chunk lines and trailers; ambiguous Content-Length plus Transfer-Encoding and malformed chunk framing are rejected. Boundary, nested-duplicate, Unicode, and field-limit cases are covered by tests/json_depth.c. Storage is in-memory by default; setting DATABASE_URL enables parameterized PostgreSQL JSONB CRUD for this sample resource.

  • API route declarations connect HTTP methods and paths to a controller name. The compiler follows that name through service and repository metadata and checks method signatures, including typed parameters and return types.

  • A static route can use => handler function_name; a controller action can use => controller ControllerName.action. The API compiler reads src/application.yz, resolves its imported YAZA modules, compiles their ordinary function bodies into the server, and dispatches the route to the named function. Handler functions may return Text, Option[Text], Shape, Option[Shape], Result[Text, E], or Result[Shape, E]: Text and successful shape responses are JSON-validated, some(Text) and ok(Text) follow the same path, none maps to a safe 404 JSON envelope, and err(E) is handled through the typed ApiError mapper when known or becomes a fixed generic 500 without exposing its payload. InvalidInput(field: Text) and ValidationFailed(errors: TextList) map to 422 and emit bounded safe dotted or canonical array-indexed paths; every declared ApiError case has a fixed status/code mapping. Result[Shape, ApiError] now has a layered sample route with success, not-found, and validation outcomes; normal and ASan/UBSan HTTP smokes pass, and OpenAPI/Postman generation smokes pass. The full conformance fixture at tests/fixtures/api-complete contains greeting, typed-demonstration, scalar POST, shape POST, optional greeting, Result greeting, and Product CRUD routes calling controller → service → repository or service functions as declared; the generated API starter keeps only the Product Catalog study case. Product repository functions use the YAZA PostgreSQL adapter or bounded in-memory adapter; create, replace, patch, and find decode to ProductRecord; delete decodes to ProductDeleteOutcome behind its bodyless 204 route, while list still returns JSON Text. Controller actions read declared Text path/query/header values as Option[Text]; path/query values declared as Number, Int32, Float64, or Boolean are available through typed accessors returning Option[T]. Scalar JSON body declarations (body field: Type) bind as Option[T]; a declared request shape binds through http_body_shape("payload") as Option[Shape]. Nested shapes support required scalar leaves, optional scalar and nested-shape fields, and optional TextList fields bound from JSON string arrays (up to 64 items and 1023 UTF-8 bytes per item); omitted and JSON null optional fields decode to none. Numeric min/max and Text min/max Unicode-codepoint rules reject invalid values before controller dispatch. Each decoded Text has a separate 1023-byte UTF-8 cap, also described in OpenAPI. Omitted optional query values use validated declared defaults. json_quote(Text) safely encodes user text for JSON responses. The runtime validates returned JSON and replies 500 for invalid or oversized output; executable POST actions return 201. Dependency construction, tagged-variant/map request fields, typed Product collection results for list, a shared typed response/error model, generated common OpenAPI responses, and unified typed framework/auth/database error conversion remain unimplemented.

  • Postman generation includes declared path, query, header, and JSON body examples; OpenAPI emits recursively nested shape properties, TextList array schemas, omits optional fields from required, represents optional values as nullable types, includes declared numeric/Text/email/pattern constraints, and sets additionalProperties: false. The server validates request shapes and rejects unknown, malformed, wrong-typed, constraint-violating, or out-of-range values before dispatch; absent or null optional properties are accepted. Other list element types remain unimplemented; typed mapping for ApiError is not unified with framework validation, authentication, and database failures.

  • The server supports simple .env loading with shell-environment precedence, YAZA_HOST/YAZA_PORT, a shared Bearer token through YAZA_API_TOKEN for non-loopback binds, exact-origin CORS through YAZA_CORS_ORIGIN, /healthz, database-aware /readyz, request and response-status metrics, one-line JSON access logs, and graceful SIGINT/SIGTERM shutdown. It validates Host, requires JSON content type for non-empty request bodies, decodes percent-encoded path/query components, rejects encoded path separators, and applies PostgreSQL statement/lock/idle-transaction timeouts. YAZA-owned kqueue/level-triggered epoll readiness code drives the single-threaded accept/read loop, which retains a bounded configurable number of active sockets (1–127; default 64), incrementally reads incomplete requests, and closes them after a configurable absolute deadline (default 5,000 ms; YAZA_HTTP_REQUEST_TIMEOUT_MS accepts 1,000 to 300,000 ms); only the macOS backend has been exercised. HTTP/1.1 supports sequential reuse and ordered pipelining, with a configurable idle timeout (default 5,000 ms; YAZA_HTTP_KEEP_ALIVE_TIMEOUT_MS accepts 1,000 to 60,000 ms) and a 100-request connection cap; HTTP/1.0 and explicit close requests receive closing responses. Response output is queued under a 16 MiB per-response and 64 MiB aggregate pending-buffer cap, flushed on writable readiness in a maximum 64 KiB per-event-loop-turn quantum, and closed after a configurable total deadline (default 5,000 ms; YAZA_HTTP_RESPONSE_WRITE_TIMEOUT_MS accepts 1,000 to 300,000 ms). Only macOS kqueue is exercised. Smoke tests cover non-loopback auth startup policy, missing/incorrect/duplicate bearer credentials, keep-alive, pipelining, CRUD, an unrelated health request during a stalled header, and closure of overdue incomplete requests. Route handling and database calls remain synchronous, while response writes use bounded nonblocking output; the default in-memory mode is volatile.

  • The native runtime uses a bounded program arena and a bounded scratch arena for each completed HTTP request. A bounded poll connection table supports incremental reads of incomplete requests; YAZA_HTTP_MAX_CONNECTIONS selects 1–127 entries (default 64), accounting for about 4 MiB at the default request-buffer size and about 8 MiB at the maximum. In-memory CRUD records are explicitly moved into the program arena; request parsing and response allocations are reclaimed when each handled request ends. A unit harness covers allocation limits, realloc, transfer, and reset under normal and ASan/UBSan builds. Full CRUD/slow-client/timeout smoke passes under ASan/UBSan. The latest 100,000-request GET run retained its created record and measured 0 KiB sampled RSS growth at 1 KiB ps resolution (10,800 KiB baseline and peak). This internal allocator does not provide language-level ownership safety.

  • The CLI has a basic yaza test runner for .test.yz/_test.yz programs with Boolean assert; each test compiles/runs in a child process, so a compile failure is recorded and later test files still run. yaza test --format json reports isolated test outcomes in a versioned machine-readable document. yaza check --format json [file.yz] emits the versioned yaza.diagnostics schema with source URI, severity, coarse stable code, message, related/notes arrays, and line-level fallback or statement-level byte ranges; the VS Code extension converts statement byte offsets to UTF-16 positions. JSON diagnostics aggregate up to three errors per function and start: body for import-free non-API sources up to 96 KiB, 4,096 lines, and 32 functions, under a shared 128-probe cap. Up to two isolated recovery rounds can repair an explicitly typed let/var initializer with a supported default, a supported return mismatch, or a non-Boolean assert, preserving names and source lines. Other same-function errors, imported modules, API sources, malformed global declarations, and unsupported return types remain incomplete. yaza bench measures repeated native process timing. API projects include a curl-based HTTP smoke script covering CRUD, body validation, auth, CORS, Host/content-type validation, percent-decoding, log privacy, graceful shutdown, slow-client fairness, chunked JSON CRUD, keep-alive reuse, and pipelined ordering. A C loopback harness also rejects ambiguous/malformed chunk framing, checks actual connection closure and HTTP/1.0 handling, and enforces the 100-request keep-alive cap. C runtime harnesses check allocator ownership transfer/reset and JSON nesting boundaries; tests/http-memory-arena-smoke.sh separately sends 100,000 sequential requests and samples server RSS. PostgreSQL persistence is checked after an API restart when configured. There is no fixture framework, automated database-container lifecycle, general compiler-error recovery, or reusable in-process HTTP test client.

  • Sample-resource PostgreSQL CRUD and ordered SHA-256-checksummed migrations are implemented. The native standard library now also exposes bounded OS-backed secure_random_bytes(Number) returning opaque Bytes; it does not implement cryptographic primitives. Shape-mapped typed SQL, a concurrent connection pool, composable middleware execution, database-container integration testing, and structured concurrency are not implemented.

  • The pure-YAZA PostgreSQL transport now has pg_connect, trusted-static-SQL pg_query, parameterized pg_query_params, pg_query_params_typed, and pg_query_with_parameters. PgParameters provides checked text-format constructors for Text, int8, int4, float8, Boolean, hex bytea, and explicit NULL with a chosen OID. The builder validates parallel list shape, OID range, a 1024-parameter cap, NUL-free text values, and a 1 MiB aggregate bound. One result set is decoded with column metadata and a 16 MiB/10,000-cell cap. Protocol-builder and result-access tests pass. Explicit PGSSLMODE=disable plaintext is restricted to loopback and the connected peer is checked with getpeername; a local fake server exercises protocol boundaries normally and under ASan/UBSan. Live local PostgreSQL 17.6 migration and Product API CRUD/restart-persistence now pass through the YAZA client. API startup/schema/readiness still use libpq; remote TLS, broader versions, and failure-path integration remain open.

G.1–G.20 status

Section Required capability Current status
G.1 shape, variant, trait, impl, methods, and ownership modes Partial: shape product types support built-in and nested typed fields, forward declarations, dependency-ordered layouts, positional construction, checked field reads, typed updates through mutable var values, function parameters/returns, and imports. Tagged variant supports unit and named typed payload cases, checked Type::Case(...) constructors, exhaustive block matches with scoped bindings, and use as shape/Option/Result payloads. A concrete impl From[Source] for Target block with one checked from function is supported. Option[Shape] permits recursive links through arena-owned copies; general traits/impls, receiver methods, derives, and source-level ownership modes remain unimplemented. Runtime-only arenas do not implement source-level lifetime checking.
G.2 File-path module names and enforceable layer dependency rules Partial: yaza arch check and compiler commands now discover the nearest project ancestor from the source file path, then validate relative use edges against single-line or multi-line [architecture].layers and allow arrays in yaza.toml, including TOML trailing commas; this also works when yaza check is invoked from outside the project directory. Paths normalize ./.. lexically inside src, and forbidden edges include source locations. Package-level module names, aliases, filesystem symlink checks, and package-root module resolution are not implemented. The external-working-directory regression is in tests/api-layer-conformance-smoke.sh.
G.3 Named/default arguments, tuples, Option, closures, generics, trait bounds, Result, recursion, methods, and numeric types Partial: nested shape and user-defined tagged variant values support checked construction, typed fields/payloads, function parameters/returns, and exhaustive matching; Option[T] and Result[T, E] support nested built-in, shape, and variant payloads up to 16 levels. Numeric and sum-type match arms can produce a function return value, initialize a typed let/var, or assign to an existing mutable var with set; matches evaluate the subject once, check arm types, scope payload bindings, and enforce exhaustiveness (else for numeric guards). Non-void functions are checked for a return on every path through supported if/elif/else chains, including nested and inline branches; loops do not prove a return. Int32 has explicit checked conversions and overflow-checked arithmetic. for value in start..end iterates ascending half-open Number ranges with both bounds evaluated once. Postfix ? propagates a Result error through let, var, set, and return when error types match or one explicit direct concrete From conversion exists. These remain bounded constructors rather than general generics. Cyclic direct by-value layouts, match values in arbitrary expression positions, conversion chaining, arbitrary nested ? expressions, named/default arguments, tuples, closures, general traits, methods, Int64, unsigned types, Decimal, Money, and temporal types remain unavailable. Float64 has decimal and scientific literals, finite arithmetic, parsing, formatting, and exact-only explicit conversion.
G.4 Package manifest, dependencies, dev dependencies, and architecture policy Partial: API manifests declare layer names and permitted edges; yaza arch check and yaza check/build/run enforce them using the source file's discovered project root, including explicit source paths checked from another working directory. tests/api-layer-conformance-smoke.sh verifies that a forbidden controller-to-repository edge is rejected from outside the project root. Dependency/dev-dependency resolution, lockfiles, signatures, and full package-root resolution remain unimplemented.
G.5 Typed shapes, JSON/row derives, newtypes, validation, money, and time types Partial: native product shapes support built-in and nested fields, TextList, List[DeclaredShape], List[Number], List[Int32], List[Float64], List[Boolean], List[Text], nullable Option[List[T]], Option[Shape] recursive links, positional construction, checked field reads, and type-checked updates through mutable var values. json_shape(Text) strictly decodes bounded JSON into a declared shape, including nested shapes and optional fields; malformed JSON, missing/extra keys, wrong types, integer overflow, and oversized payloads fail as none. API arrays are capped at 64 items; primitive array items are checked for JSON kind, finite Float64 values, and numeric range, while declared-shape items receive nested validation. min_items/max_items constraints apply to all supported list fields. Numeric min/max plus validate <field> integer constrain Float64 whole values inside the IEEE-754 safe integer interval; Text supports min_length/max_length measured in Unicode code points, a conservative ASCII email-syntax rule, and a bounded anchored ASCII pattern subset. Constraints run during decoding and are represented in OpenAPI; decoded Text has a separate 1023-byte UTF-8 cap. API models and seed records remain metadata and are not generally derived from shapes. Direct cyclic by-value layouts, JSON/row derives, newtypes, broader validation, money, and time types are not implemented.
G.6 Error variants, Result, From, and ? Partial: Result[T, E] supports recursive nesting up to 16 levels, ok, err, result_is_ok, checked accessors, exhaustive block matches, and postfix ? in let/var/set/return when the error type matches or one direct From[Source] for Target implementation is declared. Imported concrete implementations are supported and duplicate source/target pairs are rejected. User-defined tagged error variants can carry typed fields and are supported as Result errors, including matching and conversion. The API template maps all declared ApiError cases to fixed status/code envelopes and maps InvalidInput(field: Text) plus ValidationFailed(errors: TextList) to 422 after validating bounded safe paths using dotted identifiers and canonical array indexes from 0 through 63; unknown variants, malformed field paths, and other error types never expose their payloads. Generic From, conversion chaining, arbitrary nested ? expressions, mapping for other payload-bearing errors, and shared conversion for framework/auth/database failures remain incomplete.
G.7 Environment configuration and redacted Secret[T] Partial: the API runtime loads simple .env values without replacing shell variables and reads YAZA_HOST, YAZA_PORT, YAZA_API_TOKEN, and YAZA_CORS_ORIGIN; std/security/secret.yz provides opaque SecretText, bounded text/environment constructors, fixed redaction, explicit Option[Text] reveal, and explicit shared-buffer zeroization. The compiler does not allow implicit printing, and API JSON serialization rejects the type. std/crypto/password.yz provides bounded Argon2id hash/verify/rehash helpers. Typed layered configuration, automatic secret lifetime management, PII tracking, and login/session integration remain unimplemented.
G.8 PostgreSQL connection pools and parameterized typed SQL Partial: generated Product CRUD uses parameterized std/pg/api_records.yz calls for list/get/insert/replace/patch/delete. API startup and readyz hooks perform the PostgreSQL schema check and readiness probe through the pure-YAZA client; generated API builds no longer define YAZA_WITH_POSTGRES or link libpq. The latest database-configured migration and full API smoke passed against disposable PostgreSQL 18.6, covering current lifecycle startup, sample seeding, readiness, CRUD, and restart persistence; PostgreSQL 17.6 migration, CRUD/restart, snapshot, and transaction evidence also exists for the earlier lifecycle path. The generated Product API now uses a bounded, process-local PostgreSQL pool for repository, startup, and readiness operations. The runtime pool is wrapped by std/pg/pool.yz, keyed by a SHA-256 digest of connection settings, capped at 128 slots globally and 64 per database identity, and defaults to 8 connections per identity, a 5,000 ms acquisition timeout, and a 60,000 ms idle timeout; bounded environment overrides are supported. It expires idle connections, pings reused connections after 1,000 ms of idle time, and discards unhealthy handles. Release checks that a socket remains active, so a connection closed by transaction cleanup is discarded even if the release call says healthy; tests/pg_pool.c covers this in normal and ASan/UBSan builds. The pool exposes counts and drains leases during shutdown. The C harness covers capacity/timeout, reuse, ping, wait/wakeup, idle expiry, discard, stats, and shutdown; the PostgreSQL 18.6 API smoke passes through the pool. Pool coordination is thread-safe, and generated handlers/database calls execute on the bounded API worker pool while the event loop owns socket I/O. Two blocked handlers, prompt health/readiness, timeout accounting, and shutdown pass normal, ASan/UBSan, and ThreadSanitizer loopback checks. Live PostgreSQL overlap, Linux, remote TLS, and a broader PostgreSQL version matrix remain unverified. Remote TLS, Linux, and a broader PostgreSQL version matrix remain unverified. Remote connections require sslmode=verify-full; explicit local sslmode=disable is restricted to 127.0.0.1 or ::1 and the connected peer is checked. Normal HTTP smoke rejects remote disable/prefer/allow/require/verify-ca and unpinned localhost before network access. Remote TLS, broader server coverage, automated live-database CI, and transaction failure recovery remain open. yaza db migrate/status/snapshot uses the pure-YAZA PostgreSQL v3 transport. That driver performs SSLRequest/TLS/startup/SCRAM, simple-query exchange, and Parse/Bind/Describe/Execute/Sync extended-query exchange through ReadyForQuery. Verified TLS is the default and is required for remote peers; explicitly configured PGSSLMODE=disable permits plaintext only after loopback peer verification. pg_execute_command_script accepts trusted command-only scripts up to 1 MiB and reports up to 10,000 command completions; the completion cap is checked after the submitted script has run and is not a server-side execution limit. PgParameters has checked text-format constructors for Text, int8, int4, float8, Boolean, hex bytea, and explicit NULL with an OID; parameter count, OID range, list shape, NULs, and the 1 MiB aggregate value bound are checked. This selects PostgreSQL types but is not binary Bind encoding. pg_parameters_add_text_as accepts caller-supplied PostgreSQL text representations for other OIDs, without native YAZA conversions. Result metadata and SQL NULL are preserved, supported text-format scalar values are decoded, and nullable typed accessors are provided for numbers, Booleans, text, and bytes; response bounds are 16 MiB/10,000 cells. yaza db migrate applies each SQL file in a managed transaction, parameterizes ledger writes, rejects checksum edits, and rejects common top-level transaction-control statements before execution. yaza db snapshot writes version-2 deterministic JSON with a SHA-256 fingerprint over ordered migration names and checksums; before writing, it verifies that the database migration ledger matches local files. yaza db validate-snapshot [file.json] validates the JSON and compares the fingerprint offline, and project check/build/run enforce the default snapshot when present. Snapshot catalog queries and fingerprint round-trip pass on PostgreSQL 17.6; broader versions, failure modes, and CI remain open. Fingerprints catch local migration changes but not out-of-band DDL, and snapshots do not feed typed query compilation. Row-to-shape mapping, Unicode SASLprep, and ownership-driven transaction cleanup remain absent; the explicit defer-based rollback guard is tracked under G.17. Provider-neutral pooling and non-PostgreSQL pool implementations are also not available. pg_query accepts only trusted static SQL; use bound queries for external values.
G.9 Ordered, embedded, checksummed migrations Partial: yaza db migrate/status uses the pure-YAZA PostgreSQL wire client, applies ordered external SQL files in managed transactions, records OS-backed SHA-256 checksums, and rejects edits to applied migrations. A lexical preflight rejects common top-level transaction-control statements. yaza db migrate has applied the generated API migration successfully against an isolated local PostgreSQL 17.6 server. Migrations are external files, not embedded in binaries; broader server-version and remote-TLS coverage remain open.
G.10 Repository traits with typed optional and fallible results Partial: Option[T] and Result[T, E] work for built-in, shape, and typed-list payloads. All six Product operations return typed results through controller, service, repository interface, and implementation: four return Result[ProductRecord, ApiError], list returns Result[List[ProductRecord], ApiError], and delete returns Result[ProductDeleteOutcome, ApiError] behind a bodyless 204 route. Strict JSON decoders reject malformed or incompatible stored records; the typed list decoder checks each ProductRecord before producing a List[ProductRecord]. The HTTP runtime serializes the list as a JSON array, and OpenAPI derives the array item schema from the declared result. Each service/repository method binds to one reachable function in its matching implementation file; the compiler checks exact parameter count/types and return type against the interface and executable YAZA function. Pagination passes limit and offset through all three layers; invalid bounds return the stable 422 InvalidInput envelope in both in-memory and PostgreSQL paths. Fixture yaza check, OpenAPI/Postman generation, HTTP response smoke, and the three-stage macOS bootstrap pass. Invocation remains static rather than runtime-polymorphic; generalized typed repository code generation, generic traits, and arbitrary typed-list codecs remain incomplete.
G.11 SQL and in-memory CRUD repositories Partial: with DATABASE_URL, all six generated Product operations reach YAZA repository code and the YAZA JSONB adapter using bound parameters; without it, std/api/memory_records.yz provides the same repository operations and returns Result values. Create/replace/patch/find decode ProductRecord, list returns Result[List[ProductRecord], ApiError] after validating every array element, and delete decodes ProductDeleteOutcome behind a bodyless 204 route. The native adapter mutates the bounded runtime resource table; ordinary handler serialization sends repository results. Starter CRUD, complete API HTTP fixture, typed response generation, and PostgreSQL fixtures pass. Typed YAZA-owned storage, reusable typed repositories, runtime-polymorphic interface dispatch, unified lifecycle management, and broader live-server coverage remain open.
G.12 Business services, TTL cache, structured logging, and error propagation Partial: std/cache/ttl.yz provides a process-local, mutex-protected cache with 128 fixed entries, 255-byte keys, 4095-byte values, monotonic TTL expiry up to seven days, least-recently-used eviction, explicit remove/clear, and wiping on removal/replacement/expiry/shutdown. It is volatile and must not hold secrets or cached authorization decisions. log_event(level, event, fields) emits bounded JSON-line records to stderr, rejects invalid levels, duplicate keys, invalid UTF-8 and oversized records, and redacts sensitive field names. Direct error conversion via From/? and executable controller/service/repository functions are implemented. Product use cases, conversion chaining, typed application-error mapping, tracing context, log filtering/configuration, and asynchronous sinks remain incomplete.
G.13 Typed HTTP handlers, path/query/body parsing, validation, and status mapping Partial: the runtime validates declared path/query/header presence and primitive types, percent-decodes safe path/query components, requires application/json for non-empty bodies, decodes bounded HTTP/1.1 chunked JSON bodies, and rejects unknown, malformed, or wrong-typed fields against controller body metadata. GET and POST controller actions read declared Text and primitive path/query/body values as Option[T]; http_body_shape decodes nested request shapes with required scalar fields, optional scalar/nested fields, TextList arrays of strings, arrays of declared shapes (List[Shape]), and primitive arrays (List[Number], List[Int32], List[Float64], List[Boolean], and List[Text]), each capped at 64 elements. Nullable Option[List[T]] fields accept absent or JSON null; present elements are checked for JSON kind and numeric range, and declared min_items/max_items bounds run before controller dispatch. Handler outcomes support Text, Option[Text], direct Shape, Option[Shape], List[Shape], Option[List[Shape]], Result[Text, E], Result[Shape, E], and Result[List[T], E]/Option[List[T]] for scalar element types Number, Int32, Float64, Boolean, and Text. Scalar lists use bounded, type-checked JSON serialization; OpenAPI derives each array item schema from the declared element type. none maps to 404. Shape outcomes serialize scalar, nested-shape, TextList, List[Shape], and primitive typed-list fields. For Result[..., ApiError], every declared case maps to a fixed status/code envelope; InvalidInput(field: Text) and ValidationFailed(errors: TextList) include only bounded safe paths using dotted identifiers and canonical array indexes from 0 through 63. Unknown cases and other error types map to generic 500 without exposing payloads. 401 adds WWW-Authenticate: Bearer; 429/503 add Retry-After: 1. OpenAPI emits common 400/401/404/405/413/415/422/429/431/500/503 schemas on every operation, typed success/error schemas, safe field patterns, and authentication/retry headers. Omitted or JSON null optional properties become none; out-of-range values, declared numeric/Text codepoint-length, list item-count, email-syntax, and bounded pattern constraints are rejected before dispatch. Invalid typed path/query/header parameters and unknown query keys return structured 400 errors; JSON body/schema validation failures return structured 422 errors with safe field paths and stable codes. Optional query defaults use checked typed conversion. Executable POST actions default to 201 unless the route declares 200, 201, 202, or 204. HTTP smoke covers primitive/nested/string-list/typed-array binding and responses, optional value/absence/null/wrong-type cases, defaults, validation boundaries, Result success and all known ApiError mappings, shape and primitive list outcomes, response escaping, and error-payload privacy. HTTP smoke passes normally and with ASan/UBSan; OpenAPI/Postman/Swagger generation and the 2026-10-28 full YAZA suite pass. OpenAPI represents optional scalar/array/object fields with nullable types, excludes them from required, includes declared constraints, and documents byte caps with x-yaza-maxUtf8Bytes; Postman includes request examples and absolute operation URLs. Invalid items in TextList, List[Shape], and primitive typed arrays include canonical array indexes; array-level errors such as malformed containers and item-count bounds identify the field. Arbitrary nested collection codecs, typed framework/authentication/database conversion, and additional typed response forms remain incomplete.
G.14 Chained middleware, route groups, authentication, timeout, recovery, and error mapping Partial: the runtime has strict bounded HTTP parsing, Host/framing checks, request and socket deadlines, active-connection limits, keep-alive/pipelining, bounded nonblocking response writes, route-specific 405 Allow headers derived from registered methods for the matching path, common safe status envelopes, and optional shared Bearer auth. Routes/groups support inherited auth required, auth public, and auth jwt policies; the JWT profile verifies compact HS256 tokens, pins issuer and configured audience, checks integer exp/optional nbf/iat, rejects unknown JOSE headers, and returns token_expired for a verified expired token. A verified JWT handler may read bounded top-level string claims through http_auth_claim_text(name) -> Option[Text]; this is available only for the matched JWT-protected request, and request-scoped claim bytes are wiped after dispatch. JWT-only non-loopback binding requires at least one JWT route and explicit policies for every declared route. Global and scoped exact-origin CORS and bounded per-client IPv4 rate limits compose through route groups; OpenAPI/Postman reflect the effective route policy. Normal and ASan/UBSan route-auth smokes cover string/array audience matching and rejection, claim access, Unicode, missing optional subject, malformed subject rejection, and spoofed-header rejection; the macOS bootstrap passes the three-stage self-host build, the 2026-10-28 full YAZA suite, and route middleware, OpenAPI, and Postman checks. The event loop uses kqueue on macOS and level-triggered epoll in Linux source, but only macOS has been exercised. Generated controller/service/repository handlers and database-backed readiness probes now run on a bounded worker pool; individual YAZA and PostgreSQL calls are blocking within each worker. Handler code can poll http_request_cancelled() -> Boolean to observe client disconnect, request-deadline, or shutdown cancellation; loops and blocking/native or PostgreSQL calls are not forcibly preempted. The event loop owns socket I/O, response framing, health, and metrics. Worker queue/execution gauges and counters are exposed at /metrics. The API handler/readiness concurrency harness blocks two handlers at once plus one queued job, checks active/queued/in-flight metrics, proves health stays responsive, checks HTTP 504 and its timeout metric, and passes normally, under ASan/UBSan, and under ThreadSanitizer. A forked worker-pool harness confirms an uncooperative thread cannot hold bounded stop past its deadline; live PostgreSQL concurrency remains pending. General user-defined middleware, login/token issuance, typed principal and role policy, ownership authorization, refresh/revocation/key rotation, asymmetric JWT algorithms, trusted-proxy identity, distributed quotas, panic recovery, unified typed framework/auth/database errors, inbound TLS, and Linux runtime evidence remain incomplete.
G.15 Composition root, database setup, migrations, server tasks, signals, graceful shutdown Partial: the API entry point starts the native event loop, a bounded handler/readiness worker pool, and a request-reader task for each accepted connection. SIGINT/SIGTERM stops accepts, collects socket readiness without blocking, completes requests already readable, closes incomplete/idle sockets, then drains queued response bytes for up to the configured response-drain grace before reaping remaining connection tasks. Normal and ASan/UBSan HTTP smokes verify request and response drain. Queued worker jobs observe cancellation before execution during shutdown; active handler code may poll http_request_cancelled() -> Boolean. The configured YAZA_HTTP_SHUTDOWN_GRACE_MS also bounds worker termination after response draining; if a worker has not exited by the deadline, the process logs a fixed diagnostic and exits with failure rather than freeing runtime state while the worker is active. The setting accepts 1,000 to 120,000 ms (default 5,000 ms). The loop uses kqueue on macOS and level-triggered epoll in Linux source; only macOS has been exercised. Declared YAZA startup/readiness hooks use the pure PostgreSQL driver to configure connect/query/lock/idle-transaction timeouts, verify the migrated record table, seed initial demo data, and probe database readiness with a 500 ms per-operation budget. Readiness returns a PostgreSQL-specific 503 while unavailable. Generated API binaries no longer use libpq. Migration and the full database-configured HTTP smoke passed against disposable PostgreSQL 18.6, including startup, seeding, CRUD, restart persistence, and /readyz failure/recovery across a database pause/resume. yaza db migrate/status uses YAZA's own PostgreSQL transport (verified TLS by default, with explicit peer-checked loopback-only plaintext). Language-visible async tasks are not implemented; a handler that ignores cancellation cannot be preempted, so the process exits with failure if it remains active when the shutdown deadline expires. Remote TLS and broader server coverage remain unverified.
G.16 Unit, integration, database-container, and HTTP tests Partial: yaza test discovers native YAZA test programs with Boolean assertions in sorted order. It builds each test from the project root, then runs its executable in a private /tmp/yaza-run.XXXXXX/work directory. The private temporary tree is removed without following symlinks, with limits of 64 directory levels and 100,000 entries; this isolates relative paths but is not an OS sandbox and does not restrict absolute paths or system access. A 30-second default budget covers compilation and execution; --timeout <ms> or YAZA_TEST_TIMEOUT_MS sets it from 1 to 3,600,000 ms. Timeout kills the process group, reports separately, and discovery continues. yaza test --format json emits per-test path, status, phase, exit code, timeout flag, and summary; child output is sent to stderr. tests/test-runner-resilience.sh verifies JSON records for pass, compile failure, runtime failure, and timeout, plus continuation, relative-file isolation, external-path rejection, safe symlink cleanup, and preservation of an outside target. A fresh ./dist/yaza test run passed 45/45 on macOS arm64 on 2026-10-28, including PostgreSQL protocol, SQLSTATE, Product API error mapping, structured-query generation, and Argon2id password-hash tests. The focused query test passes under ASan/UBSan. API HTTP smoke covers executable handlers, typed inputs, validation, CRUD, security headers, keep-alive/pipelining/chunked JSON, and slow-client fairness; the no-database full HTTP smoke passed on 2026-10-28. The database-configured HTTP smoke also passed against disposable PostgreSQL 18.6 after the lifecycle-hook refactor. tests/api-postgres-container-smoke.sh provisions a loopback-only disposable container, applies the API migration, runs a live structured-query execution smoke, and runs the full database-configured HTTP smoke, including readiness 503 in about 500 ms while PostgreSQL is paused and recovery to 200 when it resumes, then removes the container; it passed locally with PostgreSQL 18.6. tests/postgresql-live-smoke.sh repeats migrations, checks status, creates and validates a live catalog snapshot, and exercises transaction, savepoint, rollback, and failed-transaction recovery; it passed against a disposable PostgreSQL 17.6 database. Provider/version matrix and live-DB CI remain unimplemented.
G.17 Transactions, background tasks, retry/timeout, and structured parallelism Partial: std/pg/transaction.yz adds a PgTransactionScope guard. Register defer pg_scope_cleanup(scope) immediately after begin; an uncommitted scope attempts rollback on scope exit, including return, ?, break, and continue. Commit and rollback are explicit, repeated cleanup is idempotent, and a failed or uncertain connection is closed; implicit rollback failure or timeout attempts to emit the fixed postgres_transaction_cleanup_failed event with no SQL, credential, or server error text. An uncertain commit is never retried automatically. For pooled handles, register defer pg_pool_release(handle, true) before defer pg_scope_cleanup(scope); LIFO order cleans the transaction first, and pool release discards a socket that cleanup closed. tests/pg_pool.c covers closed-handle discard in normal and ASan/UBSan builds. tests/defer-conformance.sh, tests/pg-transaction-scope-smoke.sh, and the API secret-cleanup smoke pass normally and under ASan/UBSan. The strict protocol peer covers exact wire ordering, nested-BEGIN rejection, failed-query propagation, rollback timeout/failure, uncertain commit, cleanup-event count, and no retry. Its language smoke also verifies LIFO transaction/pool cleanup: committed connections return idle, failed rollback/timeout closes the handle before pool release, and the lease is discarded. Manual transaction/savepoint behavior still has separate live PostgreSQL 17.6 evidence. The new scoped helper and migration integration have not yet been verified against a live PostgreSQL server. Cleanup is explicit opt-in; defer ordering and pool lease ownership remain caller conventions rather than statically enforced types. Concurrent use of a borrowed connection remains unenforced. Automatic retries, language-visible managed background tasks, outbound HTTP retry, WebSocket/SSE, and structured parallelism remain absent; the API worker pool is an internal synchronous-handler executor.
G.18 Uploads, gRPC, queues, schedulers, health/metrics, tracing, layered configuration, and deployment Partial: restricted CORS, /healthz, /readyz, Prometheus HTTP request/response-status counters, active/maximum HTTP connection gauges, the saturating yaza_http_connections_rejected_total counter for accepted clients closed at a full connection table, the yaza_http_accept_backoffs_total counter for listener pauses after descriptor exhaustion, API worker queue/execution metrics, and configured PostgreSQL pool-state gauges at /metrics, plus an internal bounded YAZA-owned scheduler core, are available. Loopback harnesses verify full-table rejection, continued service on the active connection, rejection metrics, listener recovery after a slot is released, and real macOS RLIMIT_NOFILE/EMFILE backoff and recovery; the API concurrency harness passes normally, under ASan/UBSan, and under ThreadSanitizer. It also verifies an empty peer close does not increment the HTTP 400 response counter. System-wide ENFILE and Linux epoll remain unverified. The HTTP smoke verifies active/limit HTTP connection gauges and zero pool gauges in the no-database profile and the configured pool cap plus idle/leased/connecting states in the live PostgreSQL 18.6 profile. It uses fixed task slots, O(1) generational-handle lookup/reuse, per-task 64 KiB arenas retained across yields and reset on reap, a bounded timer heap, structured child join, and cancellation/failure propagation. The bounded readiness-to-task bridge is now used by the HTTP server for one request-reader task per connection; the HTTP smoke covers this path. A first thread-isolation slice makes the current arena selector and ambient handler request/status state thread-local and protects shared program-arena accounting/list mutations with a mutex; tests/runtime_thread_context.c passes native and ASan/UBSan runs. The handler worker pool now runs generated API work; the cooperative scheduler itself remains single-worker and is not exposed through YAZA language syntax. Generated YAZA programs still have no language-visible async tasks. Controller handlers and database work are synchronous inside worker threads; response writes use the bounded nonblocking output path documented under G.14. Uploads, gRPC, durable queues, distributed tracing, layered configuration, and deployment are not implemented.
G.19 Mapping to Spring Boot, Go, and other familiar frameworks The current mapping is documented below; the YAZA language/runtime equivalents remain incomplete.
G.20 Explicit design decisions and RFCs The eight RFCs in docs/rfcs were accepted by the project owner on 2026-10-23. They approve design direction; implementation and incorporation into the normative language specification are still pending.

G.19 Framework mapping

Concern Spring Boot Go YAZA current state
Model and DTO Classes with annotations Structs with JSON tags API model files remain metadata; explicitly imported YAZA shape contracts bind recursively nested primitive fields, optional scalar/nested-shape fields, and optional TextList fields from bounded JSON string arrays, rejecting missing required and extra fields. Tagged-variant/map fields and generated response DTOs remain unsupported.
Interface and repository Interfaces and repository classes Interfaces and database/sql structs Product routes execute explicit controller/service/repository forwarding functions, which call the native CRUD boundary. The compiler verifies names and exact one-to-one method signatures in layer metadata, but typed runtime dispatch and typed repository results are absent.
Service @Service class Struct with methods Product forwarding functions call service functions, but business rules and CRUD storage remain in the native generic runtime. General typed service method dispatch is not implemented.
Controller and router @RestController and route annotations http.HandlerFunc Route/controller declarations generate the native route table. Path/query values and scalar or nested-shape JSON bodies bind to typed Option[T]; bounded TextList arrays, numeric bounds, and Text codepoint-length constraints are checked and emitted to OpenAPI. The separate UTF-8 byte cap is documented as a YAZA extension. Route handlers support typed Text/Option[Text]/Result[Text, E] outcomes; known template ApiError cases have safe HTTP mappings, including a bounded field path for InvalidInput(field: Text). This remains a partial error contract rather than a unified response type.
Dependency injection Container or constructor injection Manual construction in main The API runtime does not have a general DI system; compile-time metadata follows controller, service, and repository names.
Errors Exceptions and advice Returned errors Result[T, E] constructors, checked accessors, exhaustive block matching, user-defined tagged error variants, same-type ?, and one concrete direct From conversion work; generic traits, conversion chaining, nested propagation, and centralized HTTP error mapping remain absent.
Configuration Properties/YAML and secrets Environment variables or a library Simple .env and environment values configure the API; there are no typed config or redacted secret types.
Persistence and transactions JDBC/JPA and transactions database/sql The sample CRUD path uses PostgreSQL JSONB and transactional row-locked updates when configured; otherwise it is in-memory. Generated API CRUD uses a bounded process-local PostgreSQL pool; provider-neutral pool lifecycle and shape-mapped row decoding are not implemented. The pure-YAZA driver has manual transaction/savepoint helpers plus an explicit lexical rollback guard; ownership-driven cleanup and pool-lease enforcement are not implemented.
Concurrency Managed executor or coroutines Goroutines One HTTP request is handled at a time. Structured tasks are not implemented.
Deployment JVM package/container Native binary The current native CLI installer targets Apple Silicon macOS; Linux-musl deployment is not implemented.

G.20 Accepted RFC design decisions

The accepted designs are indexed in docs/rfcs. They do not imply that the features already exist. The RFCs cover type/error semantics, ownership/unsafe boundaries, modules and package supply chain, executable layered APIs/PostgreSQL, structured concurrency/HTTP, secure standard-library APIs, evidence/release gates, and Linux/WASM/edge/mobile targets.

The earlier concise decisions below record the accepted intent and must be reconciled with the RFCs when the normative language specification is written. Any unresolved semantics remain open until that update.

Design question Accepted design direction Implementation status
Shared trait-object spelling Keep Shared[dyn Trait + Sendable] explicit initially; add a standard alias only after real projects show repeated use. Not implemented.
Error conversion through From and ? Permit only one unambiguous conversion at a call site, and have diagnostics name the source and destination error types. Partial: one direct concrete conversion is resolved by exact source/target types; duplicate pairs are rejected, but generic trait resolution and conversion chains are absent.
Multi-line closures Keep expression closures until block-closure capture and return rules are specified. Closures are not implemented.
self, edit self, and move self Use read-only borrowing by default, explicit mutable borrowing for edit self, and explicit ownership transfer for move self. Ownership checking is not implemented.
SQL strings and ORM scope Use typed parameter binding for runtime values; allow raw SQL fragments only from compile-time constants. Do not require an ORM in the first release. Pure-YAZA parameter binding supports common scalar values and caller-supplied PostgreSQL text representations; schema-aware row mapping and broader native codecs remain incomplete.
Compile-time database schema checks Read an offline schema snapshot during builds; do not require a live database connection merely to compile. Partial: yaza db snapshot [output.json] generates canonical format-version-2 yaza.schema.json from PostgreSQL catalogs, with a migration-set SHA-256 fingerprint. A migrations/ directory and current migration ledger are required; snapshot generation verifies that local migration files and the database ledger match, then atomically replaces the output from a flushed same-directory temporary file. yaza db validate-snapshot [file.json] checks structure and migration freshness offline; compiler check/build/run enforces the default snapshot when present. It cannot detect out-of-band DDL, and typed SQL declarations that consume catalog metadata are not implemented. The atomic writer passed a local replacement and permission-preservation smoke; live PostgreSQL snapshot generation remains unverified.
Default values and named arguments Evaluate defaults once from left to right; allow named arguments to reorder parameters but reject duplicates and missing required arguments. Not implemented.
Money, Decimal, and Instant Provide decimal money and time types in the standard library, with currency explicit in Money. Not implemented.
Migration policy Make numbered migrations forward-only and checksum applied contents; reject edits to migrations already recorded by a database. Partial: the sample migration CLI checks order/checksums and rejects edits to applied migrations; the full policy is not yet a normative spec, and migrations are not embedded.

2026-10-24: Pure-YAZA PostgreSQL wire-codec foundation

Added bytes_from_number(Number) with a checked 0–255 range, bytes_to_text_checked(Bytes) -> Option[Text], and std/pg/protocol.yz. The YAZA module constructs PostgreSQL v3 startup, simple-query, SSL/GSSENC negotiation, and cancel messages; serializes and reads bounded big-endian integers; rejects truncated, oversized, non-ASCII-tagged, or non-exact backend frames; classifies AuthenticationOk, cleartext, MD5, SASL, SASL continuation/final, and unsupported authentication codes; parses bounded RowDescription metadata with checked UTF-8 column names and text/binary format codes; validates ErrorResponse framing and SQLSTATEs; and validates DataRow lengths while preserving SQL NULL as none. It validates SASL mechanism lists' ASCII/NUL framing. tests/pg_protocol.test.yz passes normal execution and ASan/UBSan for startup/query and negotiation framing, integer boundaries, truncation, authentication, RowDescription, ErrorResponse, DataRow values/NULL/bounds, and malformed UTF-8. Leak detection was disabled for that sanitizer run because current Bytes values do not have deterministic reclamation. The API still links libpq; no socket/TLS transport, SCRAM proof, typed SQL/result mapping, or connection pool is present, so the selected pure-YAZA driver is not implemented yet.

2026-10-25: YAZA-authored PostgreSQL connection URI parser

Added std/pg/uri.yz and moved the URI-to-PG* configuration logic used by yaza db out of the native C runtime and into YAZA source. The parser supports postgres:// and postgresql://, percent-decoded user/password/host/database/options, IPv4 and bracketed IPv6 authorities, ports from 1 through 65535, the current documented libpq-compatible query-option subset, and a bounded 8 KiB URI. It rejects malformed percent escapes, decoded control bytes/NUL, invalid UTF-8, empty database paths, extra path segments, URI fragments, empty ports, unsupported query keys, and malformed query pairs without logging credentials. Configuration is parsed and validated before the environment is updated. tests/pg_uri.test.yz passes; the self-host bootstrap rebuilt three compiler stages and the full language suite passed 28/28. This advances the YAZA-authored PostgreSQL client setup, but the generated API still uses libpq, no live PostgreSQL server was available for interoperability checks, and the parser does not itself establish a database connection.

Implementation sequence

The product priority is explicit: complete the API release profile before starting web, monolith, or mobile implementation. Use the API completion plan as the release-gate checklist. “Complete” refers to the published API profile and supported target matrix, not every feature that could ever be added. Additional database providers are delivered as separately conformance-tested engines after PostgreSQL API persistence is first-party and verified.

  1. Extend request-shape binding to variant/collection fields and declarative typed validation, then make Product CRUD invoke executable service and repository implementations.
  2. Build language foundations needed by the API: shapes, methods, traits/interfaces, generics, optional and result types, and package module boundaries.
  3. Add typed configuration and secrets, a reusable typed PostgreSQL API and connection pool, composable middleware, JWT authentication, and an application logging and tracing API.
  4. Extend the basic test runner with HTTP/database integration support; verify scoped transaction cleanup against live PostgreSQL and complete pool-discard coordination, then add managed background tasks.
  5. Implement the remaining G.18 capabilities in dependency order and record the accepted design choices in G.19/G.20.
  6. Keep this table aligned with behavior that can be built and run; examples, metadata checks, and empty template directories do not count as completed features.

2026-10-24: API-first database vocabulary foundation

Added std/db/core.yz with explicit provider names, typed error categories, a readiness value that distinguishes the partial PostgreSQL protocol foundation from unimplemented YAZA-owned drivers, and a bounded ASCII plain-identifier syntax check. tests/database_core.test.yz checks provider labels/readiness, valid and injection-shaped identifiers, and typed error values. The new test and the full 27-test YAZA suite pass. This is a shared vocabulary/syntax foundation only: it does not handle reserved words or provider quoting, open database connections, execute SQL, or implement SQLite/MySQL/other providers. API CRUD still uses its current generic runtime path, and the PostgreSQL API still links libpq.

2026-10-24: Declarative request-shape constraints

API request shapes accept one declaration per validation rule. Numeric fields support min/max; Float64 fields may use integer to accept exact decimal whole values in the IEEE-754 safe integer interval. Text fields support min_length/max_length measured in Unicode code points, conservative ASCII email syntax, and the bounded anchored ASCII pattern subset described above; TextList fields support min_items/max_items from 0 to 64. The compiler rejects unknown fields, duplicate rules, incompatible rule/type pairs, invalid bounds, and a minimum greater than the maximum. Runtime shape decoding rejects values outside the constraints before controller dispatch, and OpenAPI generation emits matching JSON Schema constraints plus the x-yaza-maxUtf8Bytes operational cap. HTTP and generation smoke scripts cover integer, text, list, email, and pattern rules. Other list-element validators remain unimplemented.

2026-10-24: Bounded TextList request fields

Nested API shapes now bind optional TextList fields from JSON arrays of strings. The HTTP decoder allows at most 64 items and 1023 UTF-8 bytes per item, rejects non-string elements, invalid containers, and escaped NUL, and allocates list values in the request arena. The example reads the list in its controller and passes it through the service/repository chain. OpenAPI emits nullable array-of-string schemas, and Postman retains the request sample. Normal and ASan/UBSan HTTP smoke cover empty/null lists, 64/65-item boundaries, invalid types, and layered list counts. Other list element types, variants, and maps remain unsupported.

2026-10-24: Safe field-level request validation errors

Request-shape, scalar-body, and generic in-memory/PostgreSQL CRUD validation failures now use a JSON 422 envelope with type, field, and stable code properties. Paths for declared nested fields are preserved; unknown JSON keys map to $ so attacker-controlled key text is not reflected. Submitted values are never included. HTTP smoke asserts invalid primitive types, missing required fields, unknown fields, and nested validation paths. Normal and ASan/UBSan smoke pass, the YAZA suite passes 16/16, and two consecutive native compiler stages emit byte-identical C. This is limited to JSON body/schema validation; query, authentication, database, and application errors still need a unified typed mapping.

2026-10-24: Structured path and query validation errors

Invalid typed path, query, and header parameters now return structured 400 responses with a declared parameter name and stable code. Unknown query keys use $ and do not echo their values. HTTP smoke covers path overflow, invalid typed query values, and unknown keys; normal and ASan/UBSan HTTP smoke pass, and all 16 YAZA tests pass. The PostgreSQL-backed smoke also passed with the checked-in migration and restart-persistence check, both normally and under ASan/UBSan. Authentication, database, and application failures still need a unified typed error model.

2026-10-24: Pure-YAZA PostgreSQL SCRAM protocol progress

Implemented extended PostgreSQL frontend packet builders and backend status parsers in std/pg/protocol.yz; added std/pg/scram.yz with SCRAM-SHA-256 client-first/continue messages, bounded server-first parsing, nonce binding, client proof generation, and constant-time server-signature verification. Runtime crypto calls CommonCrypto on macOS and OpenSSL on Linux for SHA-256, HMAC-SHA-256, and PBKDF2-SHA-256; explicit bytes_zeroize wipes intermediate SCRAM key buffers. Bounded plain TCP connect/read/write/close builtins now enforce handle, byte, and deadline limits; a loopback client/server fixture passes normally and under ASan/UBSan. RFC 7677 and published primitive vectors pass, including under ASan/UBSan. The 21-test YAZA suite passes and consecutive compiler stages emit byte-identical C. Username/password input is currently limited to printable ASCII because Unicode SASLprep is not implemented. This is only the driver protocol/authentication foundation: API projects still use libpq; TLS certificate verification, PostgreSQL state-machine integration, shape-to-row mapping, transaction handling, migrations through YAZA wire protocol, pooling, and yaza.schema.json generation/checking remain unimplemented.

2026-10-24: Bounded TLS transport slice

Added typed net_tls_client(handle, hostname, timeout_ms) and net_tls_is_active(handle) builtins, routed reads/writes on upgraded sockets through TLS, and made the PostgreSQL startup sender require the TLS-active flag. TLS 1.2 is the minimum; hostname and system trust validation are enabled, and macOS trust evaluation is configured not to fetch certificates over the network. macOS uses Secure Transport (deprecated by Apple); Linux uses OpenSSL, but Linux compilation is not available on this host. The compiler was self-bootstrapped again through two identical generated-C stages, and all 22 YAZA tests pass. The current tests cover API typing and closed-handle errors, not successful TLS handshakes, so TLS is still prototype transport infrastructure and cannot yet be called production-verified. std/pg/transport.yz now performs SSLRequest negotiation, TLS upgrade, and SCRAM-SHA-256 startup authentication; live-server behavior and simple-query execution remain untested or incomplete; the sample API still uses libpq.

2026-10-24: Pure-YAZA simple-query execution

Added pg_simple_query_message, pg_query, PgQueryResult, and column/cell accessors to std/pg/protocol.yz and std/pg/transport.yz. The query runner requires an already TLS-verified connection, applies a single overall deadline, accepts one command/result set, reads through ReadyForQuery, preserves SQL NULL separately from empty text, and decodes text-format scalar values through the existing OID codec. It caps accumulated response frames at 16 MiB and stored cells at 10,000; malformed or oversized results are drained to the protocol boundary when possible, while transport/framing loss closes the handle. Unit tests verify query framing, metadata/value extraction, typed integer decoding, SQL NULL, and malformed result storage; the suite passes 22/22. This does not establish live TLS/PostgreSQL interoperability. The SQL string is unparameterized and must be trusted static input. Extended-query parameter binding, row-to-shape mapping, API integration, transactions, and pooling remain outstanding.

2026-10-24: Parameterized pure-YAZA PostgreSQL queries

Added pg_bind_values_message, which encodes bounded text parameters separately from SQL and supports SQL NULL through a validated parallel flag list. pg_bind_text_message now uses that checked implementation. pg_parse_message_with_oids and pg_extended_query_message_with_oids encode checked PostgreSQL parameter OIDs; pg_query_params_typed sends the exchange through the same bounded response loop as pg_query. The response loop accepts extended-query completion/NoData frames and returns the same NULL-preserving result model. Tests assert injection-shaped input remains data, encoded lengths, empty-string versus NULL encoding, OID count/range/serialization, mismatched flags, metadata validation, and the exact frontend message sequence; all 22 tests pass, and focused protocol/transport test binaries pass ASan/UBSan with leak detection disabled for the current arena runtime. This does not yet provide native YAZA-to-PostgreSQL value encoders, live server verification, API migration from libpq, transaction helpers, or pooling.