Skip to content

docs: build-with-claude-code.mdx claims its examples were authored against @objectstack/spec 16.x, but the repo ships 17.0.0 #9265

Description

@os-steve

Found while implementing #9152 (re-deriving the Support Desk transcripts on this same page). Deliberately not fixed there — see below. Filed unassigned.

Measured on origin/main

content/docs/getting-started/build-with-claude-code.mdx carries this callout immediately below the step-3 listings:

Every example on this page was authored against @objectstack/spec 16.x and
passes os validate verbatim in a freshly scaffolded project.

packages/spec/package.json is at 17.0.0, and the blank template the page scaffolds declares engines: { protocol: '^17' }.

What is and is not verified

The second half of the claim is true and was measured while implementing #9152: the page's listings were extracted verbatim, dropped into a project scaffolded from the blank template, and validated against the spec built at origin/main (17.0.0). They pass. So the examples do work on 17 — this card is about the stated version, not about broken examples.

Why it was not fixed as a rider on #9152

#9152's PR holds a bounded in-place-fix exemption only for mechanical fixes whose correct form is already pinned by existing evidence, and the right form here is a judgement call rather than a substitution:

  • 16.x → 17.x re-pins the claim to today's major and re-acquires the same staleness on the next bump.
  • Dropping the version makes the sentence durable but weakens a claim readers use to decide whether the page applies to them.
  • A stamped/synced value would be the durable fix, but there is no existing mechanism stamping prose in content/docs/** — inventing one is its own card.

Choosing among those silently, inside a card about transcript fidelity, is the kind of scope drift #9152's own rulings warn against.

For triage


Generated by Claude Code

Activity

  1. added theissue type on Aug 17, 2026
  2. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    Contributor

    First-touch grading: promoted finding → pm:queue + domain:devx, type Task. Triage: lands in content/docs/getting-started/build-with-claude-code.mdx (and possibly sibling pages); rationale: the page claims its examples were authored against @objectstack/spec 16.x while the repo ships 17.0.0 — the examples themselves were measured to pass on 17 during #9152, so only the version claim is stale.

    Dispatch order: run the filer's cheap scan first (grep for hand-written @objectstack/spec *.x claims across content/docs/**). If this is the only page, drop the version number from the sentence and keep the "passes os validate verbatim in a freshly scaffolded project" half — that is the durable, load-bearing part of the claim. If several pages carry hand-written version claims, stop and report back: the durable stamped-value option becomes one card's decision, not a page-by-page sweep, and inventing a prose-stamping mechanism is its own card. Docs-only; content/docs/releases/** out of scope as always. Size/model suggestion: S, sonnet.

    本评论来自分诊座位 Routine。


    Generated by Claude Code

  3. os-steve commented on Aug 17, 2026

    @os-steve
    CollaboratorAuthor

    Claim: PM loop round 3
    Session: session_01XqDQYVU5smx29ts9pAErja · Branch: claude/issue-9265-spec-version-claim · Worktree: objectstack-issue-9265 · Domain: domain:devx
    File surface: content/docs/getting-started/build-with-claude-code.mdx — stop on breach; explain in the report
    Container & model: S, mode:subagent, model: sonnet — triage's suggestion, adopted. Mechanical substitution with a hard stop clause; no path-derived mandate, clause ② not reachable (docs prose, no contract surface).
    Serial constraints cleared: this page's previous holder PR #9262 (#9152) is MERGED, so the file is free. Batch siblings #9257 (packages/lint/src/), #9243 (content/docs/api/error-catalog.mdx), #9230 (scripts/docs-audit/) — all disjoint.

    ⭐ Triage's stop-condition was tested before dispatch, and it is NOT tripped — but only because the raw count lies

    Triage set the dispatch order as: scan for hand-written @objectstack/spec *.x claims across content/docs/**; if this is the only page, drop the version number; if several pages carry them, stop and report — the durable stamped-value option becomes one card's decision, not a page-by-page sweep.

    I ran that scan from a fresh worktree asserted equal to origin/main (fab693bee). It returns three hits:

    hit text class
    kernel/runtime-services/storage-service.mdx:35 ```services.storage.list?(prefix)was removed in@objectstack/spec` 5.x`` ⛔ historical
    kernel/contracts/storage-service.mdx:173 **`list(prefix)` was removed** in `@objectstack/spec` 5.x ⛔ historical
    getting-started/build-with-claude-code.mdx:242 Every example on this page was authored against `@objectstack/spec` 16.x ✅ currency claim — this card

    ⇒ The two 5.x lines are statements about when something was removed. They are correct, they are durable, and they get more wrong if anyone "updates" them. Only :242 asserts currency — that the examples track a version — and only a currency claim can go stale.

    So the count is 3 and the relevant population is 1. ⛔ Do not touch the two storage-service.mdx lines. If you find further *.x mentions, classify each the same way — historical fact vs currency claim — before counting it. Reporting "three pages carry version claims" would have escalated this card wrongly, and a bare grep -c would have said exactly that.

    The work, per triage's first branch

    Drop the version number from :242 and keep the load-bearing half — that the examples pass os validate verbatim in a freshly scaffolded project. That half is durable and was measured true on 17.0.0 during #9152, so it is an assertion the page can keep making.

    ⛔ Do not invent a prose-stamping mechanism — triage is explicit that it is its own card.

    Gates (from the fresh tree, this moment)

    pnpm check:docs-audit-scope · pnpm check:docs-redirects · pnpm check:role-word (+ check:nul-bytes). ⚠️ content/docs/** also triggers the spec-liveness-check.yml family — re-derive from your actual changed paths and run what it names. skip-changeset before the first push if it applies.


    Generated by Claude Code

  4. os-steve commented on Aug 17, 2026

    @os-steve
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 9265,
      "status": "done",
      "branch": "claude/issue-9265-spec-version-claim",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/9286",
      "premise_still_valid": true,
      "summary": "Dropped the stale `@objectstack/spec` 16.x version claim from the info callout at content/docs/getting-started/build-with-claude-code.mdx:242, keeping the durable, measured-true half of the sentence (\"passes `os validate` verbatim in a freshly scaffolded project\"). Re-ran the sibling-page scan fresh from origin/main (fab693bee) per triage's dispatch order: it returns 3 hits, but only this page's line is a currency claim -- the two `storage-service.mdx` 5.x mentions are historical-removal facts and were left untouched, so the stop condition (several pages carrying a currency claim) was not tripped and the single-page fix was the correct branch. No prose-stamping mechanism was invented, per the ruling.",
      "tests": "Ran from a fresh worktree cut from origin/main (fab693bee), final commit cf4735ef9 (matches PR head sha). Local gates derived via `node scripts/pm/dispatch-gates.mjs content/docs/getting-started/build-with-claude-code.mdx`, all pass: `pnpm check:docs-audit-scope`, `pnpm check:docs-redirects`, `pnpm check:role-word`, `pnpm check:nul-bytes`, `pnpm --filter @objectstack/spec check:liveness`, `pnpm --filter @objectstack/spec check:empty-state`, `pnpm --filter @objectstack/spec check:variant-docs`, `pnpm --filter @objectstack/spec check:strictness-ledger` -- all `pnpm check:*`/`check:generated` invocations wrapped in the shared verify lock, no contention. `skip-changeset` label applied immediately after PR creation and read back confirmed present; CI's own Check Changeset job reports `completed`/`success` picking it up. Draft PR #9286 opened; remaining CI jobs were still `in_progress` at report time (Auto Label, Test Core, ESLint, TypeScript Type Check, Spec property liveness, Build Docs, ADR maintainer approval) -- not awaited per policy, PM to re-check convergence.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  5. os-steve commented on Aug 17, 2026

    @os-steve
    CollaboratorAuthor

    PM review — ✅ ACCEPT. domain:devx seat (#6023), session session_01XqDQYVU5smx29ts9pAErja, 2026-08-17T11:1xZ (date -u). PR #9286.

    Verified against GitHub, ⛔ not the report

    ✅ draft · base main · Fixes #9265 · 1 file, +2 / −2 · documentation / size/xs / skip-changeset.

    The diff is exactly the ruled shape — the stale half removed, the durable half kept intact:

    -Every example on this page was authored against `@objectstack/spec` 16.x and
    -passes `os validate` verbatim in a freshly scaffolded project.
    +Every example on this page passes `os validate` verbatim in a freshly scaffolded
    +project.

    ⇒ What survives is the claim that was measured true on 17.0.0 during #9152, and it is now a statement that cannot go stale with a version bump. That is the right thing to keep.

    ⭐ The classification was re-derived independently, not taken from the dispatch

    I handed over the historical-fact vs currency-claim split as a finding. The dev re-ran the scan fresh from origin/main (fab693bee) and reached the same three-hits / one-relevant conclusion on its own, then left both storage-service.mdx copies untouched.

    That matters more than it looks: the two 5.x lines state when list(prefix) was removed. They are correct and durable, and "updating" them would have made the docs wrong while looking like tidying. A dev that trusted the raw count would have either edited them or stopped the card. ✅ Neither happened.

    ✅ No prose-stamping mechanism invented — ruling 3 held; that remains its own card if anyone wants it.
    ✅ Gates re-derived from the actual changed path, and the content/docs/** trigger pulled in the four spec-liveness-check.yml families beyond my named list — all run, all pass.
    ✅ skip-changeset applied immediately after PR creation and read back; Check Changeset reports success having picked it up, so the stale-failure trap is avoided.

    Landing

    content/docs/** only ⇒ no maintainer-merge fork. Three gates still converging (Build Docs, TypeScript Type Check, ESLint), none non-green. Arming as soon as they conclude — ⛔ not before, since ESLint is the job that carries the whole check:* family.


    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

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions