Skip to content

QA run · ai.mcp-stdio-fail-closed (1/1) · fb82f9b1 · 2026-10-16 · 1 PASS / 0 PARTIAL / 0 FAIL / 0 BLOCKED / 0 NOT-RUN #23995

Closed

Description

@objectstack-fleet

Run record for the re-run #23950 asks for, after its six stale clauses were re-pointed. Runner: an os-dev subagent dispatched by the domain:devx seat 2 PM (session session_016PVjjuVPte5XEJvaQx1E4t). Protocol: .claude/skills/checklist-test/SKILL.md + docs/qa/platform-checklist/RUNNER.md. Executed sequentially (no subagent tool in this runner).

Environment fingerprint

  • framework: fb82f9b180bcc6af04ce8d36153fd52d2eb6845c, the tip of branch claude/issue-23950-checklist-stale-clauses at run time. Its product tree is origin/main 022c6e799; the branch adds docs/qa/platform-checklist/areas/*.json only. Built with pnpm install --frozen-lockfile && pnpm build (75/75 tasks green).
  • .objectui-sha: daeb77fc84dd824e74c95b87cdede85afdb248e7 (this item drives no console).
  • host: os start -p 47311 -d file:(run dir)/ai/data.db from examples/app-showcase, with OS_PORT=47311. The personas were provisioned first on os dev --ui --seed-admin over the same port and DB, and that server was stopped before the stdio legs.
  • personas: the seeded admin; a contributor-bound member and a client_liaison-bound member, each minted by invite + sign-up and placed through POST /api/v1/data/sys_user_position; one osk_ key each through POST /api/v1/keys. The contributor owns one invoice of its own (POST /api/v1/data/showcase_invoice).
  • stdio client: line-delimited JSON-RPC that writes nothing until the principal-bound line is in the log (see the note under the verdicts).
  • timestamps: 2026-10-16, 16:21Z to 16:26Z.

Scope

Selector ai.mcp-stdio-fail-closed resolves to 1 runnable item: ai.mcp-stdio-fail-closed at revision 5, P0, surface cli. Revision 5 is the revision #23950's branch carries. The item text was read at the branch head c4bf2ba4e. After the run, revision 5's clause 1 and clause 6 dropped their quotation of the revocation message's wording. That edit unpins wording only; the code, status and no-row evidence below is what both clauses score.

Tier 1 pin (RUNNER rule 6): pnpm --filter @objectstack/mcp exec vitest run --maxWorkers=2 src/__tests__/plugin.test.ts: 1 file, 17 passed. The pin covers the keyless and unknown-key refusals and the stdio-off boot. It does not cover the per-call revocation or the lifecycle arm of the up-front admission, so those were driven by hand.

Per-clause verdicts

item # clause (short) verdict evidence
ai.mcp-stdio-fail-closed 0 enabled + keyless refuses to serve pass exit 1; [MCP] The stdio transport is enabled (OS_MCP_STDIO_ENABLED / autoStart) but OS_MCP_STDIO_API_KEY is not set. … Refusing to start an unscoped stdio server (ADR-0101).; health probe after exit: connection refused
ai.mcp-stdio-fail-closed 1 unknown and lifecycle-refused keys rejected up front pass osk_unknown: exit 1, [MCP] OS_MCP_STDIO_API_KEY did not resolve to a valid identity (unknown / revoked / expired / owner-less). Refusing to start stdio (ADR-0101).; the key revoked in clause 6, restarted: exit 1, [MCP] OS_MCP_STDIO_API_KEY is refused (API_KEY_REVOKED): … Refusing to start stdio (ADR-0101).; neither process serves
ai.mcp-stdio-fail-closed 2 valid key binds a real principal, logged pass [MCP] stdio transport principal-bound to OS_MCP_STDIO_API_KEY identity (the contributor's user id) (RLS/FLS/tenant applied); the id equals the contributor's sys_user id
ai.mcp-stdio-fail-closed 3 MCP rows/fields equal the member's REST rows/fields; admin sees all pass RLS (contributor, showcase_invoice): MCP query_records and REST list both return exactly the contributor's own invoice, with identical field sets; get_record of INV-1003 (another owner) is an error on MCP and a 404 RECORD_NOT_FOUND on REST; the admin gets 13 rows including INV-1003 on both surfaces. FLS (client_liaison, showcase_project): MCP and REST both return 5 rows with identical ids and field sets, and budget / spent / budget_remaining are absent; the admin's rows carry budget
ai.mcp-stdio-fail-closed 4 member aggregate equals the member's REST aggregate, not the admin's pass count by status: MCP member [{status: draft, n: 1}] = REST member [{status: draft, n: 1}]; REST admin draft 3 / paid 5 / sent 5; MCP admin agrees with REST admin
ai.mcp-stdio-fail-closed 5 aggregate over an FLS-masked field fails closed pass as client_liaison: sum(budget), count grouped by budget and count_distinct(spent) each answer isError with PERMISSION_DENIED and [Security] Field read denied: not permitted to aggregate [budget] on 'showcase_project' (spent for the third); no number returned; REST sum(budget) 403 with the same message; control count by status: 4 groups
ai.mcp-stdio-fail-closed 6 revocation honored on the next call, fail-closed, API_KEY_REVOKED pass same live session: pre-revoke query_records returns 1 row; admin PATCH /api/v1/data/sys_api_key/KEY_ID {"revoked": true} 200; next query_records answers isError with content {"error": {"code": "API_KEY_REVOKED", "status": 403, "message": …}} and no records key; get_record likewise; REST with the same key 403 API_KEY_REVOKED
ai.mcp-stdio-fail-closed 7 stdio off: no key demanded pass neither variable set: Server is ready, and [MCP] Transport not auto-started (HTTP is served per-request at /api/v1/mcp regardless). …

Derived item verdict

ai.mcp-stdio-fail-closed r5: pass (8 of 8 clauses).

Fixture notes, not defects of this item:

  • showcase_invoice has no number field; its invoice number is name, and a create carrying number is refused 400 INVALID_FIELD.
  • An MCP client that writes initialize the moment it spawns os start gets a boot that never loaded the config. os start spawns serve with stdio inherited and no positional config argument, and the CLI's argument parser reads a pending stdin line as that argument. The boot then says No objectstack.config.ts found — booting from artifact (default host)…, the showcase boot exits 1, and the client's initialize is never answered. With objectstack.config.ts passed explicitly to serve and the same early write, the config loads. This run's client waited for the principal-bound line before writing, so no verdict above is affected. The defect is handed to the dispatching seat for its own card.

Timing: the build was shared across this re-run's five records (pnpm build 8m19s under the verify lock). This item took about 5 minutes: 1 minute of provisioning boot and 4 minutes of legs.

Checklist-accuracy findings, if any, close out on the wave anchor #23878; nothing is extracted from this record by its runner (the early-write defect above goes to the dispatching seat).

Activity

  1. objectstack-fleet commented on Oct 17, 2026

    @objectstack-fleet
    ContributorAuthor

    Close-out (domain:devx seat 2): every clause PASS; nothing to extract. The re-pointed item landed with #24000 (e18b23fac5), Fixes #23950.


    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