Skip to content

QA run · release-18.3.0-w4-c2a (63/63) · 7fa9873f · 2026-11-02 · 21 PASS / 40 PARTIAL / 2 FAIL / 0 BLOCKED / 0 NOT-RUN #28929

Open

Description

@objectstack-fleet

domain:devx#1 · os-warren · session_01JQwxbWBtYWqaV8NhvUrShB

Filed by the dispatching PM seat session for the W4-C2a runner session_01JQwxbYA4iFU41N3PukeHhD, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).
Part of #27377 (wave 4, W4-C2a)

Selector release-18.3.0-w4-c2a: Tier 1 half A of the 18.3.0 release-candidate sweep, wave 4 — the 63 pinned, non-P0 items in access-security, ai, api-backend, approvals, attachments-storage, automation and cli, as listed by the wave-4 brief (computed from the ledger at the subject). Release-candidate rerun (SKILL §5 trigger 1). Every item has a verdict: 21 PASS / 40 PARTIAL / 2 FAIL / 0 BLOCKED / 0 NOT-RUN. No item is planned.

Coverage mode: this card ran the pins, not the live legs. The wave-4 brief scopes C2a to "build closure only; run each item's automated.ref in per-area vitest batches". So a clause whose oracle sits on a live or browser leg that no pin drives is skipped here, and a pin that stops below its clause's oracle layer scores that clause partial (RUNNER rule 6). Wave 3 (#27409) drove those live legs, so most PASS→PARTIAL deltas below are this coverage mode, not regressions. The two FAILs are real disagreements between a pin's measured answer and the clause text.

Environment fingerprint

  • Subject: framework 7fa9873f38f7a0158e3ce17338dcc0f446b113e3 (detached, never followed main or the Version PR chore: version packages #26517). ui/ is in the same tree; the console Vite dev server ran from it.
  • Build: npm_config_nodedir=/opt/node22 pnpm install --frozen-lockfile (30 s), then pnpm exec turbo run build --concurrency=2 under scripts/pm/os-verify-lock.sh: 118/118 tasks, 0 cached, 15m15s. check-dev-prereqs: 106 package artifacts present.
  • Node v22.23.4, pnpm 10.31.0, Playwright chromium from /opt/pw-browsers. 4 CPUs, ~15 GB.
  • Pins: one vitest invocation per package, files deduplicated across areas, --maxWorkers=1 (ui jsdom suites from the ui/ root at 2), JSON reporter per package; cli *.e2e.test.* in its own invocation under OS_TEST_TIERS=nightly. Two lanes in parallel (dogfood | every other package).
  • Live boot (for the two live Playwright pins and the off-clause probes): OS_PORT=41421 OS_STORAGE_LOCAL_ROOT=/tmp/w4c2a/e2e/uploads setsid pnpm -C examples/app-showcase exec objectstack dev --ui --seed-admin -p 41421 -d file:/tmp/w4c2a/e2e/data.db; console dev server DEV_PROXY_TARGET=http://localhost:41421 vite --port 41496 (proxy mode, VITE_SERVER_URL unset — see the probe section).
  • Scaffold replay (cli.scaffold-first-run): the scaffold-local job of .github/workflows/scaffold-e2e.yml replayed in /tmp/w4c2a/scaffold, server on 48080.
  • Seed: --seed-admin (admin@objectos.ai) and the showcase demo personas (phone.demo, password showcase123).
  • Times: 2026-11-02 03:35Z to 04:20Z.
  • Execution: one runner session ran every pin, spec and replay itself. Four scoring subagents (effort high) then mapped the captured test output to clauses per area, reading each pin's harness for its layer; their verdicts were checked against the evidence before this record was written (the two FAILs and one blocked set were re-derived by the runner, see below).

Scope: selector and the revision each verdict is valid for

  • access-security (17): record-access-explain r4, fls-mask-and-strip r8, public-form-withdrawal-layers r5, activation-write-operator-gate r12, platform-owner-email-anchor r13, me-permissions-aggregation-parity r4, record-view-read-audit r7, share-link-landing-page r6, anonymous-floor-v18-doors r5, meta-authoring-trail-and-audience-gates r4, security-catalog-activation-and-clone-doors r3, security-catalog-one-holder-and-boot-report r4, grant-table-write-contract r8, parent-and-organization-write-guards r7, deployment-tables-platform-only r4, share-link-combined-gates r5, org-admin-assignment-boundary r2
  • ai (5): mcp-http-surface r8, mcp-validate-expression r6, skill-instructions-mcp-prompts r4, mcp-oauth-private-host-transport r6, mcp-coded-refusals-and-runtime-exposure r4
  • api-backend (11): bulk-write-contract r6, declarative-endpoint-execution r6, action-activation-door-contract r7, rest-crud-config-contract r6, rest-batch-config-contract r6, rest-metadata-config-contract r8, rest-route-generation-tombstones r4, second-object-exposure-and-internal-fields r3, data-request-shape-and-query-arity r4, meta-read-doors-v18 r4, error-sentences-and-unique-violation-wire-code r5
  • approvals (4): email-action-token-door r10, status-mirror-field r6, request-page-reply-and-reader-visibility r5, act-door-and-admin-rescue-slate r5
  • attachments-storage (10): presigned-upload-roundtrip r3, download-authz-both-sides r10, read-inherits-parent-rls r9, attach-requires-parent-edit r9, sys-file-status-pipeline r5, orphan-tombstone-reap r4, upload-session-abort r8, inline-grid-receipt-cells r5, upload-limits-scope-and-ownership r4, chunked-upload-integrity r8
  • automation (10): trigger-type-matrix r10, screen-flow-roundtrip r7, durable-suspend-restart r4, paused-run-trigger-record-masked r5, setup-packaged-automation-board r10, flow-registration-verdict-on-read r2, flow-authoring-refusals-v18 r5, flow-run-semantics-v18 r3, inbound-hook-timestamped-signature r2, scheduled-work-opt-in r2
  • cli (6): scaffold-first-run r7, dev-automigrate-policy r8, migrate-meta-write-stored-and-all r3, meta-package-flags-and-explain r3, validate-v18-authoring-verdicts r2, verify-derived-proof-families r3

Tier 1 pins

236 distinct test files across 32 packages: 6749 passed, 0 failed, 1 skipped. Every file a ref names (after resolving bare basenames to their package path) exists at the subject and collected tests, except the three automation.setup-packaged-automation-board files retired by #28785 (below). The one skip is by design: attachments-permission-matrix case (g), cross-tenant isolation, on a single-organization boot.

area packages file runs passed skipped
access-security 19 76 1991 0
ai 6 16 283 0
api-backend 7 46 1582 0
approvals 5 18 573 0
attachments-storage 6 27 714 1
automation 11 29 1047 0
cli 7 28 682 0

(Per-area rows count a file shared by two areas twice; the 236 / 6749 total counts it once.)

Live Playwright pins (from ui/, playwright.live.config.ts, against the boot above):

  • ui/e2e/live/screen-flow.spec.ts: 1 passed, twice (23.8 s, 15.8 s), with the dev server in proxy mode. Four earlier runs with VITE_SERVER_URL also set failed; that was the topology, not the product (probe section).
  • ui/e2e/live/grid-file-upload.spec.ts: 1 passed, twice (17.2 s, 15.1 s).

cli.scaffold-first-run (automated.kind: ci, ref .github/workflows/scaffold-e2e.yml): the scheduled Scaffold E2E run at the subject (actions run 41383199590, success) is the registry canary only — it scaffolds the published create-objectstack@latest — so it is not subject evidence. The repo-dist job was replayed locally instead: scaffold from the subject's create-objectstack exit 0; npm install exit 0 (registry @objectstack/* 18.2.0, no fallback branch); validate 0; build 0; npm test 0; os start --artifact healthy on the 4th probe, /api/v1/health 200 and /api/v1/ready 200; skills probe set-equal to the curated skills/ (11 names) and the repo-root listing "Found 11 skills" with no dogfood-verification. Not replayed: the pinned-shape (full install) step and the docker steps. Because the project installs the published 18.2.0 runtime, A0–A3 score partial: they judged the subject's scaffolder over the published runtime, not the subject's runtime.

Per RUNNER rule 6 each clause row names the layer its pin drives. HTTP-in-process (a booted showcase or stack answering through Hono app.request) counts as the HTTP layer, as in wave 3.

Reproduction rules

1. api-backend.rest-metadata-config-contract · A2 · FAIL (product defect)

The metadata.endpoints.item switch now unmounts thirteen routes; its published describe() and the clause enumerate twelve. The thirteenth is GET /api/v1/meta/app/:appId/bundle, added by #28287 (8441a01, part of #27627).

  1. At the subject, cd packages/rest && pnpm exec vitest run src/rest-config-mount-table.pin.test.ts → passes. Its metadata.endpoints.item row (the "[Seam: one request opens a record — a record-page payload (record + related counts and first rows + field access + lock) and an app-scoped metadata bundle, so a record open is 2–3 requests instead of 23–45 serialized in three stages #27627] Thirteen" comment) asserts the per-switch route-table diff against the all-true baseline is exactly 13 routes, including GET {prefix}/app/:appId/bundle. The pin builds a real RestServer route table.
  2. Read packages/spec/src/api/rest-server.zod.ts, metadata.endpoints.item: its describe() lists GET/PUT/DELETE /meta/:type/:name, /references, /layers, the six history routes and GET /meta/book/:name/tree — twelve — and no bundle route. The same file's header says the describe() strings are exhaustive and a moved radius moves the table and the declaration in the same PR.
  • Expected (clause A2 verify): the measured diff equals the declared radius; "a diff that disagrees with them is a defect in the code or in the declaration".
  • Actual: measured 13, declared 12. The code is consistent with the switch's meaning (the bundle is the item read's own answer, per the pin comment), so the defect is in the declaration. The clause's "twelve mounts" is stale the same way (accuracy line for [sweep] v18.3.0 release test sweep #27377).
  • Reproduced twice at the subject: the pin lane run and a second standalone run of the file, both passing with the 13-route assertion.

2. api-backend.error-sentences-and-unique-violation-wire-code · A1 · FAIL (stale spec)

The clause pins the pre-ruling shape of an undeclared hook refusal.

  1. cd packages/qa/dogfood && pnpm exec vitest run test/error-sentences-live.dogfood.test.ts → passes. Its acceptance[1] cases drive POST /data/errsent_budget and /createMany (in-process HTTP, scratch app with a sandboxed refusing beforeInsert hook) and assert 400, the hook sentence verbatim, nothing written, and body.code === 'HOOK_ABORTED' ("the hook declared no code, so the /data door answers the ruled HOOK_ABORTED").
  2. cd packages/rest && pnpm exec vitest run src/rest-write-route-hook-refusal-sentence.ledger.test.ts → passes; the nested-envelope rows (sharing rules, suggested bindings, approvals) answer HOOK_ABORTED_400 = { status: 400, code: 'HOOK_ABORTED' }, "the floor's VALIDATION_ERROR before".

