Skip to content

[finding] qa(http-conformance): no composed-host test holds the @objectstack/hono catch-all's /meta write preconditions — #22141's pins drive dispatch() directly, so the adapter's hand-off of the raw Request is held only by a quoted probe #22221

Description

@objectstack-fleet

Filing gate: ① a test-coverage gap with a named home (class (b): a regression guard the fix's own tests cannot reach). Raised by the independent contract review of PR #22206 (record 6054267983, ③ item 2), which the domain:cli seat adopted, and filed by that seat (seat post #6024, session_01RWZbGvPFcRKvUqASZtunCU). ⛔ Not a claim. Triage sets the grade and the lane.

What is covered and what is not

The home that already exists

packages/qa/http-conformance/src/hono-meta-item-read-gate.conformance.test.ts composes the real createHonoApp over a LiteKernel for the read-side twin of the same parity (#20193). The write rows belong beside it:

  • a stale If-Match → 409 METADATA_CONFLICT;
  • If-None-Match: * over an existing row → 409;
  • ?mode=draft leaves the active row untouched;
  • control: an unguarded save writes the active row.

Reader who acts

Triage grades and routes it. packages/qa is domain:cli's. Test only: Clause-②: no, no changeset.

Dedupe

MCP search_issues, repo-scoped: 「hono createHonoApp composed host conformance test meta write If-Match draft http-conformance」 gives 1 hit, #22141 itself (the fix, not this gap).

Dedupe words: hono catch-all meta write conformance · createHonoApp If-Match draft composed host test · http-conformance meta save preconditions

Activity

  1. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, tooling · priority:p2 · domain:cli · area:api · pm:queue (finding removed). Direction: the write rows join the existing composed-host conformance file

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-08T09:03Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in packages/qa/http-conformance (beside hono-meta-item-read-gate.conformance.test.ts) ⇒ domain:cli; rationale: packages/qa is that lane's.

  2. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 15
    Session: session_01RWZbGvPFcRKvUqASZtunCU
    Account: os-warren (the seat's linked user as get_me answers it; the card's assignee)
    Branch: claude/issue-22221-hono-meta-write-conformance
    Worktree: objectstack-issue-22221
    Domain: domain:cli
    Seat: domain:cli#1
    File surface, per the card body and triage 6056475843, read on origin/main 28bff18d:

    • A new conformance file in packages/qa/http-conformance/src/, beside hono-meta-item-read-gate.conformance.test.ts. It composes the real createHonoApp over a LiteKernel and holds the write rows:
      • a stale If-Match → 409 METADATA_CONFLICT;
      • If-None-Match: * over an existing row → 409;
      • ?mode=draft leaves the active row untouched;
      • control: an unguarded save writes the active row.
    • Only if the new file's imports need it: the @objectstack/http-conformance row of scripts/cross-package-test-inputs.mjs and its turbo.json test input.
    • ⛔ No production code: packages/adapters/hono/src/index.ts (the catch-all's { request: c.req.raw }, :739) is the line under test, not an edit. No packages/spec, no content/docs.
      Container & model: S, mode:subagent, model: default (opus). dispatch-gates --tier over the path gives no path-derived mandate.
      Clause-②: no
    • Test only: no accepted input, export or published shape changes. No changeset (skip-changeset).
      Responsibility: platform code: the hono catch-all's hand-off of the raw Request is the one line that carries #22141's /meta write preconditions to a composed host, and no CI test holds it | none known: #22141's pins drive dispatch() directly, because runtime cannot depend on @objectstack/hono | any composed host behind createHonoApp: if the hand-off regressed, every If-Match and ?mode=draft on PUT /meta would be dropped again with nothing in CI going red
      Thread-read: 6056475843
      Serial constraints cleared: read 2026-10-08T18:20Z:
    • Open PRs (14, each file list read by name against the merge base): none touches packages/qa/http-conformance/src, packages/adapters/hono/src/index.ts, scripts/cross-package-test-inputs.mjs or turbo.json. The release PR chore: version packages #21988 touches only packages/qa/http-conformance/CHANGELOG.md and package.json.
    • In-flight claims in domain:cli: [finding] cli(migrate meta): on a composeStacks preserve project the authored-source load is refused with STACK_PROVENANCE_MISSING ("not built by defineStack") although every input is wrapped #22289 (PR fix(cli): os migrate meta runs on a composeStacks project and migrates its package bodies #22326, accepted, landing) holds packages/cli files only.

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T18:20Z

  3. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22221,
    "status": "done",
    "branch": "claude/issue-22221-hono-meta-write-conformance",
    "pr": "#22341",
    "head": "e66efff753faaaf12f59c6dc43e59edb86d06944",
    "session": "session_01RWZbGvPFcRKvUqASZtunCU",
    "premise_still_valid": true,
    "summary": "Added one test file, packages/qa/http-conformance/src/hono-meta-save-preconditions.conformance.test.ts (a new file beside the read-side twin, so each file stays about one door; no production code). It sends four PUT /meta rows through the real createHonoApp (app.request) over a real ObjectStackProtocolImplementation (ObjectQLPlugin's built-in assembly on in-memory SQLite WASM, both already devDependencies): a stale If-Match gives 409 METADATA_CONFLICT with the active row unchanged; If-None-Match: * over an existing row gives 409 with the row unchanged; ?mode=draft leaves the active row and the draft reads back through GET ?state=draft; and the unguarded control writes the active row. Each row reads sys_metadata after the request. H4 is partly falsified: passing {} at :739 reddens only the two header rows, because mode rides the catch-all's queryParams argument, not context.request, so the draft row got its own ablation of that argument; the control stayed green in every leg. Premise re-measured: at base, none of the 8 test files that import createHonoApp sends If-Match, If-None-Match or mode=draft (grep exit 1; control grep hits the new file 12 times), and the 5 under packages/adapters/hono run against a runtime stub.",
    "tests": "At e66efff, all through os-verify-lock.sh. Build: pnpm --workspace-concurrency=2 --filter '@objectstack/http-conformance^...' build, VERDICT command-exit 0; runtime dist carries metaSaveRequestOptions({ headers: _context.request?.headers, query }) (grep). Tests: pnpm --filter @objectstack/http-conformance test, 'Test Files 9 passed (9)', 'Tests 106 passed (106)'. New file alone: 'Tests 4 passed (4)'. Typecheck: pnpm --filter @objectstack/http-conformance typecheck, exit 0, 'check:test-typecheck: OK ... 3 file(s) / 27 error(s) / 10 pinned signature(s) held', ledger unchanged; tsc --listFiles -p tsconfig.test.json puts the new file in the program (9 of 9 test files). Tier: Test Core, per PR (ci.yml Test Core (N/6) runs pnpm turbo run test over the affected set; this package's test is a bare vitest run with no project split). Ablations, never committed, subject packages/adapters/hono/src/index.ts (HEAD blob 8c32e89e8fc2, loaded as SOURCE through vitest.config.ts's anchored @objectstack/hono alias, so no dist leg; hono dist untouched while each leg went red), each through node scripts/ablation-replace.mjs in WRAP mode under the lock, directions written down before running: leg A '{ request: c.req.raw }' to '{}' (anchor x1 to x0, blob 3900c478d42e): control green, stale If-Match RED (200 success:true for 409), If-None-Match RED (200 for 409), draft green, 'Tests 2 failed | 2 passed (4)'. Leg A' to a headerless 'new Request(c.req.raw.url, { method: c.req.method })' (blob effd7d0f0b20): same, 2 failed | 2 passed. Leg B 'queryParams' to '{}' in the same call (blob b64245cd76d5): control, If-Match and If-None-Match green, draft RED (receipt state 'active' for 'draft'), 'Tests 1 failed | 3 passed (4)'. Every restore: 'ok restored: blob == HEAD (8c32e89e8fc2) and git diff HEAD is empty', re-checked by git hash-object and git status --porcelain (clean).",
    "gates": "The order's 71 commands, each exit recorded before any pipe as 'COMMAND :: exit N', at e66efff: 70 exit 0. node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands re-derived at head gives 53 (1 path, 206 changed lines), a subset of the order's 71; --ran: '✓ dispatch-gates --ran: 53 derived famil(ies) accounted for — 52 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)', 0 unrun, plus 18 recorded beyond the derivation (all exit 0). NOT MEASURED: pnpm check:dual-build-cjs-loads, reason: exit 3 PREREQUISITE NOT MET (34 packages unbuilt in this worktree); this diff adds one test file to a private package with no build script, so it emits nothing that gate reads; CI runs it in full. H5: pnpm check:cross-package-test-inputs exit 0, 'OK: 30 package(s) read outside themselves, all declared ... every one declared', so no row and no turbo.json input. pnpm lint (eslint . --no-inline-config, whole repo) at e66efff: exit 0, no findings. CI at 2026-10-08T18:55Z (one read, not polled): 31 check-runs, 14 success, 3 skipped, 13 in_progress, 1 failure = Check Changeset, annotation 'This PR adds no changeset ... apply the skip-changeset label', i.e. the label write the classifier refused (see deviations). Upstream: origin/main is 1 commit past base (e36ee53, 10 storage/organizations/dogfood files, none in this suite's closure), not merged.",
    "line_budget": "206 changed lines (+206 / -0, 1 file) vs the 5000 human-merge threshold: under. No governed surface touched.",
    "files_changed": [
    "packages/qa/http-conformance/src/hono-meta-save-preconditions.conformance.test.ts"
    ],
    "deviations": [
    "PR assignee NOT written: 'node scripts/pm/label-write.mjs --repo objectstack-ai/objectstack --issue 22341 --assign os-warren' was refused by this session's auto-mode permission classifier ('[External System Writes]') before any request was made. Not retried by any other route. The seat sets the assignee os-warren on PR #22341.",
    "skip-changeset label NOT written: 'node scripts/pm/label-write.mjs --repo objectstack-ai/objectstack --issue 22341 --add skip-changeset' was refused the same way, before any request. Not retried. Check Changeset is red at e66efff for exactly that reason; the seat applies skip-changeset (criterion holds: @objectstack/http-conformance is private: true and the diff is one test file).",
    "The harness's attribution reminder asked for a commit trailer naming a model and a different PR footer. Per the order and AGENTS.md, the commit carries the model-free pair (Claude-Session, Co-Authored-By: Claude) and the PR body ends with the session-URL footer.",
    "The report carries gates, line_budget, files_changed and deviations beyond os-dev.md's template, because the order says the seat reads them.",
    "Cleanup (rm -rf the worktree's node_modules, then git worktree remove) is done after this comment is posted, because the comment is posted with the worktree's own scripts/pm/post-stamped.mjs."
    ],
    "mcp_calls": "0",
    "api_writes": "2 — (1) pr_create through the fleet relay: POST /repos/objectstack-ai/objectstack/dispatches (HTTP 204, request fw-20261008T185225Z-a0839c), executed by run 37827634465 as POST /repos/objectstack-ai/objectstack/pulls (draft) as objectstack-fleet[bot], giving #22341; read back 9669 bytes sent, 9669 stored, identical; (2) this os-dev-report comment, POST /repos//issues/22221/comments through scripts/pm/post-stamped.mjs. Two label-write.mjs invocations were refused by the local classifier before any request (not counted as writes; see deviations). Two git pushes of the branch are not REST writes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · boot noise, not a finding: each boot prints two [sql-driver] DATABASE_ERROR lines (no such table: sys_setting, _objectstack_sequences) from kernel:ready platform-migration probes against tables this minimal composition does not provision; they print before the first request and no row depends on them · noted in PR #22341's Acceptance notes, not filed",
    "carrier: the domain:cli seat (PR #22206's open question H6) · the catch-all's 409 still carries no currentVersion as data; these rows assert only status, success and error.code, so they neither pin nor block any answer · noted, not filed"
    ]
    }

  4. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #22341 at e66efff7, pending two PR writes and CI

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · read on GitHub 2026-10-08T18:59Z

    Checked on GitHub and in the diff, not from the report:

    • Shape:
      • draft, base main;
      • line 1 is Fixes #22221, line 2 is Clause-②: no;
      • 1 file, +206 / −0: packages/qa/http-conformance/src/hono-meta-save-preconditions.conformance.test.ts, beside the read-side twin;
      • no production code.
    • The rig composes everything the hosted path uses, for real:
      • LiteKernel with ObjectQLPlugin's built-in assembly, which registers ObjectStackProtocolImplementation and the sys_metadata* objects;
      • over an in-memory SQLite (WASM) driver;
      • with the real createHonoApp on top.
      • The one stubbed seam is the dispatcher's identity step, as in the twin: one author holding manage_metadata.
      • The file header says why this lives in packages/qa and not in adapters/hono (its runtime stub) or runtime (it cannot depend on hono).
    • The four rows go through app.request(...), and each reads sys_metadata after the request:
      • a stale If-Match gives 409 / METADATA_CONFLICT, the active row stays v2, and the current token still saves;
      • If-None-Match: * over an existing row gives 409, and the row stays first;
      • ?mode=draft returns a receipt in state draft. The active row is unchanged. The draft reads back through GET ?state=draft, and the plain read still answers the active row;
      • the control: an unguarded save writes the active row, and the last writer wins.
    • H4 is partly falsified, and the dev's correction holds. The two headers ride { request: c.req.raw }, but ?mode rides the catch-all's queryParams argument (hono/src/index.ts:739).
      • So the dev ablated each hand-off separately. {} and a headerless rebuilt Request each turned the two header rows red. queryParams → {} turned the draft row red. The control stayed green in every leg.
      • Each leg was restored to a blob equal to HEAD.
    • H5: check:cross-package-test-inputs is OK with no new row. The imports are the package's existing dev dependencies.
    • Tier: Test Core, per PR. @objectstack/http-conformance runs a bare vitest run, and the dev reports 9 files and 106 tests passing.
    • Clause-②: no stands: a test-only change in a private package. It needs no changeset.

    Owed before landing:

    Not filed:

  5. objectstack-fleet commented on Oct 8, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22341 → 6a53564b9f, a single-parent queue squash

    domain:cli seat · session_01RWZbGvPFcRKvUqASZtunCU · 2026-10-08T23:23Z

    • Landing shape:
      • 6a53564b9f has one parent.
      • It is an ancestor of origin/main; the pre-merge head e66efff7 is not.
      • It entered the merge queue 2026-10-08T23:02:41Z and merged 2026-10-08T23:22:44Z on that first entry.
      • Fixes #22221 closed this card as completed.
    • Content on origin/main: packages/qa/http-conformance/src/hono-meta-save-preconditions.conformance.test.ts (+206, test only), beside the read-side twin. It runs four rows through app.request(...) on the real createHonoApp over a LiteKernel with ObjectQLPlugin's own assembly and an in-memory SQLite driver, and reads sys_metadata after each:
      • a stale If-Match gives 409 / METADATA_CONFLICT and leaves the active row;
      • If-None-Match: * over an existing row gives 409;
      • ?mode=draft writes a draft and leaves the active row;
      • the control: an unguarded save writes, and the last writer wins.
    • Review of record:
      • ACCEPT 6066960748 at e66efff7. The dev's ablation of each hand-off (the two headers and queryParams) reddened exactly the rows it removed.
      • Clause-②: no, a test-only change in a private package; no contract review and no changeset were owed.
      • The skip-changeset label and the assignee os-warren were written by the seat through the relay, on the maintainer's authorization, after the dev's own label write was refused. Check Changeset then re-ran and was skipped, as the label provides.
      • CI on the head was green before arming (29 success, the rest skipped). check-governed-merges: not governed. check-expected-skips: OK. Arming re-ran git merge-tree against a fresh origin/main in the same step: clean.
    • Delivered: the hosted metadata save path's three preconditions (If-Match, If-None-Match: *, ?mode=draft) are pinned through the real Hono door, not only at the protocol layer.
    • Not filed (from the ACCEPT): the two [sql-driver] DATABASE_ERROR boot lines from this minimal composition's migration probes, which no row depends on; and the catch-all's 409 still carrying no currentVersion (PR fix(runtime): the @objectstack/hono catch-all's PUT /meta honours If-Match, If-None-Match and ?mode=draft #22206's H6).

    pm:dispatched removed.

  6. added a commit that references this issue on Oct 9, 2026
    6a53564
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsdomain:clipriority:p2Medium: important, M3tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions