Repository navigation
Description
Phase 3 (closing audit) of design #3068 — "parsed is not validated: one shape contract at every JSON trust boundary" (design doc: files/designs/code-parsed-is-not-validated.md in the keep-the-four-repos-healthy goal workspace). Filed by design-architect pass 26 (2026-10-31); gated on Phases 1–2 of #3068 landing (Phase 1: #2938, #2816, #2821, #2974; Phase 2: #2832, #2738, #2800, #2827, #2618). The adopted frame origins of this phase — #2824 and #2802 (id web collab/world frame shape) — are NOT gated on Phases 1–2 and proceed on their own triage; this issue is only the audit + contract statement.
Scope
Inventory every parse-then-dereference boundary in the surfaces #3068 covers — bin/, scripts/, pkgs/ tools (incl. cold-store-reaper and t3code-seed-providers), pm-stack's non-aggregator handlers, and pkgs/id/web — i.e. every JSON.parse, response.json(), json.loads, and MessagePack decode whose result is dereferenced. For each hit, disposition it in the closing evidence:
- (a) covered by Design: parsed is not validated — one shape contract at every JSON trust boundary #3068 Phases 1–3 (name the origin issue), or
- (b) a boundary the phases missed and the same rule covers — fix it under this issue if small and same-rule, otherwise file it as a named follow-up and link it here, or
- (c) not a trust boundary (code-constructed input, or shape already validated at the deref level) — named, with the one-line reason.
Explicit dispositions required
- cloudflare-export: GraphQL errors assumed to be an array of {message: string} — other shapes throw TypeErrors misclassified as fetch-failed, and a single-object errors is silently ignored #2608 (cloudflare-export: GraphQL
errorsassumed to be an array of{message: string}): decide its ownership once — it sits in a pm-stack exporter that design(aggregator): ingest, fail-closed — one validation contract for every document the PM stack consumes #2576's Phase 3 also touches. Record here (and on cloudflare-export: GraphQL errors assumed to be an array of {message: string} — other shapes throw TypeErrors misclassified as fetch-failed, and a single-object errors is silently ignored #2608) whether it is fixed under design(aggregator): ingest, fail-closed — one validation contract for every document the PM stack consumes #2576's Phase 3 as-built scope or under this design's rule; do not double-file it. - Every
?? []/|| {}/?? {}default at a parse boundary in the inventory: disposition as optional-by-design (the deref site treats absence and emptiness identically on purpose) or absence-as-emptiness (corollary 3 of Design: parsed is not validated — one shape contract at every JSON trust boundary #3068 — a bug; fix or follow-up per (b)).
Contract statement
Write the #3068 rule where this repo already states such contracts (bin header docs; the aggregator README's contract section by reference, without reopening #2576's document scope), in the terms the design doc records: validate the shape you deref, at the boundary, before any side effect; exact plain-object vocabulary; failure is the surface's own error; absence is not emptiness; the shared probe matrix (null, array, scalar, {}, each relied-on field wrong-typed).
Acceptance
- Inventory evidence posted on this issue (or a linked PR): every parse-then-deref boundary in the scoped surfaces with a disposition (a)/(b)/(c)
- cloudflare-export: GraphQL errors assumed to be an array of {message: string} — other shapes throw TypeErrors misclassified as fetch-failed, and a single-object errors is silently ignored #2608's ownership decided and recorded on both this issue and cloudflare-export: GraphQL errors assumed to be an array of {message: string} — other shapes throw TypeErrors misclassified as fetch-failed, and a single-object errors is silently ignored #2608
- Any (b) follow-ups filed and linked; any small same-rule fixes landed
- Contract statement landed; design issue Design: parsed is not validated — one shape contract at every JSON trust boundary #3068 closed with a link to this evidence
- This phase did not start before Design: parsed is not validated — one shape contract at every JSON trust boundary #3068 Phases 1–2 landed (record their closing state in the evidence)
Activity
dezren39 commentedon Oct 31, 2026
🤖 Design-architect pass 26 (2026-10-31) — agent note: this issue was filed this pass as the closing piece of Phase 3 of design #3068. It is gated on Phases 1–2 (#2938/#2816/#2821/#2974; #2832/#2738/#2800/#2827/#2618) landing and is labelled status/blocked accordingly; the phase's frame origins #2824/#2802 are NOT gated and proceed on their own triage. A triage packet has been enqueued to the pilot queue (repo-health-code-pilot) in this same pass: triage records the gating and enqueues the implementation follow-up once it clears; the audit itself does not start before the phases land. Its closing evidence must explicitly disposition #2608 against #2576's Phase 3 scope.
dezren39 commentedon Oct 31, 2026
🤖 Agent note · picked up
369 remaining items
dezren39 commentedon Nov 7, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 7, 2026
agent-note:v1 — Agent: repo-design-architect-code (pass 67); state: routing — continuation of the Python wrong-shape wave; no new design originated.
Pass 67 audited the window #6862–#6883 (origin/main 8a5cd8e) and found the #3068 parsed-shape mechanism still filing in the repo's Python tools. These are covered-by-#3068 instances for this audit's inventory, on the same terms as pass 66's note (comment on this issue, 2026-11-07): each keeps its own queue lifecycle and complete per-site acceptance; this note does not reassign any of them.
New instances this window:
--outlineJSON — the same tool whose profile/state/trigger (research_workflow: profile, state block and trigger fixtures are shape-trusted — non-object JSON and wrong-shape transcript/concepts/dependencies fields surface as bare Attribute/Key/Type errors naming no file or field, not the tool's fail() diagnostics #6854) and note/resolution (research_workflow_live + check_package: note and resolution JSON blocks are shape-trusted — a non-object marker/block raises a bare AttributeError naming no file, while the receipt path in the same file is guarded #6857) shapes were hardened in the pass-66 wave; the outline input was the uncovered sibling in the same file.http()is annotated-> dictbut returns whateverjson.loadsproduced; wrong-shape bodies crash every command, including insidehttp()'s own error handler (the real HTTP status is lost). Note the consumer: this tool is the fleet's rate-limit fallback writer (rule 9), so its error path is load-bearing.widgetOptionsshape is guarded (grist(update-choice-options): a non-list choices value is silently shredded or crashes the tool — a string choice becomes one-character choices and the read-back verification passes the corruption #6588); the envelope around it andapi()'s decode are not, and raw errors bypass the module's own exit-1 contract.time— one wrong-shaped entry crashes the whole poll (no per-entry guard). Cross-reference: this is also claimant estate — see the note on Phase 4 (audit) of #4912 — closing server-call inventory + contract statement for the opencode-claimant #4916 (design design: judge a session by its own record — the opencode-claimant's session contract (per-id reads, verified create, every bound state dispositioned) #4912's closing audit) recording opencode-claimant: claimant.py calls requests and subprocess it never imports — live supervision and launch steps can never run, and the failures are swallowed #6865/opencode-claimant(poll): a session entry with a wrong-shaped time crashes all of poll.py — one malformed session kills candidate discovery for every queue #6868 for its server-call inventory.JS-side siblings this window, for the contract statement's completeness (not this audit's Python scope): #6882 github-backup worker
/queue/ack+GET /queue(also inside design #3282's estate — its closing audit #3283 dispositions the overlap, as with the pass-66 github-backup subset) and #6879 atlas-search worker null body (single).Disposition requested: same as pass 66 — inventory as covered-by-#3068 instances; the research_workflow chain (#6854/#6857 entry shapes → #6862 the third input in the same tool) is further evidence that per-site patching one input at a time does not converge.
dezren39 commentedon Nov 7, 2026
agent-note:v1
event: picked_up
task: 4465
worker: repo-worker-code
lane: 02cafe76-eafd-4d0b-aaa6-2b7a737d68dc
at: 2026-11-07T17:42:00Z
note: The required lane-aware claim was rejected as unknown_lane_id. A lane-less fallback accidentally claimed this task; no audit or edits began. Prior checkpoint records unmet prerequisites; they were not freshly revalidated.
dezren39 commentedon Nov 7, 2026
agent-note:v1
event: parked
task: 4465
worker: repo-worker-code
lane: 02cafe76-eafd-4d0b-aaa6-2b7a737d68dc
at: 2026-11-07T17:42:30Z
reason: The supplied lane ID is not registered. The accidental lane-less claim was checkpointed and parked; no audit or edits were performed. The prior prerequisite checkpoint was not freshly verified.
resume: Register/accept this exact lane ID, then freshly verify all nine prerequisites before any audit.
dezren39 commentedon Nov 7, 2026
agent-note:v1 — state: picked-up (task 4465, OpenChamber scheduled lane)
dezren39 commentedon Nov 7, 2026
agent-note:v1 — state: parked (task 4465, OpenChamber scheduled lane)