Derived item verdicts

  • PASS (21): access-security.public-form-withdrawal-layers, access-security.activation-write-operator-gate, access-security.platform-owner-email-anchor, access-security.record-view-read-audit, access-security.anonymous-floor-v18-doors, access-security.meta-authoring-trail-and-audience-gates, access-security.security-catalog-activation-and-clone-doors, access-security.security-catalog-one-holder-and-boot-report, access-security.parent-and-organization-write-guards, access-security.deployment-tables-platform-only, access-security.share-link-combined-gates, access-security.org-admin-assignment-boundary, api-backend.declarative-endpoint-execution, api-backend.rest-crud-config-contract, api-backend.rest-batch-config-contract, api-backend.rest-route-generation-tombstones, api-backend.second-object-exposure-and-internal-fields, api-backend.data-request-shape-and-query-arity, api-backend.meta-read-doors-v18, attachments-storage.chunked-upload-integrity, cli.meta-package-flags-and-explain.
  • FAIL (2): api-backend.rest-metadata-config-contract (A2, product defect); api-backend.error-sentences-and-unique-violation-wire-code (A1, stale spec).
  • PARTIAL (40), each with what kept it below PASS:
    • access-security.record-access-explain: A1 pass-below-oracle (engine, no HTTP door); A0, A2, A3, A4 skipped (live/browser legs)
    • access-security.fls-mask-and-strip: A4 pass-below-oracle (scratch set, budget only, no browser leg); A3 skipped (browser)
    • access-security.me-permissions-aggregation-parity: A2/A3/A5/A6 pass-below-oracle (unit or member-half only); A0/A1/A4 skipped (manual live parity)
    • access-security.share-link-landing-page: A0 pass-below-oracle (ui-unit fold only); A1-A4 skipped (browser legs)
    • access-security.grant-table-write-contract: A4 pass-below-oracle (engine pin; walled HTTP door not driven)
    • ai.mcp-http-surface: A0,A1,A3,A4,A5 rest on dispatcher units / fake-service sockets or partial assertions; served-door legs not driven (pins-only card)
    • ai.mcp-validate-expression: A0,A1,A3 plugin-unit only (served MCP door not driven); A2 live-only
    • ai.skill-instructions-mcp-prompts: A0–A3 network oracles carried by a plugin unit only; A3 non-projected half and N1 unpinned
    • ai.mcp-oauth-private-host-transport: every clause is a booted server's discovery answer or boot log; both pins are plugin units (ref says neither scores a clause)
    • ai.mcp-coded-refusals-and-runtime-exposure: A1–A3 api oracles reached only at plugin-unit / engine (stdio); HTTP door legs not driven
    • api-backend.bulk-write-contract: A0/A3 below oracle; A1,A2,A4,A5 live-only
    • api-backend.action-activation-door-contract: A4: metadata-plane 503 arm has no stock door and no pin (knownGaps)
    • approvals.email-action-token-door: A0,A1,A3,A4 pinned in part (each verify names its unpinned half); A5 blocked(fixture)
    • approvals.status-mirror-field: A0,A1 below api (unit/engine only); A2 SLA half unit-only; A3,A4 live legs not driven
    • approvals.request-page-reply-and-reader-visibility: A1-A3 pinned below the api door only; A4 browser leg not driven
    • approvals.act-door-and-admin-rescue-slate: A1 self-hosted PUT 404 arm (os dev boot) is a live leg no pin holds
    • attachments-storage.presigned-upload-roundtrip: A0,A2,A4 pinned in half; A1,A3 hand-driven legs not driven
    • attachments-storage.download-authz-both-sides: A2 uploader-bypass + bytes legs unpinned; A4 component-only (browser leg not driven)
    • attachments-storage.read-inherits-parent-rls: A3 probe half pinned only at engine/unit (knownGaps[2])
    • attachments-storage.attach-requires-parent-edit: A2 uploader leg unpinned; A5 engine-only (REST PATCH not driven)
    • attachments-storage.sys-file-status-pipeline: A0 pending read unpinned; A1,A2,A5 route-handler/unit only
    • attachments-storage.orphan-tombstone-reap: A1 failure leg unit-only
    • attachments-storage.upload-session-abort: A0 live leg not driven; A3 warn text unasserted; A4,A5 route-handler unit only
    • attachments-storage.inline-grid-receipt-cells: A2 upload trace and A3 sys_file stamp/batch-success unasserted by the pin
    • attachments-storage.upload-limits-scope-and-ownership: A1 no sys_file count; A2 route-handler only; A5 engine only
    • automation.trigger-type-matrix: A0-A3 skipped (live trigger runs); A4 network half only, run reads not pinned
    • automation.screen-flow-roundtrip: A1, A4, A6 skipped; A0, A3 network half only; A5 engine only (HTTP 400 missing)
    • automation.durable-suspend-restart: A2, A3 skipped; A0/A1/A4 generic fixture half only, A1 cold boot is in-process not a spawned server
    • automation.paused-run-trigger-record-masked: A0, A1 member persona not driven; A3 in-process cold boot
    • automation.setup-packaged-automation-board: item describes the retired Packaged automation page (feat(setup): retire Packaged automation's flows half; Packaged actions is its own Setup entry #28785); only component-layer actions analogues for A3/A4
    • automation.flow-registration-verdict-on-read: A1, A2 pinned at engine/protocol, HTTP door missing
    • automation.flow-authoring-refusals-v18: A1-A3 need CLI + boot legs
    • automation.flow-run-semantics-v18: A1 skipped (live read-back)
    • automation.inbound-hook-timestamped-signature: A1 below the booted door; A2 live only
    • automation.scheduled-work-opt-in: A1, A2 need served boots
    • cli.scaffold-first-run: runtime half measured on registry 18.2.0 not subject; scaffolder's own skills install and docker steps not replayed
    • cli.dev-automigrate-policy: A0-A3 below the boot-log/schema-dump oracle (driver or partial-scope CLI pins)
    • cli.migrate-meta-write-stored-and-all: A3 at formatter unit, A4 at library layer
    • cli.validate-v18-authoring-verdicts: A1, A2 need CLI legs
    • cli.verify-derived-proof-families: A1 skipped (showcase run)

Delta against wave 3 (#27409, at c4c515a)

Off-clause probes (RUNNER rule 8)

About 10 min on the live boot, after the pins had run. Doors: POST /security/explain, POST /actions/showcase_task/:action, POST /automation/:flow/trigger, /automation/:flow/runs/:id/resume and the run read, POST /storage/upload/presigned, GET /data/showcase_task with $top. Personas: admin, and the demo member phone.demo. Boundary classes: empty strings, unknown ids, an unknown operation, a negative and a non-numeric $top, a negative size, and a member resuming and reading the admin's suspended screen-flow run.

  • Every answer was a coded 4xx naming the problem (400 VALIDATION_FAILED / VALIDATION_ERROR / INVALID_REQUEST, 404 RECORD_NOT_FOUND / OBJECT_NOT_FOUND / RESOURCE_NOT_FOUND / RUN_NOT_FOUND, 403 PERMISSION_DENIED for the member's explain-of-another-user, resume and run read). No product defect found.
  • One environment finding: with VITE_SERVER_URL set to the API origin (as the dogfood-verification skill §2 prescribes for the HMR console), every action and flow click POSTs to that off-origin URL through createAuthenticatedFetch({ sameOriginOnly: true }) without the bearer, and answers 401 UNAUTHENTICATED; screen-flow.spec.ts failed 4/4 that way. That is ruled behaviour (objectui#5702, maintainer ruling 2026-08-22, app-shell CHANGELOG "split-host setups"), so it is not extracted; the skill's line is an accuracy finding for [sweep] v18.3.0 release test sweep #27377.

Time: environment prep vs testing

  • Environment prep: install 30 s + full build 15m15s (03:35Z–03:51Z), plus about 3 min of boots (showcase, Vite).
  • Testing: pin lanes 03:51Z–04:05Z (14 min wall; dogfood 53 files in 525 s), live specs and the scaffold replay about 6 min, probes about 10 min, clause scoring about 7 min wall (four scorers in parallel, ~24 agent-minutes).
  • Ratio about 1 to 2. Wall clock about 45 min to verdicts.

Per-clause verdicts

One row per acceptance clause, with the layer and one line of text evidence. partial = the pin passed below the clause's oracle layer; skipped = a live/browser leg outside this pins-only card. Each negative[] entry was checked under the clause it guards. The tables are in the comments below, one per area group.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-warren · session_01JQwxbWBtYWqaV8NhvUrShB

    Filed by the dispatching PM seat session for the W4-C2a runner session_01JQwxbYA4iFU41N3PukeHhD, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).

    Per-clause verdicts (1/4): access-security.

    access-security

    item · rev clause verdict layer · text evidence
    access-security.record-access-explain · r4 A0 skipped browser-live: live leg, out of this pins-only card: screenshot of the Explain access panel; no pin renders it
    access-security.record-access-explain · r4 A1 partial engine: showcase-permission-zoo 12 passed: 'explain() reports the vama_bypass layer with the auditor set as contributor' — explain() in-process, isSystem, object-level; POST /security/explain not driven
    access-security.record-access-explain · r4 A2 skipped HTTP-in-process (GET halves only): live leg, out of this pins-only card: zoo pins auditor GET 200 and plain-member GET non-200 (HTTP-in-process), but the plain-member explain verdict has no pin at any layer
    access-security.record-access-explain · r4 A3 skipped none: live leg, out of this pins-only card: no pin makes a deny-side (plain-member) explain call; N0 (wrong-persona) likewise unpinned
    access-security.record-access-explain · r4 A4 skipped browser-live: live leg, out of this pins-only card: panel-vs-API field compare needs the browser
    access-security.fls-mask-and-strip · r8 A0 pass HTTP-in-process: showcase-permission-zoo 12 passed: 'FLS: a contributor can edit a project but NOT its budget fields' — name PATCH ‹300 and system re-read shows the new name
    access-security.fls-mask-and-strip · r8 A1 pass HTTP-in-process: same case: budget PATCH status >=300 and system re-read budget === pre-write value (value oracle)
    access-security.fls-mask-and-strip · r8 A2 pass HTTP-in-process: zoo 'FLS: the admin's budget write on the same project succeeds and persists' — admin PATCH ‹300, re-read equals raised value, restored
    access-security.fls-mask-and-strip · r8 A3 skipped browser-live: live leg, out of this pins-only card: contributor edit-form disabled state of budget/spent; no pin drives the console. N0 holds at API (A1)
    access-security.fls-mask-and-strip · r8 A4 partial HTTP-in-process: showcase-fls-read-mask-strip 8 passed: key ABSENT by id/list/select for a SCRATCH readable:false set on 'budget' only; stock showcase_client_liaison, spent/budget_remaining and the UI render are not pinned by the ref
    access-security.public-form-withdrawal-layers · r5 A0 pass HTTP-in-process: showcase-public-form-withdrawal-layers 4 passed: 'withdrawn by an admin WITH an active organization: the save is environment-wide, and it closes the form' + no-org read case; N0/N1 held
    access-security.public-form-withdrawal-layers · r5 A1 pass HTTP-in-process: same file: 'open environment-wide (control): both doors accept and the row lands in the organization'
    access-security.public-form-withdrawal-layers · r5 A2 pass plugin-unit: rest public-form-withdrawal 27 passed (RestServer over mocked protocol) + metadata-core anonymous-form-intake 47 passed: 'only an explicit false withdraws…', 'not a withdrawal…' (oracle test layer)
    access-security.public-form-withdrawal-layers · r5 A3 pass plugin-unit: public-form-withdrawal kill-switch describe + protocol.org-scoped-write-refused 309 passed: 'the doors serve no copy once one package withdraws the name' both registry orders
    access-security.public-form-withdrawal-layers · r5 A4 pass plugin-unit: anonymous-form-intake: 'a schema-parsed false that keeps the link IS a withdrawal' + protocol block (a) cases passed
    access-security.public-form-withdrawal-layers · r5 A5 pass plugin-unit: protocol block (c): 'the package-less copy serves each package's slot…' and '…a package's own copy serves that package's slot' on both kernels, passed
    access-security.activation-write-operator-gate · r12 A0 pass HTTP-in-process: activation-write-operator-gate-single 11 passed: 'the flow door: a plain member is refused 403 PERMISSION_DENIED with that door's own sentence' (tier, not §5; N0 held)
    access-security.activation-write-operator-gate · r12 A1 pass HTTP-in-process: same file: 'the action door: a plain member is refused 403 PERMISSION_DENIED with that door's own sentence'; N2 'the two doors speak distinct sentences'
    access-security.activation-write-operator-gate · r12 A2 pass HTTP-in-process: same file: INVALID body still 403 at both doors; 'acceptance[2]: the refusals wrote no ledger row for either artifact'
    access-security.activation-write-operator-gate · r12 A3 pass HTTP-in-process: same file: scratch-set member holds manage_metadata, not platform_admin (server-side); both doors admit, one row each with no organization_id key; N1 admin 200 both doors
    access-security.activation-write-operator-gate · r12 A4 pass plugin-unit: automation-activation-posture-gate 19 + action-activation-posture-gate 29 passed: group/isolated refuse tenant org admin, no write, posture named, operator allowed; walled live leg not driven
    access-security.activation-write-operator-gate · r12 A5 pass plugin-unit: same unit files: 'ALLOWS engine self-invocation' (isSystem) per posture, passed; live restart re-hydration line not read
    access-security.platform-owner-email-anchor · r13 A0 pass HTTP-in-process: platform-owner-email-anchor 6 passed: 'acceptance[0]: unset — M is refused, the admin stands on the grant anchor' (N2 admin 200 beside)
    access-security.platform-owner-email-anchor · r13 A1 pass HTTP-in-process: same file: 'the variable names M while M is UNVERIFIED — M is refused exactly as at baseline'
    access-security.platform-owner-email-anchor · r13 A2 pass HTTP-in-process: same file: 'the variable names an address no row holds — nothing changes for anyone'
    access-security.platform-owner-email-anchor · r13 A3 pass HTTP-in-process: same file (captured process log): 'a malformed list refuses the WHOLE variable, loudly once — the well-formed, VERIFIED sibling confers nothing'
    access-security.platform-owner-email-anchor · r13 A4 pass engine: resolve-authz-context.platform-admin-config 37 passed: DECLARED capability set, id-shaped predicate, case-insensitive cases; dogfood verified live leg passed; N1 stored-row pin passed
    access-security.platform-owner-email-anchor · r13 A5 pass engine: same file L5 + ADR-0131 D5 describes passed; platform-admin.test 25 'deprecation pointer is retired'; admin-standing-surface 10; N0 dogfood non-table input case passed
    access-security.me-permissions-aggregation-parity · r4 A0 skipped none: live leg, out of this pins-only card: map-vs-live-PATCH parity cross-check is STILL MANUAL per ref; no pin
    access-security.me-permissions-aggregation-parity · r4 A1 skipped none: live leg, out of this pins-only card: fields-map vs live budget refusal cross-check unpinned
    access-security.me-permissions-aggregation-parity · r4 A2 partial HTTP-in-process: me-apps-and-everyone-baseline 6 passed: member sees showcase, 'requiredPermissions still gates: the member does not see capability-gated apps', tabPermissions hidden drop; admin half unpinned
    access-security.me-permissions-aggregation-parity · r4 A3 partial plugin-unit: hono-current-user-endpoints 8 passed: bare Hono, no auth gate, toEqual {authenticated:false}/{apps:[]}; dogfood anon /me/apps asserts body only, never status — 401-floor regression unobservable here
    access-security.me-permissions-aggregation-parity · r4 A4 skipped none: live leg, out of this pins-only card: ?userId= self-scoping probe has no pin
    access-security.me-permissions-aggregation-parity · r4 A5 partial plugin-unit: current-user-endpoints-localization 18 passed: 'with nothing configured: the time-zone floor answers, and currency… stays null', 'answers the tenant's configured currency and time zone' (unit, not live stack)
    access-security.me-permissions-aggregation-parity · r4 A6 partial plugin-unit: get-effective-object-permissions 64 passed (plain-wildcard parity table over fixture schemas); W's live PATCH/GET cross-check unpinned
    access-security.record-view-read-audit · r7 A0 pass HTTP-in-process: record-view-read-audit 7 passed: stock 'boot log carries INFO lines… and no install line' + 'member's detail read answers 200 and, past the flush window, lands no read row'
    access-security.record-view-read-audit · r7 A1 pass HTTP-in-process: same file: install line names exactly the surviving set without sys_job; one row per detail read; 'a detail read of an object OFF the list lands no row'
    access-security.record-view-read-audit · r7 A2 pass HTTP-in-process: same file: 'one detail read lands one row recording who, which and when — and no values'
    access-security.record-view-read-audit · r7 A3 pass HTTP-in-process: same file: 'a LIST read of the audited object lands no row'
    access-security.record-view-read-audit · r7 A4 pass HTTP-in-process: same file (captured boot log): 'sys_job draws the exclusion warning, by name' + install set omits it
    access-security.record-view-read-audit · r7 A5 pass plugin-unit: read-audit 33 passed: 'a SYSTEM-elevated read produces no row', 'a read with NO principal produces no row' (N1); audit-plugin 21 passed
    access-security.share-link-landing-page · r6 A0 partial ui-unit: shared-record-shape 12 passed: normalizeResolvedShare folds redactFields→redactedFields on both bodies (#3983 pin); server-side strip, DOM render and notice unpinned (browser-live/network missing)
    access-security.share-link-landing-page · r6 A1 skipped browser-live: live leg, out of this pins-only card: password-gate round trips and record-free 401 bodies; unit 'reads each 401 code as its gate' covers client mapping only
    access-security.share-link-landing-page · r6 A2 skipped browser-live: live leg, out of this pins-only card: revoked/expired/garbage designed states need screenshots
    access-security.share-link-landing-page · r6 A3 skipped browser-live: live leg, out of this pins-only card: SIGN_IN_REQUIRED render; SharedRecordPage-11649.test.tsx exists but is not in the ref and was not run
    access-security.share-link-landing-page · r6 A4 skipped browser-live: live leg, out of this pins-only card: standalone layout outside the shell
    access-security.anonymous-floor-v18-doors · r5 A0 pass test: all 8 ref files ≥1 test, 0 failed: anonymous-floor-v18-doors 13, showcase-anonymous-deny-surfaces 75, anonymous-door-sweep 20, rest-api-description 9, docs-viewer-retired 6, i18n 52, settings 30, submit-answer 10
    access-security.anonymous-floor-v18-doors · r5 A1 pass HTTP-in-process: anonymous-floor-v18-doors: anonymous GET notifications/keys/share-links/openapi.json/i18n/locales/settings/branding each 401 unauthenticated code; admin served on 5 (keys GET 405 by design); sweep N0 held
    access-security.anonymous-floor-v18-doors · r5 A2 pass HTTP-in-process: showcase-anonymous-deny-surfaces: '[#25104] the retired viewer page is routed NOWHERE — the host's ordinary 404 for everyone, not a 401'
    access-security.anonymous-floor-v18-doors · r5 A3 pass HTTP-in-process: anonymous-floor-v18-doors: 'a bogus share-link token answers the token face's own refusal, never the floor's 401'
    access-security.anonymous-floor-v18-doors · r5 A4 pass HTTP-in-process: anonymous-floor-v18-doors: 'an anonymous submit forging owner_id and status answers 201 with exactly { id }' (forged values not stored)
    access-security.meta-authoring-trail-and-audience-gates · r4 A0 pass test: 4 ref files ≥1, 0 failed: meta-view-audience-alternate-doors 8, wall-authoring-trail-doors 31, meta-history-diff-authoring-door 20, meta-view-dashboard-audience-gate 19
    access-security.meta-authoring-trail-and-audience-gates · r4 A1 pass HTTP-in-process: wall-authoring-trail-doors single describe: history/audit/diff/commits 'a setup.access-only holder is refused here too' (403 FORBIDDEN / PERMISSION_DENIED on commits)
    access-security.meta-authoring-trail-and-audience-gates · r4 A2 pass HTTP-in-process: meta-view-audience-alternate-doors: absent from member list; by name,/published,/layers,?state=draft 403 PERMISSION_DENIED; /history FORBIDDEN first vs studio.access PERMISSION_DENIED; admin reads all; N0 ETag never 304
    access-security.security-catalog-activation-and-clone-doors · r3 A0 pass test: 4 ref files ≥1, 0 failed: catalog-activation-door.dogfood 10, permission-set-clone-door.dogfood 11, runtime catalog-activation-door 71, permission-set-clone 35
    access-security.security-catalog-activation-and-clone-doors · r3 A1 pass HTTP-in-process: catalog-activation-door.dogfood: 'a declared position switches off: 200, one deployment-level row' + 'the resolver… stops granting… and grants again once it is back on'
    access-security.security-catalog-activation-and-clone-doors · r3 A2 pass HTTP-in-process: same file: everyone/guest 'refused 400 and nothing is written'; 'a name nobody declares is 404 and writes nothing'
    access-security.security-catalog-activation-and-clone-doors · r3 A3 pass HTTP-in-process: permission-set-clone-door.dogfood: clone 200 without dropped keys (isDefault too); taken/own name 409; unknown 404; bad name 400; closed body 400 VALIDATION_FAILED; 403 w/o manage_metadata; 401 anonymous
    access-security.security-catalog-one-holder-and-boot-report · r4 A0 pass test: 8 ref files ≥1, 0 failed: one-holder-http 4, cold-boot-environment-holder 4, standalone 6, cli overlays 6, catalog-reference-report 15, binding 19, registration 4, collision 18
    access-security.security-catalog-one-holder-and-boot-report · r4 A1 pass HTTP-in-process: security-catalog-one-holder-http: 'install-local of a package redeclaring a showcase permission set is 422 PLUGIN_REGISTER_FAILED naming the name and its holder; nothing is installed'
    access-security.security-catalog-one-holder-and-boot-report · r4 A2 pass HTTP-in-process: same file: 'a permission-set save whose body packageId names another package is 400 VALIDATION_ERROR at packageId'
    access-security.security-catalog-one-holder-and-boot-report · r4 A3 pass CLI-in-process: security-catalog-overlays.integration 6 passed (oclif in-process): preview exit 1 with rows, --apply --yes exit 0, --json listed/deleted/rows
    access-security.security-catalog-one-holder-and-boot-report · r4 A4 pass HTTP-in-process: one-holder-http (captured boot output): 'a clean boot logs the one info line'; 'a reboot holding 51 grants… logs the [security] error line, its list capped at 50'
    access-security.grant-table-write-contract · r8 A0 pass test: 6 ref files ≥1, 0 failed: grant-table-write-contract 3, assignment-window 7, grant-permission-set-name 16, window-order 11, granted-by-writer-provenance 20, grant-holder-membership-refusal 21
    access-security.grant-table-write-contract · r8 A1 pass HTTP-in-process: grant-table-write-contract: permission_set_id '400 INVALID_FIELD, and nothing is stored'; 'a second identical grant is 409 UNIQUE_VIOLATION, and one row stands'
    access-security.grant-table-write-contract · r8 A2 pass HTTP-in-process: permission-set-assignment-window: 'the door refuses a window whose end is not after its start, and the boot stores none' (400 VALIDATION_FAILED rule_violation, no unevaluable; valid window 201)
    access-security.grant-table-write-contract · r8 A3 pass HTTP-in-process: grant-table-write-contract: 'a grant naming ANOTHER user as granted_by stores the caller'
    access-security.grant-table-write-contract · r8 A4 partial engine: grant-holder-membership-refusal 21 passed (real ObjectQL+SQL driver); walled HTTP leg (400 VALIDATION_FAILED user_id reference_not_found at the door) not driven
    access-security.parent-and-organization-write-guards · r7 A0 pass test: 7 ref files ≥1, 0 failed: parent-org-write-guards 6, cbp-attachment-comment 10, cbp-explain 20, tenant-wall-org-removal 34, unreadable-header 30, predicate-related-header 22, cbp-chain-middle-master 9
    access-security.parent-and-organization-write-guards · r7 A1 pass HTTP-in-process: parent-and-organization-write-guards walled describe (bootShowcase multiTenant 'posture-only', isolated wall active asserted): PATCH {organization_id:null} 403 PERMISSION_DENIED, org kept; empty-org insert stamped
    access-security.parent-and-organization-write-guards · r7 A2 pass HTTP-in-process: same file: 'an unreadable and a nonexistent master answer the same 400 reference_not_found, field by field'; cbp detail one refusal byte-for-byte (N0 held)
    access-security.parent-and-organization-write-guards · r7 A3 pass HTTP-in-process: cbp-parent-attachment-comment-gates: attach 403 ATTACHMENT_PARENT_ACCESS, delete other's file 403 ATTACHMENT_DELETE_DENIED; cbp-explain-master-write: decidedBy 'sharing', not-writable, matches PATCH
    access-security.deployment-tables-platform-only · r4 A0 pass test: 4 ref files ≥1, 0 failed: deployment-tables-platform-only 15, deployment-level-no-tenant-column 31, sys-flow-dispatch.object 4, sys-presence.object 12
    access-security.deployment-tables-platform-only · r4 A1 pass HTTP-in-process: deployment-tables-platform-only: guard (org admin, no manage_platform_settings) then per table 'the org admin is refused 403 PERMISSION_DENIED; the platform admin reads 200' x7
    access-security.deployment-tables-platform-only · r4 A2 pass HTTP-in-process: same file: 'an organization_id filter is 400 INVALID_FIELD (the column does not exist)' x7
    access-security.share-link-combined-gates · r5 A0 pass test: 5 ref files ≥1, 0 failed: combined-gates.dogfood 4, share-link-eligibility 43, envelope.conformance 26, messages-audience 85, refusal-order 60
    access-security.share-link-combined-gates · r5 A1 pass HTTP-in-process: share-link-combined-gates: 'link A answers 401 SIGN_IN_REQUIRED for no, a wrong and the right password — byte-identical' (N0 held)
    access-security.share-link-combined-gates · r5 A2 pass HTTP-in-process: same file: 'link B answers one 404 INVALID_OR_EXPIRED body to every non-entitled variant — the unknown token's body'; control resolves 200
    access-security.share-link-combined-gates · r5 A3 pass HTTP-in-process: same file: '/messages is refused exactly where /resolve refuses, and open exactly where it passes' (404 NOT_FOUND / 400 UNSUPPORTED)
    access-security.org-admin-assignment-boundary · r2 A0 pass test: 3 ref files ≥1, 0 failed: org-admin-assignment-boundary.posture 60, delegated-admin-gate 137, rbac-objects 13
    access-security.org-admin-assignment-boundary · r2 A1 pass engine: posture file (real ObjectQL+SqlDriver+SecurityPlugin): orgAdmin and orgAdminNoBypass in/out-boundary insert+delete cells on both tables, single/group/isolated, passed
    access-security.org-admin-assignment-boundary · r2 A2 pass engine: same file: platform cells admitted and member cells refused, per posture, passed
    access-security.org-admin-assignment-boundary · r2 A3 pass engine: same file: 'the delegable-scope report offers the org admin its in-boundary po…' per posture, passed; N0/N1 cells pass; N2 non-admin_full_access sets only in delegated-admin-gate unit (no posture dimension)

    Derived: record-access-explain PARTIAL · fls-mask-and-strip PARTIAL · public-form-withdrawal-layers PASS · activation-write-operator-gate PASS · platform-owner-email-anchor PASS · me-permissions-aggregation-parity PARTIAL · record-view-read-audit PASS · share-link-landing-page PARTIAL · anonymous-floor-v18-doors PASS · meta-authoring-trail-and-audience-gates PASS · security-catalog-activation-and-clone-doors PASS · security-catalog-one-holder-and-boot-report PASS · grant-table-write-contract PARTIAL · parent-and-organization-write-guards PASS · deployment-tables-platform-only PASS · share-link-combined-gates PASS · org-admin-assignment-boundary PASS


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-warren · session_01JQwxbWBtYWqaV8NhvUrShB

    Filed by the dispatching PM seat session for the W4-C2a runner session_01JQwxbYA4iFU41N3PukeHhD, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).

    Per-clause verdicts (2/4): ai, api-backend.

    ai

    item · rev clause verdict layer · text evidence
    ai.mcp-http-surface · r8 A0 partial plugin-unit + HTTP-booted-server (fake services): http-dispatcher.mcp 19p: opt-out 404 (/mcp, /mcp/skill), no-service 501, anon 401 first, status only; hono 15p: signed-in 404/501 codes. Message text unasserted. N1: 404 vs 501 kept distinct
    ai.mcp-http-surface · r8 A1 partial plugin-unit: http-dispatcher.mcp 'serves the env-customized SKILL.md as text/markdown, anonymously' (no-store, env URL); content-disposition unasserted; cli nightly e2e GET /mcp/skill 200 corroborates only
    ai.mcp-http-surface · r8 A2 pass HTTP-booted-server: mcp-skill-method-not-allowed.hono.integration 9p (real Hono socket, port 0): POST -> 405, Allow: GET, standard envelope 'Method not allowed — use GET'
    ai.mcp-http-surface · r8 A3 partial plugin-unit + HTTP-booted-server (fake services): http-dispatcher.mcp-oauth 9p: both 401 forms (WWW-Authenticate when OAuth live / plain when off); hono 15p: anon 401 +/- resource_metadata; 'a valid API key is required' wording unasserted
    ai.mcp-http-surface · r8 A4 partial HTTP-in-process: showcase-mcp-http-identity 6p 'an authed member gets a tool list': session bearer, no initialize, 2 names; osk_ initialize + 12 names unpinned. N0 held: 'denies an anonymous MCP request before any tool runs'
    ai.mcp-http-surface · r8 A5 partial plugin-unit: http-dispatcher.mcp-oauth 'verified bearer with NO MCP scope -> 403 insufficient_scope' (header only; body + scope list unasserted); mcp-http-tools.scopes 9p 'data:read alone exposes only the read family'
    ai.mcp-validate-expression · r6 A0 partial plugin-unit: mcp-validate-expression 22p 'accepts a sound formula and reports its inferred type + in-scope context' over a fake McpDataBridge; inferredType not asserted at any layer
    ai.mcp-validate-expression · r6 A1 partial plugin-unit: same file: 'flags a bare field reference…(error)', 'flags an unknown field with a did-you-mean (error)', 'warns (does not error) on a text field misused in arithmetic'
    ai.mcp-validate-expression · r6 A2 skipped none: live leg, out of this pins-only card: no pin runs one expression under both formula and flow_condition
    ai.mcp-validate-expression · r6 A3 partial plugin-unit: same file 'errors clearly when the object does not exist' + 'refuses system objects (fail-closed guard)'. N1 pinned at plugin-unit: 14 blank/whitespace cases 'gets the save gate verdict'
    ai.skill-instructions-mcp-prompts · r4 A0 partial plugin-unit: skill-prompts 12p 'lists an authored skill that carries instructions' + 'projectSkillPrompt keeps the skill name, label and description' over a stub skill bridge
    ai.skill-instructions-mcp-prompts · r4 A1 partial plugin-unit: skill-prompts 'serves the skill instructions on prompts/get' (stub bridge; re-read at get time not driven)
    ai.skill-instructions-mcp-prompts · r4 A2 partial plugin-unit: 'does not project a skill without instructions' + 'does not project an inactive skill' (N0 guarded at unit); activate-then-appears leg not driven
    ai.skill-instructions-mcp-prompts · r4 A3 partial plugin-unit: 'rejects prompts/get for a name that is not a projected skill (-32602)' — unknown name only; non-projected (bare/inactive) get unpinned, N1 live-only
    ai.skill-instructions-mcp-prompts · r4 A4 pass plugin-unit: skill-prompts 'declares NO prompts capability when the host cannot read skill metadata' passed ([test] oracle)
    ai.mcp-oauth-private-host-transport · r6 A0 partial plugin-unit: auth-manager.mcp-oauth 77p 'a private-address plain-HTTP deployment gets the OAuth track and its metadata URL' + isOAuthEligibleBaseUrl private cases; no booted discovery/401 read
    ai.mcp-oauth-private-host-transport · r6 A1 partial plugin-unit: 'a public plain-HTTP deployment stays dark — fail-closed, nothing advertised'; plaintext-notice 26p 'swaps the sentence on a PUBLIC plain-HTTP deployment'; no boot (b) 404s/log
    ai.mcp-oauth-private-host-transport · r6 A2 partial plugin-unit: mcp-oauth-plaintext-notice 26p over stub logger: 'every plain-HTTP boot gets exactly one of the two sentences', warn on private, info on loopback, none under TLS — not a captured boot log
    ai.mcp-oauth-private-host-transport · r6 A3 partial plugin-unit: isOAuthEligibleBaseUrl 'unchanged: http://localhost:3000 → true' etc.; no loopback boot discovery read
    ai.mcp-oauth-private-host-transport · r6 A4 partial plugin-unit: 'is reachable by no configuration key and no environment variable' (predicate half) + 'no environment variable turns either sentence off'; git grep OS_ALLOW_INSECURE_OAUTH_HTTP: ai.json, CHANGELOG, 2 test files only
    ai.mcp-coded-refusals-and-runtime-exposure · r4 A0 pass plugin-unit + engine: all 5 named files >=1 test, 0 failed: record-resource-exposure 8, action-refusal-details 5, plugin-runtime-object-metadata-copy 10, mcp-coded-refusal 43, mcp-stdio-runtime-object-exposure 10
    ai.mcp-coded-refusals-and-runtime-exposure · r4 A1 partial plugin-unit: mcp-coded-refusal 'get_record: RECORD_NOT_FOUND from get answers code, message and status' via handleHttpRequest over a throwing bridge; served door live-only
    ai.mcp-coded-refusals-and-runtime-exposure · r4 A2 partial engine (stdio door): mcp-stdio-runtime-object-exposure 'saved with exposure off, then a restart: refused from the first call' + 'deleted: neither listed nor described'; HTTP door across restart not driven
    ai.mcp-coded-refusals-and-runtime-exposure · r4 A3 partial plugin-unit: mcp-action-refusal-details 'run_action: PERMISSION_DENIED answers code, message and status, and the caller's grants appear nowhere'

    Derived: mcp-http-surface PARTIAL · mcp-validate-expression PARTIAL · skill-instructions-mcp-prompts PARTIAL · mcp-oauth-private-host-transport PARTIAL · mcp-coded-refusals-and-runtime-exposure PARTIAL

    api-backend

    item · rev clause verdict layer · text evidence
    api-backend.bulk-write-contract · r6 A0 partial HTTP-in-process: owner-anchor-and-bulk-writes 12p "a member's REST createMany with no owner_id stamps the caller on every row" (POST /createMany via apiAs); single/bulk key-set parity and defaults unasserted
    api-backend.bulk-write-contract · r6 A1 skipped none: live leg, out of this pins-only card (no pin drives updateMany at a door)
    api-backend.bulk-write-contract · r6 A2 skipped engine (corroboration): live leg, out of this pins-only card; N0 scope rule corroborated at engine only: 'a member bulk UPDATE only touches their own rows' (ql.update multi:true)
    api-backend.bulk-write-contract · r6 A3 partial plugin-unit (route handler, mocked protocol): rest-batch-size-cap 8p 'createMany: 201 records (bare array body) → 400, protocol never called'; live zero-row count not driven
    api-backend.bulk-write-contract · r6 A4 skipped none: live leg, out of this pins-only card (engine 'member bulk DELETE only removes their own rows' is not the per-row PERMISSION_DENIED door answer)
    api-backend.bulk-write-contract · r6 A5 skipped none: live leg, out of this pins-only card (needs captured door responses + server log)
    api-backend.declarative-endpoint-execution · r6 A0 pass HTTP-in-process: showcase-declarative-endpoints 24p 'answers 200 for an authenticated caller' + 'carries the declared cacheTtlSeconds as a Cache-Control header — private included'
    api-backend.declarative-endpoint-execution · r6 A1 pass HTTP-in-process: same file 'DENIES an anonymous caller with 401 — authRequired finally gates' (object_operation + flow); declarative-endpoint-policy 8p 'an OMITTED authRequired denies anonymous' — N0 held
    api-backend.declarative-endpoint-execution · r6 A2 pass CLI-spawn + plugin-unit: authoring-refusal 8p (spawned CLI: validate/build refuse script+proxy, controls accept; PUT /meta/api refused); endpoint-executor 51p 'script answers 501 NOT_IMPLEMENTED with a hint'; apis-publish-gates 48p
    api-backend.declarative-endpoint-execution · r6 A3 pass HTTP-in-process: showcase-declarative-endpoints 'an undeclared path UNDER the endpoint mount is the same bare 404 as one off it'
    api-backend.action-activation-door-contract · r7 A0 pass HTTP-in-process: action-activation-door-live 7p 'acceptance[0]: authority runs first — the member gets the capability 403, the anonymous caller the 401' (N1)
    api-backend.action-activation-door-contract · r7 A1 pass HTTP-in-process: same file 'acceptance[1]: the 2-segment path is the door's shape 400; the 4-segment path is the router's 404'; action-params-contract 5p [#12160] corroborates
    api-backend.action-activation-door-contract · r7 A2 pass HTTP-in-process: same file 'acceptance[2]: the body contract refuses with named field codes, never inverts' (N0)
    api-backend.action-activation-door-contract · r7 A3 pass HTTP-in-process: same file 'acceptance[3]: an empty body ENABLES — 200 with enabled true'
    api-backend.action-activation-door-contract · r7 A4 partial HTTP-in-process: same file 'acceptance[4]: an undeclared action is 404 "nothing to switch off", and no refusal so far wrote a row' (N2); metadata-plane 503 arm: no stock door, no pin (knownGaps[3]) — not covered
    api-backend.action-activation-door-contract · r7 A5 pass HTTP-in-process: same file 'acceptance[5]: the flip answers its body and keeps exactly ONE deployment-level row, updated in place'
    api-backend.action-activation-door-contract · r7 A6 pass HTTP-in-process: same file 'acceptance[6]: 409 RESOURCE_CONFLICT naming every owner, from either object, and nothing written' (activation-ambiguity-fixture)
    api-backend.action-activation-door-contract · r7 A7 pass plugin-unit: posture-gate 29p 'reports a write that could not be made durable, instead of a 200' + 'says so plainly when the engine has no activation ledger'; ledger-reach 11p 'the flip that answered 503 … now succeeds'
    api-backend.rest-crud-config-contract · r6 A0 pass HTTP-in-process: rest-config-contract-live 7p 'crud acceptance[0]: all six default data mounts answer, none with the routing-404 control'
    api-backend.rest-crud-config-contract · r6 A1 pass plugin-unit (real RestServer route table): rest-config-mount-table.pin 24p: create/read/update/delete 'exactly 1 route(s) gone', list 'exactly 2' (N0)
    api-backend.rest-crud-config-contract · r6 A2 pass plugin-unit (real RestServer) + HTTP-in-process: harness 'acceptance[2]: a switched-off operation leaves no handler at all'; live 'an apiEnabled: false object answers OBJECT_API_DISABLED, distinguishable from the routing-404 control' (N1)
    api-backend.rest-crud-config-contract · r6 A3 pass plugin-unit (real RestServer): harness 'acceptance[3]: dataPrefix re-bases the whole data surface, and nothing is left under /data'; discovery-services-route-follows-mount 10p
    api-backend.rest-crud-config-contract · r6 A4 pass plugin-unit (real RestServer): harness 'acceptance[4]: both tombstones refuse at construction with the schema and the prescription'; parse-not-cast §E crud case
    api-backend.rest-crud-config-contract · r6 A5 pass plugin-unit: rest-sub-config-parse-not-cast 25p §C 'an empty config still constructs, with the declared defaults', §D 'KEEPS a partial crud.operations'
    api-backend.rest-batch-config-contract · r6 A0 pass HTTP-in-process: rest-config-contract-live 'batch acceptance[0]: the four per-object bulk doors and the cross-object door are mounted'
    api-backend.rest-batch-config-contract · r6 A1 pass plugin-unit (real RestServer route table): mount-table.pin 'batch.enableBatchEndpoint: on → mounted, off → exactly 1 route(s) gone' (cross-object /batch survives)
    api-backend.rest-batch-config-contract · r6 A2 pass plugin-unit (real RestServer route table): mount-table.pin createMany/updateMany/deleteMany 'exactly 1 route(s) gone' + §2 'the four bulk mounts drop when the protocol lacks the member' (N0)
    api-backend.rest-batch-config-contract · r6 A3 pass plugin-unit (route handler): rest-batch-size-cap 8p: all five doors 400, 'exactly at the cap still goes through', 'the cap follows the deployment config, not a hardcoded 200'
    api-backend.rest-batch-config-contract · r6 A4 pass HTTP-in-process: rest-config-contract-live 'batch acceptance[4]: 201 records against the default cap answer 400 BATCH_TOO_LARGE (max 200) and create nothing'
    api-backend.rest-batch-config-contract · r6 A5 pass plugin-unit (real RestServer): harness 'acceptance[5]: upsertMany and defaultAtomic (true and false) refuse with the schema and the replacement'
    api-backend.rest-batch-config-contract · r6 A6 pass plugin-unit: parse-not-cast §A maxBatchSize 0 / 2000 / 2.5 refused; §C empty-config defaults
    api-backend.rest-metadata-config-contract · r8 A0 pass HTTP-in-process: rest-config-contract-live 'metadata acceptance[0]: every default-prefix metadata mount answers, none with the routing-404 control'
    api-backend.rest-metadata-config-contract · r8 A1 pass plugin-unit (real RestServer): harness 'acceptance[1]: prefix re-bases every metadata route, nothing is left under /meta, and discovery follows'; discovery-services-route-follows-mount 'moves metadata on the same terms'
    api-backend.rest-metadata-config-contract · r8 A2 fail plugin-unit (real RestServer route table): mount-table.pin passes asserting metadata.endpoints.item removes 13 routes incl GET /meta/app/:appId/bundle (#28287); clause/steps + spec describe() enumerate twelve. types 2, items 1, maintenance 3 match
    api-backend.rest-metadata-config-contract · r8 A3 pass HTTP-in-process + plugin-unit: live 'metadata acceptance[3]: the client_liaison member's served schema omits the withheld fields entirely' (N1: admin copy is the control); meta-object-fls 95p D8; §D 'KEEPS metadata.maskObjectFields: false'
    api-backend.rest-metadata-config-contract · r8 A4 pass plugin-unit (real RestServer): harness 'acceptance[4]: enableCache selects the cached read, and each carve-out bypasses it with the switch on'
    api-backend.rest-metadata-config-contract · r8 A5 pass plugin-unit (real RestServer): harness 'acceptance[5]: cacheTtl (3600, 0, -1) and endpoints.schema refuse with the schema and the replacement'
    api-backend.rest-route-generation-tombstones · r4 A0 pass plugin-unit (real RestServer): rest-route-generation-tombstones 10p 'acceptance[0]: each key refuses at construction, whatever value is authored' (nameTransform none+plural); parse-not-cast §E corroborates
    api-backend.rest-route-generation-tombstones · r4 A1 pass plugin-unit: same file 'acceptance[1]: the same refusals survive the plugin path, beside a control that boots'; parse-not-cast §B routes.nameTransform via createRestApiPlugin().start()
    api-backend.rest-route-generation-tombstones · r4 A2 pass plugin-unit: same file 'acceptance[2]: each prescription names a surface that exists in the shipped spec and server'
    api-backend.rest-route-generation-tombstones · r4 A3 pass build (tsc spawn): same file: 5x 'fails tsc on the key's own line' + 'control: the empty block typechecks clean'
    api-backend.rest-route-generation-tombstones · r4 A4 pass plugin-unit: same file 'acceptance[4]: routes: {} constructs and normalizes to {}, and an unknown key inside it is stripped'
    api-backend.second-object-exposure-and-internal-fields · r3 A0 pass engine + plugin-unit: all 6 named files >=1, 0 failed: relation-condition 13, expand-target 15, data-door-internal 50, objectql internal-field 6, second-object-exposure 48, internal-field-data-door 15
    api-backend.second-object-exposure-and-internal-fields · r3 A1 pass HTTP-in-process: second-object-exposure 48p 'the refusal locates the condition at filter.REL, on both doors' + 'names the target'; 404 OBJECT_API_DISABLED / 405 OBJECT_API_METHOD_NOT_ALLOWED; admin + member
    api-backend.second-object-exposure-and-internal-fields · r3 A2 pass HTTP-in-process: same file '$expand on the list/single-record/query route: a withheld target answers as an unexpanded lookup', admin + member
    api-backend.second-object-exposure-and-internal-fields · r3 A3 pass HTTP-in-process: same file internal field filter GET/POST, sort, groupBy, aggregate → 400 INVALID_FIELD naming sox_source/internal_f; internal-field-data-door-positions 15p on sys_api_key.key; N0 control 'no row carries' it
    api-backend.data-request-shape-and-query-arity · r4 A0 pass plugin-unit + engine: all 7 unit files >=1, 0 failed: request-schema-gate 16, data-write-request-gate 76, update-expected-version 65, delete-expected-version 34, query-arity 33, flag-arity 11, conflict-visibility 16
    api-backend.data-request-shape-and-query-arity · r4 A1 pass HTTP-in-process: data-request-shape-live 13p: null/array/number PATCH body, expectedVersion '' and empty If-Match → 400 VALIDATION_FAILED, CONTROL record body served
    api-backend.data-request-shape-and-query-arity · r4 A2 pass HTTP-in-process: same file '400 VALIDATION_FAILED on query, and no rows' + CONTROL empty query 200
    api-backend.data-request-shape-and-query-arity · r4 A3 pass HTTP-in-process: same file 'GET /packages?status=a&status=b: 400 VALIDATION_ERROR' + doubled keepData DELETE refused, package and table remain (N0)
    api-backend.data-request-shape-and-query-arity · r4 A4 pass HTTP-in-process: same file 'member: 404, exactly what the same PATCH with no token answers' + owner 409 CONTROL + row untouched
    api-backend.meta-read-doors-v18 · r4 A0 pass plugin-unit: all 7 unit files >=1, 0 failed: rest sortability 13, member-selector 32, closed-sets 29; runtime app-package-id 12, sortability 8, package-all-fold 13; protocol app-package-id 8
    api-backend.meta-read-doors-v18 · r4 A1 pass HTTP-in-process: meta-read-doors-live 11p 'GET /meta/app/PACKAGE_ID answers the showcase's app' + 'an unknown package answers the same 404 as an unknown name'
    api-backend.meta-read-doors-v18 · r4 A2 pass HTTP-in-process: same file '?member=zh-CN reads only that member', '?member= on … object: 400 VALIDATION_ERROR', 'an unknown parameter … 400 naming it'
    api-backend.meta-read-doors-v18 · r4 A3 pass HTTP-in-process: same file 'GET /meta/view?package=all is byte-identical to GET /meta/view'
    api-backend.meta-read-doors-v18 · r4 A4 pass HTTP-in-process: same file client_liaison budget ABSENT from sortability.fields + sort=budget 403, admin CONTROL; showcase-fls-read-mask-strip 8p
    api-backend.error-sentences-and-unique-violation-wire-code · r5 A0 pass plugin-unit + engine: all 4 unit files >=1, 0 failed: hook-refusal-sentence.ledger 601, hook-script-fault-envelope 18, unique-violation-wire-code 7, storage server-fault-withheld 18
    api-backend.error-sentences-and-unique-violation-wire-code · r5 A1 fail HTTP-in-process: error-sentences-live passes asserting 400 + sentence + body.code 'HOOK_ABORTED' (#27597); clause says no code. Ledger asserts HOOK_ABORTED_400 on nested rows (#27672), clause says VALIDATION_ERROR. Likely stale clause
    api-backend.error-sentences-and-unique-violation-wire-code · r5 A2 pass HTTP-in-process: error-sentences-live '409 UNIQUE_VIOLATION, details exactly { developerMessage, object }, and the row keeps its email'
    api-backend.error-sentences-and-unique-violation-wire-code · r5 A3 pass HTTP-in-process: error-sentences-live 'POST /storage/upload/chunked: 500 INTERNAL with the generic sentence, never the caught text'

    Derived: bulk-write-contract PARTIAL · declarative-endpoint-execution PASS · action-activation-door-contract PARTIAL · rest-crud-config-contract PASS · rest-batch-config-contract PASS · rest-metadata-config-contract FAIL · rest-route-generation-tombstones PASS · second-object-exposure-and-internal-fields PASS · data-request-shape-and-query-arity PASS · meta-read-doors-v18 PASS · error-sentences-and-unique-violation-wire-code FAIL


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-warren · session_01JQwxbWBtYWqaV8NhvUrShB

    Filed by the dispatching PM seat session for the W4-C2a runner session_01JQwxbYA4iFU41N3PukeHhD, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).

    Per-clause verdicts (3/4): approvals, attachments-storage.

    approvals

    item · rev clause verdict layer · text evidence
    approvals.email-action-token-door · r10 A0 partial plugin-unit + engine: approval-service 'issueActionTokens: stores hashes only…' + 'remind: … none carries an action link' (fake engine); internal-hash 1, generic-door 6, at-rest 4 passed. Unpinned: non-pending FORBIDDEN arm; live at-rest read
    approvals.email-action-token-door · r10 A1 partial HTTP-in-process + plugin-unit: action-page-member 'GET renders the confirm page … never decides however often it is fetched'; approval-service 'peek: validates without consuming'. N0 held. Byte-identity of timeline/consumed_at unpinned
    approvals.email-action-token-door · r10 A2 pass HTTP-in-process + engine + plugin-unit: approval-service 'redeem: approves as the bound approver and burns the token'; action-page-member 'POST redeems as the bound approver — the audit row names that approver'; at-rest positive control passed
    approvals.email-action-token-door · r10 A3 partial engine + HTTP-in-process + plugin-unit: replay halves passed: approval-service redeem (consumed), generic-door 'redeems exactly once … refused as consumed on replay', at-rest control; N1 held. Consume-FIRST (failed decide still burns) unpinned
    approvals.email-action-token-door · r10 A4 partial HTTP-in-process + plugin-unit: action-page-member 'a dead link — unknown, expired, consumed — … 200, through GET and POST alike' (N2 held, byte-equal to no-summary page); not_pending/not_approver pages blocked(fixture, kg[0]); live garbage leg skipped
    approvals.email-action-token-door · r10 A5 blocked none: blocked(fixture, knownGaps[0]): no stock door mints a raw token to present as Bearer. Converse pinned: action-page-member 'the token is the only credential: a cookie or Authorization header is never read' passed
    approvals.status-mirror-field · r6 A0 partial plugin-unit + engine: api oracle undriven (pins-only). Below: approval-service mirror cases (open/decide/recall, sendBack 'returned', auto-reject) fake engine; status-mirror-declared-values 7 passed (engine). Ref: corroborating only
    approvals.status-mirror-field · r6 A1 partial engine + plugin-unit: record-lock-multi-update 'exempts a status-mirror write (only the approvalStatusField changes)' (engine) + record-lock hook 'still blocks a mirror write that changes anything else too' (unit); refused PATCH not driven
    approvals.status-mirror-field · r6 A2 partial engine + plugin-unit: status-mirror-cascade 2 passed: 'approve mirror hands the flow a trigger user', 'dead-run release cascades user-less, and is still refused' (N2 held). SLA half only unit 'SLA auto-decision: stays user-less'
    approvals.status-mirror-field · r6 A3 skipped none: live leg, out of this pins-only card: no pin drives an unmirrored node (ref: api clause, run drives it live)
    approvals.status-mirror-field · r6 A4 skipped none: live leg, out of this pins-only card: no pin asserts the '[approvals] mirrorStatusField failed' warn on a nonexistent field with a finalized decision
    approvals.request-page-reply-and-reader-visibility · r5 A0 pass jsdom/plugin-unit + engine: all 6 named files ≥1 test, 0 failed: sys-approval-request-page 20, component-record-approval-decision-22472 8, record-reader-opt-in 8, request-read-gate 16, request-child-read-gate 25, subject-title-reader-fls 8
    approvals.request-page-reply-and-reader-visibility · r5 A1 partial plugin-unit: approval-service 'comment: submitter and approver may reply; outsiders may not' + 'a reply the route admits is a comment row on the request timeline' (fake engine); live page GET + reply POSTs not driven
    approvals.request-page-reply-and-reader-visibility · r5 A2 partial engine (protocol in-process): request-read-gate 16 passed (hidden request 404 by id, excluded from list/count) via findData/getData, no HTTP; /data door leg not driven; 404-persona leg blocked(fixture) regardless
    approvals.request-page-reply-and-reader-visibility · r5 A3 partial engine (protocol in-process): record-reader-opt-in 8 passed incl. read-only/no actions and inbox not widened; live per-flag list not driven
    approvals.request-page-reply-and-reader-visibility · r5 A4 skipped none: live leg, out of this pins-only card (screenshot of decision panel); component-record-approval-decision-22472 is a spec-level pin only
    approvals.act-door-and-admin-rescue-slate · r5 A0 pass plugin-unit + engine + HTTP-in-process: approvals-act 13, action-page-member 12, hono-approvals-act.conformance 4, admin-rescue-named-slate 21 (W3: 16), approval-admin-rescue-slate.dogfood 1 — all passed, 0 failed
    approvals.act-door-and-admin-rescue-slate · r5 A1 partial HTTP-in-process + plugin-unit: hono conformance 'GET renders … a form POST redeems it'; action-page-member dead-link 200 + mount parity; approvals-act 'claims exactly … GET, HEAD and POST'. Self-hosted PUT ENDPOINT_NOT_FOUND/no-Allow: no pin
    approvals.act-door-and-admin-rescue-slate · r5 A2 pass HTTP-in-process: approval-admin-rescue-slate.dogfood 'lists, counts and notifies each administrator, not a member, records an ordinary approval' (asserts via_override false) over bootStack REST door

    Derived: email-action-token-door PARTIAL · status-mirror-field PARTIAL · request-page-reply-and-reader-visibility PARTIAL · act-door-and-admin-rescue-slate PARTIAL

    attachments-storage

    item · rev clause verdict layer · text evidence
    attachments-storage.presigned-upload-roundtrip · r3 A0 partial HTTP-in-process: matrix '(e) authenticated upload succeeds and sys_file.owner_id is server-stamped' (committed row). Presign response fields + pending-row read unpinned
    attachments-storage.presigned-upload-roundtrip · r3 A1 skipped none: live leg, out of this pins-only card: no pin reads sys_file pending→committed around /upload/complete (uploadFile helper asserts statuses only)
    attachments-storage.presigned-upload-roundtrip · r3 A2 partial HTTP-in-process: matrix '(e-read)' asserts {success:true,data:{url}} on owner /url, never follows it; byte comparison unpinned for attachments scope (storage-unclaimed-download follows on a scope-less file)
    attachments-storage.presigned-upload-roundtrip · r3 A3 skipped none: live leg, out of this pins-only card for the attachments-scope file; corroborating only: storage-unclaimed-download 'a signed-in caller with a bearer token is served' 302→Location→bytes on a scope-less file
    attachments-storage.presigned-upload-roundtrip · r3 A4 partial HTTP-in-process: matrix '(e) anonymous presigned upload → 401 AUTH_REQUIRED' passed (N0 held); sys_file count before/after unpinned
    attachments-storage.download-authz-both-sides · r10 A0 pass HTTP-in-process: matrix '(e-read)' anon 401 AUTH_REQUIRED on /url and /files (attachments scope); public-read-acl 'a FIELD-owned file opts out the same way' anon 401 AUTH_REQUIRED before flip (N0 held)
    attachments-storage.download-authz-both-sides · r10 A1 pass HTTP-in-process: matrix '(e-read)' 403 ATTACHMENT_DOWNLOAD_DENIED; public-read-acl 'BEFORE the flip: … refused 403' and field-owned 403 FILE_DOWNLOAD_DENIED
    attachments-storage.download-authz-both-sides · r10 A2 partial HTTP-in-process: matrix '(e-read)' 200 {success,data:{url}} for owner and a parent-reading member; url never followed; uploader-bypass leg unpinned (ref: hand-driven)
    attachments-storage.download-authz-both-sides · r10 A3 pass HTTP-in-process: public-read-acl 8 passed: 'AFTER the flip: acl=public_read 302s anonymously to the REAL BYTES', per-FILE sibling stays closed, flip back re-closes, ttl branch distinguished
    attachments-storage.download-authz-both-sides · r10 A4 partial jsdom component: RecordAttachmentsPanel.test.tsx 31 passed (friendly-copy mapping, both envelope dialects); browser screenshot leg not driven — ref: lifts A4 and N1 to partial only
    attachments-storage.read-inherits-parent-rls · r9 A0 pass HTTP-in-process: matrix '(c) a member CANNOT list/read sys_attachment rows whose parent record they cannot read' passed: scoped list excludes att_secret rows, readable-parent row listed (N0 held)
    attachments-storage.read-inherits-parent-rls · r9 A1 pass HTTP-in-process + engine: count-parity 7 passed: member total excludes, entitled includes, paging = total, engine.count under resolved ctx filtered, narrowed count 0 (N1 held)
    attachments-storage.read-inherits-parent-rls · r9 A2 pass HTTP-in-process: matrix '(c)' by-id GET of the hidden attachment answers 403/404, not the row
    attachments-storage.read-inherits-parent-rls · r9 A3 partial HTTP-in-process + engine + plugin-unit: scan-cap 3 passed (>2000 rows served whole, true total, no '-row cap' log via captured logger); probe half only attachment-read-leaf.integration 11 (engine) + attachment-read-leaf 20 (unit)
    attachments-storage.attach-requires-parent-edit · r9 A0 pass HTTP-in-process: matrix '(item 3) a member who can READ but not EDIT the parent cannot attach — yet can still list its attachments' (403 ATTACHMENT_PARENT_ACCESS). N1 re-list after refused attach not pinned
    attachments-storage.attach-requires-parent-edit · r9 A1 pass HTTP-in-process: matrix '(f) member attaches to a readable record; uploaded_by is server-stamped over a spoofed value' passed
    attachments-storage.attach-requires-parent-edit · r9 A2 partial HTTP-in-process: matrix (a): read-not-edit 403 ATTACHMENT_DELETE_DENIED, non-reader 404, parent editor 200, rows re-read. Uploader-without-parent-edit leg not pinned (ref: hand-driven)
    attachments-storage.attach-requires-parent-edit · r9 A3 pass HTTP-in-process stack, engine holder: unscoped-delete-gate 10 passed incl. block 2 'refuses { multi: true } … even though the caller may delete every matched row' + 'refuses on an EMPTY table too'; access-hooks 150
    attachments-storage.attach-requires-parent-edit · r9 A4 pass HTTP-in-process: matrix '(#2727) attaching to an object without enable.files → 403 FILES_DISABLED' passed (pin fixture, not showcase_account). N1 re-list not pinned
    attachments-storage.attach-requires-parent-edit · r9 A5 partial engine (real ObjectQL, stub driver): capability-gate-update-verb 12 passed: by-id and predicate re-point 403 FILES_DISABLED, parent_object unchanged (N2 held at engine); REST PATCH lane not driven
    attachments-storage.sys-file-status-pipeline · r5 A0 partial HTTP-in-process doors + engine read: matrix lifecycle 'tombstones on last-ref delete, keeps shared files alive, un-tombstones on re-attach': committed→deleted→committed read via ql.findOne(SYS); pending→committed never read
    attachments-storage.sys-file-status-pipeline · r5 A1 partial route-handler unit: tombstone-download-live-reference 'leaves pending refused — only the tombstone limb widened' (mock HTTP server, fake engine) — verify: never scores this api clause
    attachments-storage.sys-file-status-pipeline · r5 A2 partial route-handler unit: tombstone-download-live-reference 9 passed (live holder 200 on both endpoints, sweep agrees, 404 when last holder goes); live 404/200 legs not driven
    attachments-storage.sys-file-status-pipeline · r5 A3 pass HTTP-in-process doors + engine read: matrix lifecycle: after first join DELETE over /data sys_file still committed, deleted (deleted_at set) after second (N0 held)
    attachments-storage.sys-file-status-pipeline · r5 A4 pass HTTP-in-process doors + engine read: matrix lifecycle: re-attach → status committed, deleted_at null
    attachments-storage.sys-file-status-pipeline · r5 A5 partial plugin-unit: attachment-lifecycle 'never tombstones non-attachments scopes (Field.file/avatar protection)' over stub adapters; N1 'a failing lookup never blocks the delete' unit
    attachments-storage.orphan-tombstone-reap · r4 A0 pass HTTP-in-process + plugin-unit: matrix 'sys_file orphan lifecycle (ADR-0057 reap guard)' 5 passed; attachment-lifecycle 50 passed incl. 'a byte-delete failure vetoes the row', 'vetoes field-file tombstones while the deployment gate is closed'
    attachments-storage.orphan-tombstone-reap · r4 A1 partial HTTP-in-process setup + in-process sweep; unit: matrix 'the sweep reaps expired tombstones AND their bytes…' (row null, bytes gone on disk; N0 held); failed-byte-delete leg + warn only unit (fake engine, mock logger)
    attachments-storage.orphan-tombstone-reap · r4 A2 pass HTTP-in-process setup + in-process sweep: matrix 'sweep-time re-verification: a tombstone that regained a reference behind the hooks' back is un-tombstoned, not reaped' passed
    attachments-storage.orphan-tombstone-reap · r4 A3 pass HTTP-in-process setup + in-process sweep: matrix sweep case: committed control and fresh tombstone survive (fresh still 'deleted'; N1 held)
    attachments-storage.upload-session-abort · r8 A0 skipped none: live leg, out of this pins-only card; storage-chunked-resume-integrity drives the chunked round-trip over HTTP but never reads sys_upload_session status (ref: unpinned)
    attachments-storage.upload-session-abort · r8 A1 pass HTTP-in-process + in-process sweep: matrix '(item 4 + multipart-abort guard) an abandoned chunked upload is reaped AND its uploaded parts are aborted' passed
    attachments-storage.upload-session-abort · r8 A2 pass plugin-unit: createUploadSessionReapGuard 'does NOT abort a completed session', 'reaps a session with no backend_upload_id without calling abort', 'reaps the row when the adapter cannot abort at all' (N1 held)
    attachments-storage.upload-session-abort · r8 A3 partial plugin-unit: 'VETOES on abort failure so backend_upload_id survives for the retry' (N0 held); warn asserted on mock logger, not its text
    attachments-storage.upload-session-abort · r8 A4 partial route-handler unit: storage-routes '#7667' block: 'stamps failed…', 'stamps expired and 410s…'; no session-status scan over the doors
    attachments-storage.upload-session-abort · r8 A5 partial route-handler unit: storage-routes 'stamps expired and 410s a chunk PUT past the session deadline' / '…a completion…' / 'does not expire a session still inside its deadline'; api door not driven
    attachments-storage.inline-grid-receipt-cells · r5 A0 pass browser-live: grid-file-upload.spec.ts 1 passed twice (17.2s, 15.1s): dialog/Line Items visible, then th 'Receipt' toHaveCount(1)
    attachments-storage.inline-grid-receipt-cells · r5 A1 pass browser-live: spec: input[type=file] toHaveCount(1), input[type=text][aria-label=Receipt] toHaveCount(0) (N0 held)
    attachments-storage.inline-grid-receipt-cells · r5 A2 partial browser-live: spec asserts chip 'receipt.png' only; /api/v1/storage/* upload requests not captured (routing inferred from file door bytes)
    attachments-storage.inline-grid-receipt-cells · r5 A3 partial browser-live: spec: batch op receipt is a string not containing name; GET storage/files/:id 200 image/png bytes equal (N1 rests on that GET). sys_file row + batch success unread
    attachments-storage.upload-limits-scope-and-ownership · r4 A0 pass route-handler unit + HTTP-in-process + engine: storage-limits 18, upload-scope-vocabulary 6, storage-unclaimed-download 6, upload-door-ownership 23, raw-token-refusal 30, engine-file-hydrate-refused 15, -parent-derived 17: all passed
    attachments-storage.upload-limits-scope-and-ownership · r4 A1 partial HTTP-in-process: storage-upload-limits.dogfood 2 passed: presign/raw 413 PAYLOAD_TOO_LARGE at 100MB default and after a 1MB save without restart; no sys_file count read
    attachments-storage.upload-limits-scope-and-ownership · r4 A2 partial route-handler unit: upload-scope-vocabulary 6 passed (hand-built IHttpRequest/Response, no adapter); api door not driven
    attachments-storage.upload-limits-scope-and-ownership · r4 A3 pass HTTP-in-process (booted org wall): storage-upload-door-ownership.wall 10 passed: colleague commit/chunked-complete/progress 403 PERMISSION_DENIED, row unchanged
    attachments-storage.upload-limits-scope-and-ownership · r4 A4 pass HTTP-in-process: storage-unclaimed-download 'an anonymous caller is refused 401 AUTH_REQUIRED at both download doors' with location null (N0 held)
    attachments-storage.upload-limits-scope-and-ownership · r4 A5 partial engine: engine-file-hydrate-refused 15 + -parent-derived 17 passed (ObjectQL direct); no /data read of a planted foreign id
    attachments-storage.chunked-upload-integrity · r8 A0 pass plugin-unit + HTTP-in-process: chunked-upload-integrity 23 (W3: 13), storage-chunked-resume-integrity 4, chunk-part-record-concurrency 24, storage-upload-organization-change.wall 10: all passed
    attachments-storage.chunked-upload-integrity · r8 A1 pass HTTP-in-process: storage-chunked-resume 'REFUSED: … 409 RESOURCE_CONFLICT naming it': details.missingChunks [0] (pin's own fixture literal), progress status in_progress
    attachments-storage.chunked-upload-integrity · r8 A2 pass HTTP-in-process: storage-chunked-resume 'a RE-SENT chunk leaves the progress unchanged' passed
    attachments-storage.chunked-upload-integrity · r8 A3 pass HTTP-in-process (booted org wall): storage-upload-organization-change.wall 10 passed: chunk PUT 409, chunked complete 409, progress 200 live / 409 once expiry due, RESOURCE_CONFLICT, row unchanged

    Derived: presigned-upload-roundtrip PARTIAL · download-authz-both-sides PARTIAL · read-inherits-parent-rls PARTIAL · attach-requires-parent-edit PARTIAL · sys-file-status-pipeline PARTIAL · orphan-tombstone-reap PARTIAL · upload-session-abort PARTIAL · inline-grid-receipt-cells PARTIAL · upload-limits-scope-and-ownership PARTIAL · chunked-upload-integrity PASS


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-warren · session_01JQwxbWBtYWqaV8NhvUrShB

    Filed by the dispatching PM seat session for the W4-C2a runner session_01JQwxbYA4iFU41N3PukeHhD, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).

    Per-clause verdicts (4/4): automation, cli.

    automation

    item · rev clause verdict layer · text evidence
    automation.trigger-type-matrix · r10 A0 skipped none: live leg, out of this pins-only card: no pin yields per-variant run rows. N0 401 half pinned HTTP-in-process (anonymous-deny-surfaces 'anonymous POST /automation/:name/trigger is denied (401)'); no-run-row half undriven
    automation.trigger-type-matrix · r10 A1 skipped none: live leg, out of this pins-only card: no pin reads showcase_urgent_task_alert runs per leg
    automation.trigger-type-matrix · r10 A2 skipped none: live leg, out of this pins-only card. N1 corroborated below oracle only: inbound-hook-member.test.ts 12 passed (kernel, no HTTP server) refuses bad signatures, enqueues only verified
    automation.trigger-type-matrix · r10 A3 skipped none: live leg, out of this pins-only card: no pin observes two schedule ticks
    automation.trigger-type-matrix · r10 A4 partial browser-live: screen-flow.spec.ts 1 passed x2 (proxy mode): asserts launch POST /actions/showcase_task/showcase_bulk_reassign and resume POST; run detail paused->completed never read (live run read missing)
    automation.trigger-type-matrix · r10 A5 pass build (static ledger test): flow-trigger-conformance.test.ts 2 passed: 'is a sound conformance ledger + ratchet, every flow type has a runtime + proof'; 'discovery finds the known flow types'
    automation.screen-flow-roundtrip · r7 A0 partial browser-live: screen-flow.spec.ts 1 passed x2: launch POST on the action door asserted (collection form); run status paused at 'collect' never read (live run read missing)
    automation.screen-flow-roundtrip · r7 A1 skipped none: live leg, out of this pins-only card: no pin reads GET /runs/:runId/screen on the showcase
    automation.screen-flow-roundtrip · r7 A2 pass browser-live: screen-flow.spec.ts 1 passed x2 (23.8s, 15.8s, proxy mode): dialog visible, heading /New Assignee/ visible, input filled and submitted
    automation.screen-flow-roundtrip · r7 A3 partial browser-live: screen-flow.spec.ts: resume POST /runs/:id/resume inputs match the submitted new_assignee; run re-read status=completed not pinned (live run read missing)
    automation.screen-flow-roundtrip · r7 A4 skipped none: live leg, out of this pins-only card: the spec's final assertion is the grid cell this clause excludes; no authoritative GET /data/showcase_task read
    automation.screen-flow-roundtrip · r7 A5 partial engine: screen-resume-validation.test.ts 15 passed: 'rejects a missing UNCONDITIONAL required field', 'leaves the run resumable after a refusal'; HTTP 400 + re-read missing. N0 same layer
    automation.screen-flow-roundtrip · r7 A6 skipped none: live leg, out of this pins-only card: cancel/park not in any pin (N1 not driven)
    automation.durable-suspend-restart · r4 A0 partial HTTP-in-process: flow-durable-suspend.dogfood.test.ts 11 passed: 'suspends at the screen node and PERSISTS the pause as a paused row', 'whole SuspendedRun round-trips' (own fixture; timer + nested suspends not pinned)
    automation.durable-suspend-restart · r4 A1 partial HTTP-in-process: same file: 'the paused row survives the restart with its continuation intact' - cold boot is a 2nd bootStack in one process, not a spawned server; showcase nested pair not driven
    automation.durable-suspend-restart · r4 A2 skipped none: live leg, out of this pins-only card: showcase_task_follow_up PT1M timer resume after restart not pinned
    automation.durable-suspend-restart · r4 A3 skipped none: live leg, out of this pins-only card: project_closure/closure_signoff nested pause + approve not pinned
    automation.durable-suspend-restart · r4 A4 partial HTTP-in-process: same file: 'the suspension is CONSUMED from the durable store on resume - no zombie row', 'a THIRD boot still reads it' (generic half per ref; showcase runs live). N0 guarded here
    automation.paused-run-trigger-record-masked · r5 A0 partial engine + HTTP-in-process: flow-trigger-record-credential-mask 7 passed: 'persisted variables_json and context_json carry the mask' (engine read), data door checks record only; admin reader, member not driven; null-where-unset unexercised
    automation.paused-run-trigger-record-masked · r5 A1 partial HTTP-in-process: same file: 'GET /automation/:name/runs/:runId shows the same' (record+previous masked, leak scan) as admin; step 3's member-persona read not driven (knownGaps[1]); N0 persona half open
    automation.paused-run-trigger-record-masked · r5 A2 pass HTTP-in-process resume + engine echo read: same file: 'a node after the pause reads the mask off record and previous': seen_name value, seen_password/seen_token/seen_previous_password = SECRET_MASK. N1 ordinary-field half held
    automation.paused-run-trigger-record-masked · r5 A3 partial HTTP-in-process: same file: 'the rehydrated run resumes with the masked record' - second bootStack in the same vitest process, not a spawned server restart
    automation.paused-run-trigger-record-masked · r5 A4 pass engine: same file: 'the scene is armed: the stored row holds the plaintext password, a secret ref and the internal value'; 'the privileged resolveSecretField path is unchanged'
    automation.setup-packaged-automation-board · r10 A0 blocked none: blocked(dependency, #28785): the surface this clause names (Setup Packaged Automation board, its flow half and nav_packaged_automation) was retired at the subject (ADR-0146 D11); its ref files are deleted or renamed. stale ref + s
    automation.setup-packaged-automation-board · r10 A1 blocked none: blocked(dependency, #28785): the surface this clause names (Setup Packaged Automation board, its flow half and nav_packaged_automation) was retired at the subject (ADR-0146 D11); its ref files are deleted or renamed. stale spec: t
    automation.setup-packaged-automation-board · r10 A2 blocked none: blocked(dependency, #28785): the surface this clause names (Setup Packaged Automation board, its flow half and nav_packaged_automation) was retired at the subject (ADR-0146 D11); its ref files are deleted or renamed. stale spec (f
    automation.setup-packaged-automation-board · r10 A3 partial component (mocked fetch): PackagedActionsSection.test.tsx 18 passed: 'no clone for actions offers the switch and nothing else'; flow-row clone half retired by #28785 (stale); live DOM not driven
    automation.setup-packaged-automation-board · r10 A4 partial component (mocked fetch): PackagedActionsSection: 'shows a packaged action with no drift badge, no diff-vs-base', 'does not display ancestry even when metadata carries it'; live page not driven
    automation.setup-packaged-automation-board · r10 A5 blocked none: blocked(dependency, #28785): the surface this clause names (Setup Packaged Automation board, its flow half and nav_packaged_automation) was retired at the subject (ADR-0146 D11); its ref files are deleted or renamed. stale spec: n
    automation.setup-packaged-automation-board · r10 A6 blocked none: blocked(dependency, #28785): the surface this clause names (Setup Packaged Automation board, its flow half and nav_packaged_automation) was retired at the subject (ADR-0146 D11); its ref files are deleted or renamed. stale spec: t
    automation.setup-packaged-automation-board · r10 A7 skipped none: live leg, out of this pins-only card: member posture record needs a live boot
    automation.flow-registration-verdict-on-read · r2 A0 pass plugin-unit + engine: meta-flow-cached-registration.test.ts 3 passed (rest, stubbed); flow-refused-registration-read.integration.test.ts 5 passed (ObjectKernel+ObjectQL+SqlDriver, no HTTP)
    automation.flow-registration-verdict-on-read · r2 A1 partial engine + plugin-unit: integration: 'item read serves the stored status unchanged, beside the engine's refusal and its reason', 'control: a registered stored flow reads registered'; no booted GET /meta/flow, no showcase flow
    automation.flow-registration-verdict-on-read · r2 A2 partial engine: integration: 'the list carries each verdict beside the items, keyed by name'; protocol layer only, HTTP GET /meta/flow not driven
    automation.flow-authoring-refusals-v18 · r5 A0 pass unit (spec/lint): 9 files all passed, 0 failed: value-slot 173, text-slot 48, node-config-keys 38, node-config-values 69, bound-variable-name 115, flow 139, flow-cel-root 80, retry-policy 17, anon-elevated-gate 14
    automation.flow-authoring-refusals-v18 · r5 A1 skipped none: live leg, out of this pins-only card: no pin runs os validate per arm (ref says so). N0 not consulted
    automation.flow-authoring-refusals-v18 · r5 A2 skipped none: live leg, out of this pins-only card: no pin drives PUT /api/v1/meta/flow arms
    automation.flow-authoring-refusals-v18 · r5 A3 skipped none: live leg, out of this pins-only card: controls through os validate / PUT not pinned
    automation.flow-run-semantics-v18 · r3 A0 pass engine + plugin-unit + HTTP-in-process: all 7 passed: cel-current-user 15, cel-record-binding 17, action door 35, endpoint door 17, decision-overlap 22, verify trigger-elevated-door 16, dogfood flow-door-elevated-start 27
    automation.flow-run-semantics-v18 · r3 A1 skipped none: live leg, out of this pins-only card: no pin reads back a record-triggered run's stamped user id over HTTP (flow-cel-current-user drives the engine only)
    automation.flow-run-semantics-v18 · r3 A2 pass HTTP-in-process: verify automation-trigger-elevated-door: 'member starts etd_auto_sys: refused 403 PERMISSION_DENIED, nothing ran' (runs via listRuns 0); dogfood same on action/run_action/endpoint. N0 held
    automation.flow-run-semantics-v18 · r3 A3 pass plugin-unit (real AutomationEngine, run log): decision-overlapping-edge-conditions.pin: 'two overlapping true edges -> exactly ONE successor runs: the first declared'; 'passed-over sibling records a skipped step'
    automation.inbound-hook-timestamped-signature · r2 A0 pass plugin-unit + unit: inbound-hook-member.test.ts 12, http-signature.test.ts 16, domains/automation-hooks.test.ts 19 - all passed, 0 failed
    automation.inbound-hook-timestamped-signature · r2 A1 partial plugin-unit (kernel, real Hono mount, stub queue): inbound-hook-member: row 'a timestamped signature' -> 202, body {accepted:true,messageId}; no booted showcase server / real queue
    automation.inbound-hook-timestamped-signature · r2 A2 skipped none: live leg, out of this pins-only card: ref says cross-arm byte identity + run count are measured live only
    automation.scheduled-work-opt-in · r2 A0 pass plugin-unit (LiteKernel, fake scheduler): trigger-schedule per-kernel-scheduled-work-policy 10 passed; service-automation per-kernel-scheduled-work-policy 12 passed; 0 failed
    automation.scheduled-work-opt-in · r2 A1 skipped none: live leg, out of this pins-only card: served boot log + run list after intervals (ref: not scorable from pins)
    automation.scheduled-work-opt-in · r2 A2 skipped none: live leg, out of this pins-only card: flagged served boot run list (pins assert arming only)

    Derived: trigger-type-matrix PARTIAL · screen-flow-roundtrip PARTIAL · durable-suspend-restart PARTIAL · paused-run-trigger-record-masked PARTIAL · setup-packaged-automation-board PARTIAL · flow-registration-verdict-on-read PARTIAL · flow-authoring-refusals-v18 PARTIAL · flow-run-semantics-v18 PARTIAL · inbound-hook-timestamped-signature PARTIAL · scheduled-work-opt-in PARTIAL

    cli

    item · rev clause verdict layer · text evidence
    cli.scaffold-first-run · r7 A0 partial CLI-spawn + HTTP-booted-server: local replay of scaffold-e2e repo-dist job: scaffold/install/validate/build/test exit 0, health 200 v18.2.0, ready 200; but @objectstack/* installed from registry 18.2.0, not subject builds
    cli.scaffold-first-run · r7 A1 partial CLI-spawn: variants=[blank]: subject scaffolder's blank template validate 0, build 0 - with registry 18.2.0 CLI/runtime; pre-release variant (fixtures.requires[1], knownGaps[2]) not taken
    cli.scaffold-first-run · r7 A2 partial HTTP-booted-server: os start --artifact ./dist/objectstack.json --port 48080 healthy on try 4, no protocol refusal - handshake measured on registry 18.2.0 runtime, not the subject's
    cli.scaffold-first-run · r7 A3 partial CLI-spawn: skills add ‹repo>/skills --all --copy: SKILLS SET EQUAL (11 unique names); repo-root --list 'Found 11 skills', no dogfood-verification; scaffolder's own skills install (18-line) not replayed. N0 held
    cli.scaffold-first-run · r7 A4 pass CLI-spawn + workflow read: single probe run healthy at try 4 (within the workflow's 30x2s budget), server.log captured; scaffold-e2e.yml:218-219 '::error::server never became healthy'; cat server.log; exit 1
    cli.dev-automigrate-policy · r8 A0 partial CLI-spawn + engine: dev-standalone-self-heal: os dev restart logs '[schema-drift] auto-reconciled replace_unique_index on scaf_item.qa_code', legacy index gone; no co-staged needs_confirm/destructive, no converged 2nd boot
    cli.dev-automigrate-policy · r8 A1 partial CLI-spawn: dev-standalone-self-heal 'a production boot reports the staged drift and does not auto-migrate it' (os serve, key omitted = off): one boot; paired off boots + byte-identical dump not pinned (N1)
    cli.dev-automigrate-policy · r8 A2 partial engine (driver): sql-driver-schema-drift 'is force-disabled under NODE_ENV=production (warns, does not alter)': driver over stub logger; boot log + remedy text unread (ref: partial)
    cli.dev-automigrate-policy · r8 A3 partial engine (driver): schema-drift: 'does NOT auto-apply destructive drift (orphan column kept; warned instead)', 'needs_confirm survives dev auto-reconcile'; schemaMode gate + boot log re-warn not pinned. N0 held
    cli.dev-automigrate-policy · r8 A4 pass engine (driver): 25031 4 passed (blocked applyLimit plain+org, refused apply, CONTROL); unique-tenancy 'bare composite...ADR-0131 D1' 2 passed; 14902 'is not auto-applied at boot under dev autoMigrate: safe'. N2 held
    cli.dev-automigrate-policy · r8 A5 pass CLI-spawn + unit: dev-standalone-self-heal: keyless os dev restart logs auto-reconciled; non-dev os serve warns only, index kept; dev-auto-migrate.test 7 passed (three SQL kinds; sqlite-wasm gets nothing, N3)
    cli.migrate-meta-write-stored-and-all · r3 A0 pass CLI-in-process + library units: migrate-meta-write 24, meta.report-order 21, semantic-relevance 22, canonicalize-stored-flow 40, refused-shapes 80 - all passed, 0 failed
    cli.migrate-meta-write-stored-and-all · r3 A1 pass CLI-in-process: migrate-meta-write: 'the dry run lists the sites and writes no source (control)'; 'without --write writes no source file' (MigrateMeta.run over a temp module tree, file snapshot compare)
    cli.migrate-meta-write-stored-and-all · r3 A2 pass CLI-in-process: migrate-meta-write: 'writes every attributed site, and only those bytes change'; 'lists each refused site...with its kind'; 'is idempotent: a second run applies nothing'
    cli.migrate-meta-write-stored-and-all · r3 A3 partial unit (report formatter): meta.report-order ABSENT: 'counts them on one line naming --all', 'lists every one of them under --all' - printMigrationReport over constructed reports, not os migrate meta over a stack
    cli.migrate-meta-write-stored-and-all · r3 A4 partial library unit: canonicalize-stored-flow 40 + refused-shapes 80 pin the TODO sink; no pin runs os migrate meta --stored and reads its TODO lines (knownGaps[0])
    cli.meta-package-flags-and-explain · r3 A0 pass CLI-in-process over real save/reset doors: register-package 8, delete-reset-carriers 29, register-force 7, explain-rule-id 14, delete-noop-line 7 - all passed, 0 failed
    cli.meta-package-flags-and-explain · r3 A1 pass CLI-in-process over real save door: register-package: '--package P writes P's row' with PUT search '?package=PKG' read off the wire; 'an empty --package is refused BEFORE the client is built - nothing reaches the door'
    cli.meta-package-flags-and-explain · r3 A2 pass CLI-in-process over real save door: register-force: 'UNFLAGGED, a field removed: refused 409 DESTRUCTIVE_CHANGE...hint naming --force' exit 1; '--force...?force=true on the wire, and the save lands' exit 0
    cli.meta-package-flags-and-explain · r3 A3 pass CLI-in-process: explain-rule-id: 'os explain field-no-consumers prints the reasoning' (--json rule/covers/paragraphs), 'no-argument listing names the rule explanations', 'an id that is neither refuses with exit 1'
    cli.validate-v18-authoring-verdicts · r2 A0 pass unit (spec/formula/lint): 7 files all passed, 0 failed: seed-record-keys 13, field-existence-spellings 31, stack-duplicate-entry 138, master-detail-required 24, cbp-extension-master 12, component-props 118, email-sms 16
    cli.validate-v18-authoring-verdicts · r2 A1 skipped none: live leg, out of this pins-only card: no pin runs os validate / os build per arm (ref says so)
    cli.validate-v18-authoring-verdicts · r2 A2 skipped none: live leg, out of this pins-only card: controls through os validate / build not pinned
    cli.verify-derived-proof-families · r3 A0 pass CLI-spawn: verify-reference-shapes 3, verify-delete-behaviors 3, verify-unique-scopes 3, verify-parent-write-reach 3, verify-dashboard-windows 3 - all passed (spawnSync of the CLI)
    cli.verify-derived-proof-families · r3 A1 skipped none: live leg, out of this pins-only card: each pin runs its family over its own fixture stack, never the showcase
    cli.verify-derived-proof-families · r3 A2 pass CLI-spawn: verify-delete-behaviors 'NEGATIVE CONTROL: reports a cascade a hook undid, counts it, and exits 1' (asserts exit 1, status contradicted, summary contradicted 1, hardFailures 1)

    Derived: scaffold-first-run PARTIAL · dev-automigrate-policy PARTIAL · migrate-meta-write-stored-and-all PARTIAL · meta-package-flags-and-explain PASS · validate-v18-authoring-verdicts PARTIAL · verify-derived-proof-families PARTIAL


    Generated by Claude Code

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-warren · session_01JQwxbWBtYWqaV8NhvUrShB

    Filed by the dispatching PM seat session for the W4-C2a runner session_01JQwxbYA4iFU41N3PukeHhD, whose own write was refused by its session permissions (RUNNER rule 2: staged text, posted verbatim through the same door).

    Close-out for this record (SKILL §5).

    Extracted: #28934 · api-backend.rest-metadata-config-contract · acceptance[2]
    Extracted: #28936 · api-backend.error-sentences-and-unique-violation-wire-code · acceptance[1]
    Parked-on: #27377 · 40 PARTIAL items: coverage-mode, fixture and pin gaps, and 18 checklist-accuracy findings (anchor comment 6569185240)

    Four-way disposition of the two clause FAILs:

    No product defect came from the off-clause probes. The VITE_SERVER_URL 401 is ruled behaviour (objectui#5702) and is parked on #27377 as a skill accuracy line, not extracted. No security finding.


    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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions