Files
alkhttp/tasks/adapters/review-002-projection-truthfulness.md
T
glm-5.3-flash e2c255d40c docs(tasks): decompose review-002 into 24 tasks (23 implementation + 1 bracketed follow-up)
Decomposition of docs/reviews/002-post-remediation-review.md per its
5-unit remediation plan:

- Unit 1 (security-critical): gw15-publish-body-cap,
  prj16-schema-via-call (CF-004 filed alkcall-side), fwd13-dot-segments,
  fwd16-missing-capability, oai11-ref-memoization
- Unit 2 (timeout/terminality): ws13-idle-progress,
  fwd15-stream-timeout, cli01-retry-after-budget, con17-mcp-pagination,
  con18-wss-sweep-exit
- Unit 3 (projection/docs): projection-truthfulness, mcp-batch-cap,
  gw16-status-drift
- Unit 4 (spec-import): yaml-normalization, oai13-path-item-wildcards,
  import-loudness-cluster, js01-placeholder-check,
  fwd17-19-contract-decisions
- Unit 5 (WS polish + tests): con18b-ws-polish,
  client-policy-wire-tests, cov-deployment-knobs, cov13-dead-code,
  srv11-srv12-router-ordering
- review-002-bracketed-followup: tentatively planned post-bulk pass
  (stale-check, OQA-18 enforcement decision, CON-08/09 close() lever,
  cross-crate re-checks) — deliberately not serialized against the
  bulk

Also: review-002 numbering repair (CON-14 was double-booked; MCP
pagination now CON-14, from_wss monitor renumbered CON-18, missing
CON-14 section added).

taskgraph: 66 valid, no cycles; 24 pending (all review-002);
gen-1/gen-2 parallel waves identified; workflow-cost hotspots are
prj16 (12.8) and ws13 (11.1), both carrying the reviewed slicing
guidance in their Notes.
2026-08-30 10:50:34 +00:00

4.3 KiB

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
review-002-projection-truthfulness Projection doc truthfulness — dangling CallError ref, status clobber/drifts, OAS-invalid extension (PRJ-16b/17/18/19/20/21/23/24) pending
moderate low component implementation
adapters
review-002
to-openapi

Description

Eight review-002 findings in to_openapi.rs (+ one in to_mcp.rs), all "the generated document must be runtime-truthful and OAS-valid" — the PRJ-01..15 remediation's remaining tail:

  • PRJ-16b [major]: BatchResultEntry.error refs #/components/schemas/CallError which does not exist (to_openapi.rs:602 vs components at :387-413 defines CallFailure + per-code variants). The openapiv3 parse test runs on an empty registry so nothing trips. Generated clients/validators fail to resolve.
  • PRJ-17: an op declaring HTTP_404@404 clobbers the shared NotFound response on /call (:694/:237-239/:295-300) — losing NOT_FOUND which the runtime still emits; every real 404 then violates the documented schema. Merge op codes into the shared response (oneOf append) instead of overwriting.
  • PRJ-18: /publish 400 over-declares INVALID_OPERATION_TYPE; runtime maps that condition to 401 without a token (the 401 entry in the same doc is the true one) (:268-277).
  • PRJ-19: extractor plain-text 415 (missing content-type) and data-error 422 (JsonDataError) undocumented on /call, /batch, /subscribe (axum 0.8 emits them; the module doc admits "plain-text 400/415/422") (:673-682).
  • PRJ-20: /call 401 under-declares — unauthenticated Sub/Pub call → 401 with INVALID_OPERATION_TYPE, absent from the enum (:218-219 vs error.rs:67-73; /publish got this split right).
  • PRJ-21: /batch documents a 500 the runtime never emits (all dispatch failures are in-band entries) (:329-334).
  • PRJ-23: x-operation-error-statuses is emitted inside components.schemas (:414-417) — extension keys are legal on components, not as a schema name; OAS-invalid on any registry with op errors. Move to components level or delete (nothing consumes it).
  • PRJ-24: dead search_filter parameter in to_mcp::handle_batch (computed then let _ = discarded) — remove.

Acceptance Criteria

  • PRJ-16b: CallError defined (generic code/message/retryable/ details) OR error points at existing per-code components via oneOf; the openapiv3 parse test runs on a populated registry (with op errors — exercising PRJ-23's key too)
  • PRJ-17: protocol-status op errors merge into the shared response (oneOf append); test with HTTP_404@404 asserting NOT_FOUND survives alongside
  • PRJ-18/20: 400 and 401 oneOf lists match error.rs's actual mapping (drop IOT from publish-400; add IOT to call-401) — conformance tests for both bodies
  • PRJ-19: 415 + plain-text 422 slots documented (extend plain_text_extractor_rejection or an equivalent shared component)
  • PRJ-21: unreachable /batch 500 removed or marked reserved
  • PRJ-23: extension key legal placement (or deleted); parse test covers the with-errors path
  • PRJ-24: dead parameter removed from handle_batch
  • Golden-doc tests updated (byte-identical assertion refreshed); cargo test --all-features, cargo clippy --all-features --all-targets -- -D warnings, cargo fmt --check pass

References

  • docs/reviews/002-post-remediation-review.md (Part F', PRJ-16b/17/18/19/20/21/23/24; Test-gaps 5/6)
  • src/adapters/to_openapi.rs:387-433 (components), :602 (dangling ref), :218-300 (status oneOfs), :414-417 (extension), :673-682 (extractor text)
  • src/gateway/error.rs:57-81 (the runtime mapping these must match), routes.rs (the runtime truth)
  • tasks/adapters/review-001-openapi-projection-fidelity.md (the PRJ-01..15 work this completes)

Notes

The review-001 lesson applies again: every fix here needs its test to run against a populated registry (the empty-registry parse test is how PRJ-16b and PRJ-23 escaped). Consider one shared golden_doc_with_ops() fixture replacing per-test registry setup. ADR-045's version bump: these are doc-contract corrections — bump info.version per ADR-045's tracking rule (gateway endpoint contract itself unchanged).