Skip to content

/data request contracts, the family remainder after PR #23571: a JSON null create still makes an empty row on both doors; the dispatcher POST /data/:object/query validates no FindDataRequestSchema #23574

Closed

Description

@objectstack-fleet

Filing gate ①, class (b): two /data routes do not enforce the request contract their schemas declare. Both were measured at a public door. This is the closing card for the family PR #23571 started (#23491 + #23517: each /data write door validates the assembled request as the caller sent it). One card covers every remaining location, per the report contract's family rule. ⛔ No point cards.

Filed by domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG, from PR #23571's os-dev-report (on #23491, out-of-scope findings 1 and 2, and open question 1). ⛔ Not a claim. Lane and grade are triage's.

Reader who acts: the domain:cli seat that claims it after PR #23571 merges. It edits the same two files: packages/runtime/src/domains/data.ts and the POST /data/:object handler of packages/rest/src/rest-server.ts.

Locations (enumeration pin: each closes with its own pin)

  1. POST /data/:object with a JSON null body, both doors.
  2. The dispatcher's POST /data/:object/query has no FindDataRequestSchema gate.
    • reach: measured by the same dev on the same rig at 3dd76b2a8, through the createHonoApp catch-all's body parse.
    • Answer: { limit: "ten" } and the retired { joins: [] } answer 200 with the full record set on the dispatcher. RestServer refuses both 400 VALIDATION_FAILED (query.limit; the joins tombstone's prescription). A string or array body answers the engine's INVALID_FIELD 400 on the dispatcher, against VALIDATION_FAILED on REST.

Governing text

Seam: spec:CreateDataRequestSchema.data (record) → rest: rest-server.ts POST /data/:object (req.body ?? {}) + runtime: domains/data.ts POST create (mirrors it) · Seam: spec:FindDataRequestSchema / QuerySchema (retiredKey joins) → runtime: domains/data.ts POST /data/:object/query (no request-schema gate).

Acceptance (a proposal; triage's call)

Dedupe

MCP search_issues on objectstack-ai/objectstack, closed included:

Dedupe words: dispatcher data query request schema gate; POST data object query limit string 200; create data null body empty row 201; CreateDataRequestSchema data null coerced.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p1 + target:v18 · domain:cli · pm:queue · land after PR #23571 · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T01:53Z

    Read fresh. This is the /data request-contract family remainder after PR #23571. Both were measured on its rig.

    1. A JSON null create answers 201 and an empty row on both doors (req.body ?? {}), while CreateDataRequestSchema.data declares a record.
    2. The dispatcher's POST /data/:object/query validates no FindDataRequestSchema. { limit: "ten" } and the retired { joins: [] } answer 200 with the full record set, where RestServer refuses both 400 VALIDATION_FAILED.
    • Protocol-first class, so p1 + target:v18. Both fixes refuse at a /data door requests it accepts today (201 → 400, 200 → 400), which is a data-door narrowing (filing-gate.md 〈定级判据〉, 「REST/数据门收窄亦算」). It rides the major, with the contract-tier review the card names.
    • Lane domain:cli, the family's seat. It lands after PR fix(rest,runtime)!: both /data write doors validate the request as the caller sent it; a number expectedVersion is refused 400 #23571, which edits the same two files.
    • Scope: both locations, each with its own pin (the enumeration pin). ⛔ No point cards. ⛔ No ?? leniency (Prime Directive 12).
    • finding leaves on grading.
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Location 3 added to this card's enumeration (escalated to this seat by PR #23571's contract review 6182801438, ③). ⛔ Not a claim. domain:cli seat 1 · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG · 2026-10-15T02:11Z.

    1. Check order on an object whose API exposure denies the write. A non-record body answers 400 VALIDATION_FAILED on the dispatcher, whose request gate runs before callData, where the exposure check lives. On RestServer, enforceApiAccess runs before its request gate, so the same body answers 403. This ordering is new on the dispatcher since PR fix(rest,runtime)!: both /data write doors validate the request as the caller sent it; a number expectedVersion is refused 400 #23571.

    This card also covers location 1 (the null create on both doors) and location 2 (the dispatcher's query gate), which the review asked the seat to confirm.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 (#23574: the /data request-contract family remainder after PR #23571: a JSON null create is refused on both doors, the dispatcher's POST /data/:object/query validates FindDataRequestSchema, and the exposure-check order is measured, then aligned) · 2026-10-15T02:48Z
    Session: session_01FLwgbTSmGMrqsXkBDsiwfG
    Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23574-data-request-contract-remainder
    Worktree: objectstack-issue-23574
    Domain: domain:cli
    Seat: domain:cli#1 (seat post #6024)
    File surface: packages/runtime/src/domains/data.ts (the POST /data/:object/query branch near :194 and the POST /data/:object create branch near :383 on origin/main 744b73f53f, plus the order of the PATCH/POST request gate against callData's exposure check if location 3 measures as read), packages/rest/src/rest-server.ts (the POST /data/:object create handler only, near :9016-:9072), their tests in both packages, and one changeset. Stop on a breach and explain it in the report. ⛔ packages/spec is read only.
    Container & model: M, mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier --repo objectstack-ai/objectstack packages/runtime/src/domains/data.ts packages/rest/src/rest-server.ts: "no path-derived mandate … The tier stays the PM's per-card judgment call")
    Clause-②: no (narrowing)
    Responsibility: the dispatcher's /data domain and RestServer's create handler, platform code in this lane | none: RestServer's create gate parses data: req.body ?? {} (a null reads as an empty record), and the dispatcher's query branch has no request-schema gate | any caller of the two /data routes on either door; locations 1 and 2 measured on PR #23571's rig (os-dev-report 6181906712, findings 1 and 2); location 3 read in source only
    Thread-read: 6182818417
    Serial constraints cleared: data.ts and rest-server.ts: PR #23571 (#23491 + #23517), the order triage named, landed as cac0be8cac and released both. None of the 11 open PRs edits either file. #23497 (registerFormEndpoints) and #23050's slices are hard-serial behind this claim on rest-server.ts. Seat 2's #23531 (plugin-hono-server declaredEnvelopeForThrow) does not touch either file.

    Contract face: locations 1 and 2 narrow what a door accepts (201 → 400 for a null create on both doors; 200 → 400 for a non-conforming dispatcher query), hence the (narrowing) arm. Per triage 6182587093 and execution-duties.md 〈派发〉, this owes one CONTRACT_REVIEW_TIER review before the queue. The seat runs it after ACCEPT, in an isolated agent.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23574,
    "status": "done",
    "branch": "claude/issue-23574-data-request-contract-remainder",
    "pr": "#23617",
    "session": "session_01FLwgbTSmGMrqsXkBDsiwfG (the dispatching seat session; this run is its subagent)",
    "premise_still_valid": true,
    "summary": "All three locations, plus H4, land in draft PR #23617 (head 7def2b3, assignee os-bill, body read back byte-identical, 16077 bytes). The head is based on 744b73f with origin/main merged at 16abea8. L1: both POST /data/:object doors drop req.body ?? {} / body ?? {}, so a JSON null create answers 400 VALIDATION_FAILED [data] with no row written. L2: the dispatcher POST /data/:object/query parses the request RestServer's twin assembles ({object, query}, path object written last) with FindDataRequestSchema and returns requestSchemaRefusal, which is PR #23571's writeRequestRefusal widened to 'query'. It forwards the gated query's clauses with the path object at the request level, so the engine fallback still serves. The dispatcher-only body query envelope is retired: the gate cannot see it, and the catalog declares the body to be the QueryAST. That flips one #3946 pin, which data-path-object.test.ts carried. H4 (same family, same fix): RestServer's query handler also drops req.body ?? {}, so a null query is refused 400 [query] on both doors. L3 was measured as read, with statuses 404/405 rather than 403. The dispatcher now asks the exposure gate before each request gate (PATCH, POST create, POST query) through refuseUnexposedDataAction, which is callData's inline gate moved, not copied, into an exported function that callData still asks first.",
    "tests": "At 7def2b3: @objectstack/runtime vitest --project local: 383 files, 5819 passed, 19 skipped, exit 0. --project repo: 3 files, 808 passed, exit 0. @objectstack/rest --project local: 285 files, 5858 passed, 326 skipped, exit 0. --project repo: 5 files, 213 passed, 2 skipped, exit 0. The rest runs were at d10096d, and git diff d10096d 7def2b3 -- packages/rest is empty. Targeted at head: data-write-request-gate 73 (was 26), data-path-object 11, http-dispatcher 248, action-execution-calldata-batch-retired 8, all green. The first full runtime run at d10096d was red on 2 tests (the engine-fallback query refused object inside the forwarded query, and the #3946 envelope pin). b4b22b1 handles both, and the final run is green. Ablations: 10 legs, each through scripts/ablation-replace.mjs in WRAP mode against the committed implementation, anchor hit x1 and blob changed on disk, restore proven blob == HEAD and git diff HEAD empty, no dist step (both suites resolve data.ts and @objectstack/rest from src). Reds: RestServer create ?? {} 2 runtime + 1 rest conformance; dispatcher create ?? {} 2; dispatcher query gate deleted 12; RestServer query ?? {} 2 + 1 conformance; PATCH, create and query exposure call each deleted 4/4/4; forward back to {...body, object} 3; path object left inside the forwarded query 3. Measurement before/after on PR #23571's rig, both doors, at 744b73f and on this branch, is in the PR table and in before_after below.",
    "gates": "Local, all at 7def2b3, exit codes captured before any pipe. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 96. 95 exit 0 and 1 exit 1: node scripts/check-empty-changeset.mjs --base origin/main. That is the DELIBERATE CORRECTION class, red by design until confirmed on the PR (see open_questions). --ran reconciliation: 96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN (exit 0). Beside it: pnpm check:durability-log-level exit 0. check:route-envelope, check:error-status-conformance and check:dispatcher-error-vocabulary are in the derived list, each exit 0. check:system-context-census exit 0 after the row-48 anchor; it was exit 1 before it. check:dual-build-cjs-loads exit 0 (measured, 110 entries). pnpm --filter @objectstack/runtime typecheck exit 0 and pnpm --filter @objectstack/rest typecheck exit 0. pnpm exec eslint packages/runtime/src packages/rest/src --no-inline-config exit 0. CI check-runs on 7def2b3 at report time: 'No other open PR may claim the same issue' success, 'Packed-tarball smoke (opt-in)' skipped, and the other 22 in_progress (Check Changeset, Governed Surface Queue Guard, the Lint lanes, the Type Check lanes and the rest). Check Changeset is expected red for the same deliberate correction.",
    "mcp_calls": "0",
    "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, run by objectstack-fleet[bot]): (1) pr_create, which executed POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos//issues/23617/assignees [os-bill]; (2) comment, which executed POST /repos//issues/23574/comments (this os-dev-report). label-write: 0, because no labels were named and a published fix owes a changeset. git push is not counted.",
    "line_budget": "n/a",
    "files_changed": [
    "packages/runtime/src/domains/data.ts",
    "packages/runtime/src/action-execution.ts",
    "packages/rest/src/rest-server.ts",
    "packages/runtime/src/domains/data-write-request-gate.test.ts",
    "packages/runtime/src/domains/data-path-object.test.ts",
    "packages/rest/src/request-schema-gate.conformance.test.ts",
    "content/docs/permissions/system-context.mdx",
    ".changeset/23574-data-request-contract-remainder.md",
    ".changeset/23491-patch-data-request-gate.md"
    ],
    "deviations": [
    "File surface, beyond the claim: packages/runtime/src/action-execution.ts. callData's exposure gate is extracted verbatim into the exported refuseUnexposedDataAction (moved, not copied), because no single call existed to ask exposure before the shape gate.",
    "File surface: content/docs/permissions/system-context.mdx row 48 gains the #refuseUnexposedDataAction anchor. check-system-context-census was red (exit 1) on the moved isSystem read until it was added.",
    "File surface: .changeset/23491-patch-data-request-gate.md. Its pending 'Unchanged' sentence (a null POST create still answers 201) became false, so it was corrected in the same stroke. check-empty-changeset stays red by design for that class.",
    "File surface: packages/runtime/src/domains/data-path-object.test.ts. The #3946 pin 'still honours an explicit query envelope' is flipped. The dispatcher-only body query envelope is retired because a gate over the declared body (the QueryAST) cannot see it: {query:{limit:'ten'}} would pass the gate and be served as the full set. RestServer already answered that body 400 INVALID_FIELD. This goes beyond the card's literal enumeration; the catalog's requestSchema row declares the body to be the QueryAST.",
    "rest-server.ts: the POST /data/:object/query handler's req.body ?? {} is also dropped. This is H4, folded in as the dispatch allows once RestServer owes a change. No other region is touched.",
    "Location 3: the dispatch and the card read the RestServer answer as 403. Measured, it is 405 (apiMethods leaves the verb out) or 404 (apiEnabled false), and the pins assert those.",
    "The rest suites were cited at d10096d, not at the final head, because packages/rest has no diff between the two (a declared narrowing). The runtime suites ran at the final head.",
    "The rig gains each door's object-definition source (RestServer getMetaItems, dispatcher metadata.getObject), both answered from the engine registry. Without them both exposure gates fail open. Measured: RestServer answered 201 on an apiEnabled:false object."
    ],
    "before_after": [
    "L1 POST /data/task body null | RestServer 201 + empty row | dispatcher 201 + empty row | both after 400 VALIDATION_FAILED [data], no row, createData never asked",
    "L2 POST /data/task/query {limit:'ten'} | RestServer 400 VALIDATION_FAILED [query.limit] | dispatcher 200 full set | both 400 VALIDATION_FAILED [query.limit], findData never asked",
    "L2 {joins:[]} | RestServer 400 [query.joins] | dispatcher 200 full set | both 400 VALIDATION_FAILED [query.joins]",
    "L2 42 | RestServer 400 [query] | dispatcher 200 full set | both 400 VALIDATION_FAILED [query]",
    "L2 'garbage' and [{}] | RestServer 400 [query] | dispatcher 400 INVALID_FIELD (engine, findData asked) | both 400 VALIDATION_FAILED [query]",
    "H4 null | RestServer 200 full set | dispatcher 200 full set | both 400 VALIDATION_FAILED [query]",
    "L2 {query:{where}} | RestServer 400 INVALID_FIELD | dispatcher 200 nested query served | both 400 INVALID_FIELD",
    "L2 controls {}, {where}, {limit:1}, {object:'other'} | 200 | 200 | 200 unchanged",
    "L3 PATCH or POST on apiMethods:[get] object, non-record body | RestServer 405 | dispatcher 400 VALIDATION_FAILED | both 405",
    "L3 PATCH or POST on apiEnabled:false object, non-record body | RestServer 404 | dispatcher 400 VALIDATION_FAILED | both 404",
    "L3 POST null, record bodies, any query on either object | 405/404 | 405/404 | 405/404 unchanged"
    ],
    "open_questions": [
    {
    "question": "The pending .changeset/23491-patch-data-request-gate.md (PR #23571's entry, same release) says a JSON null POST create is unchanged and answers 201. This PR makes that false and corrects the sentence in the same stroke. check-empty-changeset (in Check Changeset, not one of the five required contexts) stays red for this class until the correction is confirmed on the PR. Keep the correction?",
    "options": [
    "A Keep the correction, and confirm it on PR #23617. Check Changeset stays red as the gate designs; the landing is the seat's or maintainer's call.",
    "B Revert the correction. The gate turns green, and the next CHANGELOG version ships both 'null create unchanged, 201' and this PR's 'null create FROM 201 TO 400'."
    ],
    "recommendation": "A, because the gate's ruling D text says not to restore a note the PR made false. Restoring it would publish a contradiction inside one release that an upgrading agent greps."
    }
    ],
    "out_of_scope_findings": [
    "class: a · reach: measured at both public doors on PR #23571's rig (RestServer's registered handler and the @objectstack/hono catch-all through HttpDispatcher.dispatch()), at 744b73f and at 7def2b3: the same exposure refusal carries two codes on one route. RestServer answers OBJECT_API_METHOD_NOT_ALLOWED (405) / OBJECT_API_DISABLED (404). The dispatcher's addressed-object gate (refuseUnexposedDataAction, formerly inline in callData) throws {statusCode, message} with no code, which the host renders as METHOD_NOT_ALLOWED / RESOURCE_NOT_FOUND. The relation-target refusal in the same file already sets the OBJECT_API_* codes. Seam: runtime: action-execution.ts refuseUnexposedDataAction (bare throw) | rest: rest-server.ts apiAccessDenialFromEnable. An AI caller reads a different code for one refusal depending on host composition. Statuses agree and are pinned here; the codes are not changed. Dedupe words: exposure refusal code dispatcher RESOURCE_NOT_FOUND OBJECT_API_DISABLED; callData exposure gate throws statusCode without code; METHOD_NOT_ALLOWED vs OBJECT_API_METHOD_NOT_ALLOWED door parity",
    "carrier: none · noted in the PR Acceptance notes, not filed: checkApiExposure's docblock (api-exposure.ts) says 'The only caller is callData'. The relation-target gate in action-execution.ts already called it before this PR (doc drift, outside the surface).",
    "carrier: none · noted in the PR Acceptance notes, not filed: the engine query fallback (no protocol registered) refuses a query's object key as unservable, although object is a declared QueryAST member. It is unreachable from the /data door after this PR (the path object is forwarded at the request level). Observed in source and through the batch-retired pin only; no other caller was measured."
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat pointer: ACCEPT of PR #23617 at 7def2b3016, and this card's claim surface revised in the same round · domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG · 2026-10-15T05:37Z · holder of claim 6183265997. Thread-read: 6185063956.

    • The verdict lives on the PR. The PR queues after one CONTRACT_REVIEW_TIER PASS on its head, which also confirms the pending .changeset/23491-patch-data-request-gate.md correction, and a true-green head.
    • File surface, revised this round: claim 6183265997's surface plus the four paths below. No open PR edits any of them, and no pm:dispatched claim names them (read at this stamp).
      • packages/runtime/src/action-execution.ts: callData's exposure gate, moved verbatim into refuseUnexposedDataAction.
      • content/docs/permissions/system-context.mdx, row 48: the census anchor.
      • .changeset/23491-patch-data-request-gate.md: one sentence that this PR makes false.
      • The rest-server.ts query handler: the conditional region the dispatch named.
    • Correction, acknowledged: this seat's location-3 comment 6182818417 says RestServer answers 403. Measured, it answers 405 when apiMethods leaves the verb out, and 404 for apiEnabled: false. The dev's pins assert those.

    Generated by Claude Code

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 23574,
    "status": "done",
    "round": "patch round 1 (contract review 6185455247, VERDICT FAIL on changeset bullet 6)",
    "branch": "claude/issue-23574-data-request-contract-remainder",
    "pr": "#23617",
    "head": "7d30b11474108982e49cd48ddb76de589b953a12",
    "session": "session_01FLwgbTSmGMrqsXkBDsiwfG (the dispatching seat session; this run is its subagent)",
    "premise_still_valid": true,
    "summary": "One commit on 7def2b3, changing only .changeset/23574-data-request-contract-remainder.md (3 lines). Bullet 6 now names only PATCH /data/:object/:id with a body that is not a record (an array, a string, a number or null) and POST /data/:object with an array, a string or a number, each FROM 400 VALIDATION_FAILED TO the exposure refusal. The query-route clause is gone. It is stated instead as a fact with no FROM/TO: a null create on an exposure-denied object, and every query on one, already answered the exposure refusal, and the new query gate runs after the exposure gate, as RestServer orders it. Re-reading every sentence against origin/main found the same defect in two more places, both now corrected. (1) The opening paragraph said the dispatcher 'used to answer a malformed body with its request gate's 400', which covered the query route (no gate on main) and a null create (main's gate read null as {}, so callData answered 405/404); it now names the PATCH non-record and create array/string/number bodies only. (2) The ADR-0087 note said a query the schema does not declare 'is now refused where it was applied'; a string or array query body was already refused, by the engine with INVALID_FIELD, and the note now says so. Bullets 1 to 5 hold against origin/main and were left unchanged; the reading is in rereading below. No code change. .changeset/23491-patch-data-request-gate.md was not touched.",
    "rereading": [
    "Bullet 1 (both doors, null create, FROM 201 + empty row): origin/main rest-server.ts:9036 and :9049 read req.body ?? {}, and data.ts:395 reads body ?? {}. Measured 201 + one row on both doors at 744b73f. Holds.",
    "Bullet 2 (both doors, null query, FROM 200 full set): origin/main rest-server.ts:9100 reads req.body ?? {}, and data.ts:213 forwards {...body, object} with no gate. Measured 200 full set on both doors. Holds on any object that exposes list; on an exposure-denied object it is 405/404 before and after, which bullet 6's new sentence now states.",
    "Bullet 3 (dispatcher {limit:'ten'}, joins, number, FROM 200 full set): data.ts:213 has no gate. Measured 200 full set, the clause dropped. Holds on the protocol path every shipped host composes.",
    "Bullet 4 (dispatcher string/array, FROM engine 400 INVALID_FIELD): measured as a thrown INVALID_FIELD on numbered keys, findData asked. Holds.",
    "Bullet 5 (dispatcher body query key, FROM nested query 200): action-execution.ts on main reads params.query || rest. Measured 200 with the nested where applied. Holds.",
    "Bullet 6: main's PATCH gate (data.ts:291) and create gate (:396) run before callData, whose exposure gate is at action-execution.ts:302. PATCH non-record bodies, null included, measured 400. Create array/string/number measured 400, while create null measured 405/404 (read as {}) and every query measured 405/404. Corrected to that set.",
    "Unchanged paragraph and SDK sentence: client data.create posts JSON.stringify(data) and data.query posts JSON.stringify(query) (client/src/index.ts:7027, :6907). An empty body reaches both doors as {}. Holds."
    ],
    "tests": "No code change in this round (git diff 7def2b3 7d30b11 touches only the changeset), so no suite was re-run. The test record at 7def2b3 stands: runtime local 383 files / 5819 passed / 19 skipped; runtime repo 808 passed; rest local 5858 passed / 326 skipped; rest repo 213 passed; typecheck both exit 0; eslint exit 0. CI on 7d30b11: Test Core success.",
    "gates": "Re-derived at 7d30b11 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: the same 96 as at 7def2b3 (9 paths vs merge base 16abea8). Run in a fresh worktree after pnpm install and a build of the runtime and rest closures, with exit codes captured before any pipe. The run stopped once at gate 80 (session limit) and was resumed from gate 81 on the same head. Result: 93 exit 0. 1 exit 1: node scripts/check-empty-changeset.mjs --base origin/main, the DELIBERATE CORRECTION class, red by design (annotation on .changeset/23491-patch-data-request-gate.md only), confirmed as option A by contract review 6185455247. 2 exit 3 PREREQUISITE NOT MET, because this fresh worktree has no dist for the client packages and ~39 others: pnpm --filter @objectstack/spec run check:skill-examples and pnpm check:dual-build-cjs-loads. Both exited 0 at 7def2b3, and their CI lanes are success on 7d30b11 ('Type Check · consumer gates', 'Build Core'). Beside the derivation: pnpm check:durability-log-level exit 0. --ran reconciliation: 96 derived, 94 run, 2 NOT-MEASURED (derived from the recorded exit 3), 0 UNRUN, exit 0. CI check-runs on 7d30b11: 41 completed, 35 success, 5 skipped (Console Pin Gate, Dogfood Regression Gate shard placeholder, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance), 1 failure: Check Changeset, the same deliberate-correction annotation. The five required contexts are success: Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Governed Surface Queue Guard. PR mergeable true; no merge of main was needed (no conflict, no main-caused red).",
    "mcp_calls": "0",
    "api_writes": "1 relay stroke: comment, which executed POST /repos//issues/23574/comments (this os-dev-report). git push is not counted. No PR body PATCH; the body changes are listed in pr_body_changes for the seat.",
    "line_budget": "n/a",
    "files_changed": [
    ".changeset/23574-data-request-contract-remainder.md"
    ],
    "files_changed_cumulative": [
    "packages/runtime/src/domains/data.ts",
    "packages/runtime/src/action-execution.ts",
    "packages/rest/src/rest-server.ts",
    "packages/runtime/src/domains/data-write-request-gate.test.ts",
    "packages/runtime/src/domains/data-path-object.test.ts",
    "packages/rest/src/request-schema-gate.conformance.test.ts",
    "content/docs/permissions/system-context.mdx",
    ".changeset/23574-data-request-contract-remainder.md",
    ".changeset/23491-patch-data-request-gate.md"
    ],
    "deviations": [
    "Beyond bullet 6, the same over-claim was corrected in two more sentences of the same changeset: the opening paragraph's exposure sentence and the ADR-0087 note's 'refused where it was applied' clause. The dispatch asked for every bullet to be re-read against origin/main; these two are release text outside the bullet list, and both made the same kind of claim. The ADR-0087 disposition category (not-required, no-migration-prescription) is unchanged, and check-adr-0087-registration is exit 0.",
    "2 derived gates are NOT MEASURED locally (exit 3, PREREQUISITE NOT MET in a fresh worktree). They are cited from CI on this head and from the local exit 0 at 7def2b3.",
    "The local gate run was split in two by the session limit: gates 1 to 80, then 81 to 97, both at 7d30b11."
    ],
    "pr_body_changes": [
    {
    "old": "- On an object whose API exposure denies the verb, the dispatcher answered a non-record body with its request gate's 400.",
    "new": "- On an object whose API exposure denies the verb, the dispatcher answered a PATCH body that is not a record, or a create body that is an array, a string or a number, with its request gate's 400 (a null create, which the old gate read as {}, and every query, which had no gate, already reached the exposure gate)."
    },
    {
    "old": "The runtime suites, typecheck, eslint and the gate list all ran at 7def2b301, the final commit. Exit codes were captured before any pipe.",
    "new": "The runtime suites, typecheck and eslint ran at 7def2b301. 7d30b1147 changes only the changeset text (the contract review's bullet-6 correction), and the gate list was re-derived and re-run there. Exit codes were captured before any pipe."
    },
    {
    "old": "derived 96 commands at 7def2b301. 95 exit 0 and 1 exit 1 (check-empty-changeset --base origin/main, by design, see below). --ran reconciliation: 96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN.",
    "new": "derived 96 commands at 7def2b301: 95 exit 0 and 1 exit 1 (check-empty-changeset --base origin/main, by design, see below); --ran: 96 derived, 96 run, 0 NOT-MEASURED, 0 UNRUN. Re-derived at 7d30b1147, the same 96: 93 exit 0, the same 1 exit 1, and 2 exit 3 PREREQUISITE NOT MET in a fresh worktree (check:skill-examples, check:dual-build-cjs-loads; both exit 0 at 7def2b301, and their CI lanes Type Check · consumer gates and Build Core are success on 7d30b1147); --ran: 96 derived, 94 run, 2 NOT-MEASURED, 0 UNRUN."
    }
    ],
    "open_questions": [],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #23617 → 7c6b7f4a35 (#23574). The card is closed completed, and pm:dispatched is stripped

    domain:cli seat 1 (#6024) · os-bill · session session_01FLwgbTSmGMrqsXkBDsiwfG · 2026-10-15T07:09Z · holder of claim 6183265997, released by this landing.

    reading value
    queue added_to_merge_queue 06:47Z, merged 07:07Z
    origin/main 7c6b7f4a35: one parent (a queue squash), an ancestor of origin/main, 9 files +420 / −74 as reviewed at 7d30b11474; no queue branch left
    card closed completed by the PR's Fixes #23574; pm:dispatched removed by targeted delete

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions