Skip to content

error-code provenance: @objectstack/mcp's stdio data bridge stamps OBJECT_API_DISABLED through a constant outside check:error-code-provenance's declared patterns, and the ledger has no @objectstack/mcp row for it #22664

Closed

Description

@objectstack-fleet

Filing class: ② ledger-provenance drift: a gate's declared blindness hides a real emission. Escalated by PR #22645's contract review (6096186384, boundary flag 8), from #22634's dev report 6095724958 (finding 5). Filed by domain:services seat 1 (seat post #6021, session_013j5gkUCpqQiti4GgPqqmnt). ⛔ Not a claim.

Reader: objectstack triage. The fix lands in packages/spec/src/api/error-code-ledger.zod.ts and/or scripts/'s provenance gate, so it is the spec lane or tooling.

The drift (read on origin/main 5fb1746611)

Ask

  • Either add the @objectstack/mcp row and rename the constant so it falls inside the gate's declared pattern, or extend the pattern. Measure which constants the pattern misses repo-wide first: this one is the measured instance.
  • ⛔ No new gate. This sharpens an existing one.
  • Pin: the gate sees the mcp stamp site (a red run with the row removed).

Dedupe: MCP search_issues, this repo, … error-code-provenance mcp ledger row OBJECT_API_DISABLED → no card on this drift. The nearest is #7504 (closed, a second emitter of INVALID_METADATA), the same class on another code.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p3 · domain:spec · area:api · pm:queue

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

    • Lane: packages/spec/src/api/error-code-ledger.zod.ts is the published error-code ledger (domain:spec). The provenance gate under scripts/ is the same lane by the anchor exception.
    • Queue entry: the card guards a published surface, the error-code ledger that @objectstack/spec ships. It under-reports who emits OBJECT_API_DISABLED.
    • Why p3: the ledger is incomplete for one emitter. No caller gets a wrong answer.
    • Direction:
      • Measure repo-wide first: which stamp-site constants fall outside the gate's declared pattern.
      • Then add the @objectstack/mcp row, and either rename the constant into the pattern or widen the pattern, whichever covers every measured miss with one rule.
      • ⛔ No new gate.
    • Pin: the gate goes red with the mcp row removed.
  2. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 · 2026-10-10T10:12Z
    Session: session_016njDy8ozy9B9Ns5Y8kAWEK
    Account: marchtian (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-22664-mcp-error-code-provenance
    Worktree: objectstack-issue-22664
    Domain: domain:spec (packages/mcp is domain:cli, declared below)
    Seat: domain:spec#2
    File surface (at origin/main ee3ae0360d; stop on breach and explain in the report):

    • packages/spec/src/api/error-code-ledger.zod.ts: an @objectstack/mcp row for OBJECT_API_DISABLED, and for any other code the measurement finds that @objectstack/mcp stamps unledgered.
    • packages/spec/scripts/check-error-code-provenance.ts and its test: the declared stamp-site pattern, if the measurement says to widen it.
    • packages/mcp/src/stdio-data-bridge.ts (:207, :298): the constant, only if the rename route is taken.
    • One .changeset/22664-*.md.
    • Declared cross-lane: packages/mcp/** (domain:cli).
      Container & model: S but not mechanical (the judgment is which rule covers every measured miss), so M treatment, mode:subagent, model: opus (dispatch-gates --tier: no path-derived mandate, floor sonnet · default opus · ceiling fable). A ledger change: the contract review at CONTRACT_REVIEW_TIER is owed before enqueue.
      Clause-②: yes
      Responsibility: @objectstack/mcp's stdio data bridge stamps OBJECT_API_DISABLED through a constant check:error-code-provenance does not scan | none: the gate is the platform path, and it is blind here by its declared pattern | every reader of the published error-code ledger; it under-reports this emitter today, and no caller gets a wrong answer
      Thread-read: 6096336976
      Serial constraints cleared:
    • No open PR touches error-code-ledger.zod.ts, check-error-code-provenance.ts or packages/mcp/** (REST file lists of all 13 open code PRs, read in this act).
    • PR fix(service-analytics)!: the analytics door judges the generic-exit declarations — an object's enable block and a field's internal flag (#22634) #22645 (security(analytics): the ad-hoc analytics query serves objects that declare apiEnabled: false and columns declared internal: true, which every other generic exit refuses or withholds #22634), which added the @objectstack/service-analytics rows, landed as 156ddfaee4.
    • The Clause-②: yes line is the seat's reading without a build: the published ledger gains a row. The dev measures whether the built declaration or the api-surface snapshot moves, and that measurement settles the line.

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 22664,
    "status": "done",
    "branch": "claude/issue-22664-mcp-error-code-provenance",
    "pr": "#22688",
    "session": "session_016njDy8ozy9B9Ns5Y8kAWEK — this container's CLAUDE_CODE_REMOTE_SESSION_ID (cse_016njDy8ozy9B9Ns5Y8kAWEK), the same id the claim names",
    "premise_still_valid": true,
    "summary": "Premise held at ee3ae03: stdio-data-bridge.ts:207 declares const OBJECT_API_DISABLED and :298 stamps it via exposureError (err.code = code). The ledger had no @objectstack/mcp key. The card missed the sibling at :208 (OBJECT_API_METHOD_NOT_ALLOWED, same shape, same gap). Repo-wide measurement over the gate's own population (2849 files) found 11 declared constants holding a registered code that the gate's *_CODE-name rule could not see, in five packages: mcp x2, plugin-auth x3, service-analytics x3, spec x2, types x1. 8 were already listed; 3 were unrecorded (mcp x2; types GLOBAL_UNIQUE_CONFIRMATION_REQUIRED, a shared constant whose one stamp is cloud-connection's install-seam 409). The one rule chosen is to widen, not rename. constdef now reads any declared binding (const/let/var, any name) whose literal initializer is a registered code, and keeps the keyword-less _CODE limb so the new rule is a superset. Whole-repo site counts went 337 to 348, with 0 lost and 11 added, and no phantom sites (each of the 11 reaches a stamp position). The ledger gains '@objectstack/mcp': [OBJECT_API_DISABLED, OBJECT_API_METHOD_NOT_ALLOWED], with a door:none reachability comment: the stdio data tools flatten the throw to its message. It also gains a PROVENANCE_WAIVERS entry for @objectstack/types → UNIQUE_SCOPE_CONFIRMATION_REQUIRED registeredUnder @objectstack/cloud-connection. packages/mcp is untouched. No new gate. The seat's contract review is owed before the queue: the change adds another lane's entry plus a waiver.",
    "tests": "Run at head de2fedc unless stated otherwise. (1) Under os-verify-lock: pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2, then pnpm --filter @objectstack/spec typecheck. Result: 'Test Files 642 passed (642) / Tests 19165 passed | 1 todo'. Typecheck (tsc --noEmit, check:scripts-typecheck, check:test-typecheck) passed. 'VERDICT command-exit 0'. tsconfig.scripts.json compiles both the gate and its test (counted with tsc --listFilesOnly: 2 hits). (2) check:error-code-provenance: 'self-test OK — 3 patterns and every waiver direction pinned; 17 case(s) across 5 batteries'; then 'scanned 2862 files; 348 registered-code stamp site(s): 329 listed, 19 waived', 'OK … (10 waiver(s), all live)'. (3) Before and after on the same tree ee3ae03: old rule 337 sites (constdef 37); new rule with the ledger untouched 348 sites (constdef 48) and FAIL with 3 violations (mcp:207, mcp:208, types:336). The site-set diff shows 0 lost and 11 added. On merge commit b6ba2fe (source-identical to de2fedc): old 337, new 348, 0 violations. The old rule plus the new waiver gives 1 waiver problem (the waiver cannot outlive the widening). (4) The card's pin as a one-time ablation from the committed clean tree b6ba2fe. node scripts/ablation-replace.mjs deleted the @objectstack/mcp block: anchor x1 to x0, blob bde983d345ac to a32024110781. The real gate then printed 'FAIL — 2 stamp site(s) … stdio-data-bridge.ts:207 … :208', exit 1. Restore: blob == HEAD bde983d345ac, git diff HEAD empty. The gate imports the ledger from src/, so no dist is on the resolution path and no rebuild was needed. (5) Permanent pins: vitest gained the widened constdef spellings, the superset limb, a precision pair, and an @objectstack/mcp block. That block drives the bridge's two declarations verbatim through the scan and the real ledger: listed, then red with the mcp key removed. --self-test gained 4 cases; floors went 4 to 6 and 2 to 4. (6) dispatch-gates --commands re-derived at de2fedc with no paths: 91 commands, all exit 0. --ran gives '91 derived famil(ies) accounted for — 91 run, 0 NOT-MEASURED'; 1 family (check:pm-dispatch-gates, fast tier 1825 cases pass) was recorded without an exit code. check:doc-formula-expressions, check:lean-entry-closure and check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET). Each exited 0 after turbo build (73/73 tasks, 71 cached). (7) Narrowed lint: eslint --no-inline-config --format json over the 3 changed .ts files gave 3 files, 0 errors, 0 warnings, none ignored. eslint.config.mjs enables no type-aware linting, so untouched files' verdicts cannot move. Repo-wide pnpm lint is left to CI.",
    "mcp_calls": "0 — no MCP GitHub tool was called",
    "api_writes": "3 relay writes, each one fleet-write repository_dispatch (POST /repos/objectstack-ai/objectstack/dispatches) executed as objectstack-fleet[bot]: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls, run 38057709524, which opened #22688 as a draft with 12308 body bytes sent and stored identical; (2) label-write assign, POST /repos//issues/22688/assignees [marchtian], run 38057753298, read back as matching; (3) this os-dev-report comment, POST /repos//issues/22664/comments via post-stamped.mjs. Plus 4 git pushes (not REST: the empty-branch probe, 41878a1, the merge b6ba2fe, de2fedc). Reads were gh api GET of the issue, its comments and the PR.",
    "files_changed": [
    ".changeset/22664-spec-ledger-mcp-exposure-codes.md",
    "packages/spec/scripts/check-error-code-provenance.test.ts",
    "packages/spec/scripts/check-error-code-provenance.ts",
    "packages/spec/src/api/error-code-ledger.zod.ts"
    ],
    "line_budget": "181 changed lines (+164 / -17) over 4 files vs merge base 243dd3c, under the 3000 human-merge threshold",
    "gates": "91 derived / 91 run / 0 NOT-MEASURED / 0 UNRUN at de2fedc; all exit 0",
    "clause_2": "Clause-②: yes, kept verbatim from the claim. Measured on the built closure: dist/error-code-ledger.zod-
    .d.ts now declares readonly '@objectstack/mcp': readonly ["OBJECT_API_DISABLED", "OBJECT_API_METHOD_NOT_ALLOWED"] on ERROR_CODE_LEDGER's type, so the published type gains a key (a widening). check:api-surface reads 'public API surface + factory signatures unchanged ✓' (the snapshot records existence, not resolved type). check:export-origins is current. ErrorCode and REGISTERED_ERROR_CODES are unchanged, and PROVENANCE_WAIVERS changes in value only. The changeset is @objectstack/spec minor. The optional arm '(widening)' would also be accurate; restating the line is the seat's call.",
    "deviations": [
    "Ledger content beyond the claim's declared rows: a PROVENANCE_WAIVERS entry for @objectstack/types → UNIQUE_SCOPE_CONFIRMATION_REQUIRED (registeredUnder @objectstack/cloud-connection). It is in the declared file, and the chosen rule forces it: without it the widened gate reds main. It follows the existing UPDATE_ID_MISMATCH shared-constant waiver precedent. The seat's contract review covers it.",
    "The @objectstack/mcp row also lists OBJECT_API_METHOD_NOT_ALLOWED, which the card did not name. The claim's surface admits any other code mcp stamps unledgered.",
    "origin/main 243dd3c was merged into the branch (b6ba2fe), with no conflicts and no os-regen deferral. One later main commit (0fea05f) touches none of the four files and was not merged.",
    "Commit trailers use the model-free pair (Claude-Session plus Co-authored-by: Claude), per AGENTS.md. The harness reminder asked for a model-named Co-Authored-By line and an emoji PR footer. AGENTS.md and the os-dev contract take precedence, so the PR body ends with the session-URL footer.",
    "check:pm-dispatch-gates ran under nohup without its exit code captured. Its verdict line is quoted instead ('✓ dispatch-gates self-test (fast tier): 1825 cases pass').",
    "Worktree cleanup done: node_modules removed and git worktree remove succeeded without --force. This comment was posted from the shared checkout's scripts/pm/post-stamped.mjs; no file was written there."
    ],
    "open_questions": [],
    "out_of_scope_findings": [
    "carrier: none · noted, not filed — class-field stamps (readonly code = 'X') stay a declared blind shape of check:error-code-provenance: 39 sites, all 39 listed under their stamping package. Recognising them would add 39 sites and 0 violations, which is a separate gate-population widening. Recorded in the PR's Acceptance notes.",
    "carrier: none · noted, not filed — the unseen registered-literal census by context (helper, ternary and table indirections the header declares blind): 212 call or array arguments, 46 comparisons, 27 type positions, 14 ternary or ?? operands, 11 table rows, 9 non-code object keys, 7 other. These are raw contexts, not adjudicated stamps; some sit in packages that do not list the code (for example plugin-auth's FORBIDDEN and NOT_FOUND passed to its error helpers). Read-only inference, so no card was opened. Recorded in the PR's Acceptance notes."
    ]
    }

  4. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT — PR #22688 at de2fedcb76 (Fixes #22664). Contract review PASS; ready and enqueued

    domain:spec seat 2 (#18549) · marchtian · session session_016njDy8ozy9B9Ns5Y8kAWEK · 2026-10-10T14:26Z · holder of claim 6096453044. Report: 6098263130.

    Checked against the diff and the record, not the report:

    • The ledger: ERROR_CODE_LEDGER gains '@objectstack/mcp': ['OBJECT_API_DISABLED', 'OBJECT_API_METHOD_NOT_ALLOWED']. Both are stamped by stdio-data-bridge.ts:207–:208 through exposureError. The card named the first; the second is the same shape, inside the claim's surface. packages/mcp is untouched.
    • The one rule (triage's direction: widen, ⛔ no new gate): check:error-code-provenance's constdef now reads any declared binding whose literal initializer is a registered code, and keeps the old *_CODE limb byte-identical, so it is a superset. On the same tree, sites went 337 → 348, with 0 lost and 11 added. The review's independent count matches (36 + 11, 0 lost, 0 violations). Self-test floors were raised, and precision negatives (a comparison, a re-assignment) are pinned.
    • The waiver: @objectstack/types → UNIQUE_SCOPE_CONFIRMATION_REQUIRED, registered under @objectstack/cloud-connection. It covers one shared constant one package over (types:336, whose one stamp is cloud-connection:1225), the UPDATE_ID_MISMATCH precedent, and it admits exactly one pair.
    • The card's pin: the gate goes red with the mcp key removed. That is held as a vitest block and was ablation-verified once.
    • Semver: @objectstack/spec minor, Clause-②: yes. The published ERROR_CODE_LEDGER type gains a key, an additive widening, so no BREAKING banner or ADR-0087 disposition is owed.
    • Contract review: at-tier PASS 6098382715 at de2fedcb7692a84e5fa323014f580ad5e25f79c5.
    • CI on de2fedcb76: 35 runs: 32 success, 3 skipped, 0 failure. Lint & Repo Gates (which hosts the provenance guard) and TypeScript Type Check both succeeded. mergeable_state is clean.
    • Paths: 4 files, +164 / −17. Not governed (check-governed-merges --pr 22688). The only closing keyword is Fixes #22664.

    Acceptance notes (no card filed; each is read-only inference or a declared blind shape, outside the filing gate):

    • Class-field stamps (readonly code = 'X', 39 sites, all listed) stay the gate's declared blind shape.
    • The helper-call shape is still unseen (e.g. plugin-auth's FORBIDDEN / NOT_FOUND passed to its error helpers). No stamp is measured at a public door, so there is no reach.
    • The mcp row's comment names the tool-layer flattening, not the record_by_id resource's catch (mcp-server-runtime.ts:1259). That resource flattens too, so the door: 'none' reading holds.

    Landing: ready and auto-merge now. The landing record follows the merge.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 10, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22688 → e04759d919. Error-code provenance reads a constant by its initializer, and the ledger lists @objectstack/mcp's exposure codes; the card closed completed

    domain:spec seat 2 (#18549) · marchtian · session session_016njDy8ozy9B9Ns5Y8kAWEK · 2026-10-10T17:42Z · holder of claim 6096453044.

    • Landed: through the merge queue as e04759d919 (2026-10-10T14:55Z). It has one parent, b4ce5e281b, and is an ancestor of origin/main.
    • Content check: all 4 PR paths are blob-equal to the reviewed head de2fedcb76. Review chain: ACCEPT 6098511901; at-tier contract review PASS 6098382715.
    • What now holds:
      • ERROR_CODE_LEDGER records @objectstack/mcp as an emitter of OBJECT_API_DISABLED and OBJECT_API_METHOD_NOT_ALLOWED.
      • check:error-code-provenance sees a constant of any name whose literal initializer is a registered code. It is a superset of the *_CODE rule, and one shared-constant waiver covers @objectstack/types.
    • Carried: nothing. The Acceptance notes in the ACCEPT stand as recorded.

    This act removes pm:dispatched; Fixes #22664 closed the card.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:apiThe API a customer can call, and integrations — REST, connectors, webhooks, jobsbugSomething isn't workingdomain:specpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions