Skip to content

create-objectstack rewrites the manifest id/namespace/name but not description, so every scaffolded project describes itself as the blank template #9263

Closed

Description

@os-steve

Found while implementing #9152 (re-deriving the Support Desk clean-run transcripts from a real run). Out of that card's scope — #9152 is docs-only and this is scaffolder behaviour. Filed unassigned.

Measured

Scaffolding with the CLI and scaffolder built at origin/main:

node packages/create-objectstack/dist/index.js support-desk --template blank --skip-install --skip-skills

produces an objectstack.config.ts whose manifest reads:

manifest: {
  id: 'support-desk',
  namespace: 'support_desk',
  version: '0.1.0',
  type: 'app',
  name: 'Support Desk',
  description: 'Minimal ObjectStack environment — a clean slate for building.',
  ...
}

id, namespace and name were all rewritten from the project name. description was not — it is still the blank template's own copy. Every command that prints the manifest surfaces it, e.g. os validate:

  Support Desk v0.1.0
  Minimal ObjectStack environment — a clean slate for building.

Where

rewriteProjectIdentity in packages/create-objectstack/src/index.ts rewrites three keys in objectstack.config.ts:

cfg = cfg.replace(/(\bid:\s*)(['"`])[^'"`]*\2/, ...)
cfg = cfg.replace(/(\bnamespace:\s*)(['"`])[^'"`]*\2/, ...)
cfg = cfg.replace(/(\bname:\s*)(['"`])[^'"`]*\2/, ...)

and for objectstack.manifest.json sets .name, .displayName, .namespace. description is in neither list.

Why it is worth fixing rather than tolerating

The line is user-visible on the first command the getting-started flow tells people to run, and it is confidently wrong rather than empty — a support desk that introduces itself as "a clean slate for building" reads as a bug in the reader's own project. It is also the kind of stale metadata an AI agent will faithfully preserve, since nothing marks it as a placeholder.

For triage


Generated by Claude Code

Activity

  1. added
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    and removed on Aug 17, 2026
  2. added theissue type on Aug 17, 2026
  3. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    Contributor

    First-touch grading: promoted finding → pm:queue + domain:cli, type Bug. Triage: lands in packages/create-objectstack/src/index.ts (rewriteProjectIdentity); rationale: the scaffolder rewrites id/namespace/name but leaves the blank template's description, so every scaffolded project misdescribes itself on the first command the getting-started flow runs — user-visible and confidently wrong, and exactly the stale metadata an AI agent will faithfully preserve.

    Suggested route (executing seat/dev to confirm): derive the description from the project name, mirroring the name rewrite — keeps the manifest line present and correct for both objectstack.config.ts and objectstack.manifest.json. Dropping the key is acceptable too (the CLI already omits the line when unset); leaving it and marking it a placeholder keeps a wrong sentence on screen and is not recommended. Carry the recorded coupling: #9152's transcript page needs a same-run update when this lands. Size/model suggestion: S, sonnet.

    本评论来自分诊座位 Routine。


    Generated by Claude Code

  4. claude commented on Aug 17, 2026

    @claude
    Contributor

    Claim: PM loop round 1
    Session: session_012WKSnqAaoqtW3QX7SSf1Vk
    Branch: claude/issue-9263-scaffold-manifest-description
    Worktree: objectstack-issue-9263
    Domain: domain:cli
    File surface: packages/create-objectstack/src/index.ts (+ its sibling tests) (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: sonnet — --tier reports no path-derived mandate; the one design fork is ruled below, which leaves a mechanical change verified by an assertion. Clause ② not reachable from content.
    Serial constraints cleared: packages/create-objectstack is free — no in-flight card touches it (#9017, the last one, is closed). ⚠️ #9264 is deliberately held back this round: it lands in the same package (templates/blank/objectstack.manifest.json + scripts/sync-template-versions.mjs) and the standing same-package serialization rule applies — it goes out only after this one lands. No same-day churn: last touch 445ae4d (2026-08-16).

    Premise re-verified on origin/main @ 68cd4e7 before dispatch: rewriteProjectIdentity is at index.ts:132, called at index.ts:345, and rewrites id / namespace / name only — description is in neither the config regex list nor the manifest-json key list. The card is accurate.

    ⚠️ Coupling now live: #9152 (the docs card whose transcript quotes the wrong description line verbatim) is closed/landed. So the transcript is on main today showing the blank-template sentence, and this fix invalidates it. That is a domain:devx surface, so it is a follow-up card at ACCEPT time, not an in-scope edit here.

    Generated by Claude Code


    Generated by Claude Code

  5. added a commit that references this issue on Aug 17, 2026
    11d36cd
  6. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    Contributor

    <!-- os-dev-report -->
    {
    "issue": 9263,
    "status": "done",
    "branch": "claude/issue-9263-scaffold-manifest-description",
    "pr": "#9335",
    "premise_still_valid": true,
    "summary": "rewriteProjectIdentity in packages/create-objectstack/src/index.ts now drops manifest.description from both objectstack.manifest.json (delete m.description) and objectstack.config.ts (new line-anchored regex) instead of leaving the blank template's own placeholder text in place. Measured the two Zone 1 landings against a real scaffold run: since the only scaffold-time input is the project name, any name-derived description would be a bare restatement of the name/displayName row, so chose (b) omit-entirely over (a) derive. Confirmed os validate (packages/cli/src/commands/validate.ts) already omits the description line when the field is absent, and that description is .optional() on both the runtime manifest schema and the template-manifest schema.",
    "tests": "Repo HEAD after final push: 11d36cd (short sha, matches PR head). All commands run from /home/user/objectstack-issue-9263 (worktree) unless noted.\n\n1. Reproduced defect pre-fix via node packages/create-objectstack/dist/index.js support-desk --template blank --skip-install --skip-skills (built dist) -> objectstack.config.ts and objectstack.manifest.json both carried the blank template's description verbatim -- matches issue body exactly.\n\n2. Post-fix smoke test via tsx (no-build, same pattern as packages/spec/scripts/dist-freshness.test.ts): node_modules/.bin/tsx packages/create-objectstack/src/index.ts smoke-app --template blank --skip-install --skip-skills -> objectstack.config.ts has no description: line, objectstack.manifest.json has no description key; id/namespace/name rewrites still present and correct.\n\n3. New test file packages/create-objectstack/src/scaffold-description.test.ts (4 tests: manifest.json drop, config.ts drop, id/namespace/name rewrite unregressed, config.ts still parses via ts.transpileModule syntactic check). pnpm vitest run src/scaffold-description.test.ts --maxWorkers=2 -> 'Test Files 1 passed (1) / Tests 4 passed (4)'.\n\n4. Full package suite: pnpm vitest run --maxWorkers=2 in packages/create-objectstack -> 'Test Files 5 passed (5) / Tests 62 passed (62)' (no regression in rewrite-identity.test.ts, runtime-image.test.ts, template-consistency.test.ts, template-registry.test.ts).\n\n5. pnpm typecheck in packages/create-objectstack -> exit 0 (ran under flock, backgrounded past 120s tool timeout, completed exit code 0 per task notification).\n\n6. npx eslint packages/create-objectstack/src/index.ts packages/create-objectstack/src/scaffold-description.test.ts --no-inline-config -> no output, exit 0 (clean).\n\n7. Gate named in dispatch prompt: node scripts/docs-audit/check-affected-docs.mjs -> '(check-affected-docs self-test: 115 cases pass)'. Also ran the real advisory mapper it wraps, node scripts/docs-audit/affected-docs.mjs --json origin/main (post-commit) -> 'docs: []' (0 hand-written docs flagged as affected; anchor derived was rewriteProjectIdentity, matched no doc).\n\n8. Re-derived gates against actual changed paths: node scripts/pm/dispatch-gates.mjs packages/create-objectstack/src/index.ts packages/create-objectstack/src/scaffold-description.test.ts .changeset/create-objectstack-drop-stale-description.md -> same docs-audit match, plus convention-triggered gates for 'adds or edits a test file': check:query-options-erasure, check:type-check-coverage, check:type-check-debt, check:engine-double-contract, check:where-matcher.\n - check:query-options-erasure: node scripts/check-query-options-erasure-ratchet.mjs --self-test && node scripts/check-query-options-erasure-ratchet.mjs -> 'ratchet holds: 67 unswept ... none new ... baseline key set verified against df04324: no files added.'\n - check:engine-double-contract: node scripts/check-engine-double-contract.mjs --self-test && node scripts/check-engine-double-contract.mjs -> 'OK -- 315 pinned, 133 in the DEBT ledger, 2 exempt' (unaffected -- new test has no engine doubles).\n - check:where-matcher: node scripts/check-where-matcher-conformance.mjs --self-test && node scripts/check-where-matcher-conformance.mjs -> '252 matcher(s) discovered, 252 answer ... correctly or refuse it loudly ... none new.' (unaffected -- new test has no WHERE matchers).\n - check:type-check-coverage (structural half): node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs -> 'OK -- 64/77 workspace packages type-checked ... 13 in the DEBT ledger ... 1 exempt' -- create-objectstack is in the clean 64, not the 13-package DEBT/exempt ledgers (grepped scripts/.json for 'create-objectstack': no hits), and its own pnpm typecheck already passed with the new test file present, so the structural half fully covers this change.\n - check:type-check-debt (re-measure half): NOT run. It refuses outright without a full build of all 55 workspace packages ('--re-measure cannot run: 55 workspace dependenc(ies) ... have no built type entry point on disk'), and create-objectstack has zero @objectstack/ workspace dependencies and is not itself in the DEBT ledger -- re-measuring 55 unrelated packages' frozen error counts to validate a 3-file leaf-package change was judged disproportionate given the local-verification-scope guidance (CI runs the real farm once regardless). Flagging this explicitly rather than silently skipping.\n\n9. node scripts/check-nul-bytes.mjs --self-test && node scripts/check-nul-bytes.mjs (any-edit gate) -> 'OK (scanned 6071 text file(s) ... no raw ASCII control bytes)'.\n\n10. Changeset validity: npx changeset status --since=origin/main lists create-objectstack under 'Packages to be bumped at patch' with no errors -- confirms .changeset/create-objectstack-drop-stale-description.md parses correctly.",
    "open_questions": [],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  7. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    Contributor

    test marker survival probe — ignore, superseded by the next comment


    Generated by Claude Code

  8. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    Contributor

    {
    "issue": 9263,
    "status": "done",
    "branch": "claude/issue-9263-scaffold-manifest-description",
    "pr": "#9335",
    "premise_still_valid": true,
    "summary": "rewriteProjectIdentity in packages/create-objectstack/src/index.ts now drops manifest.description from both objectstack.manifest.json (delete m.description) and objectstack.config.ts (new line-anchored regex) instead of leaving the blank template's own placeholder text in place. Measured the two Zone 1 landings against a real scaffold run: since the only scaffold-time input is the project name, any name-derived description would be a bare restatement of the name/displayName row, so chose (b) omit-entirely over (a) derive. Confirmed os validate (packages/cli/src/commands/validate.ts) already omits the description line when the field is absent, and that description is .optional() on both the runtime manifest schema and the template-manifest schema.",
    "tests": "Repo HEAD after final push: 11d36cd (short sha, matches PR head). All commands run from /home/user/objectstack-issue-9263 (worktree) unless noted.\n\n1. Reproduced defect pre-fix via node packages/create-objectstack/dist/index.js support-desk --template blank --skip-install --skip-skills (built dist) -> objectstack.config.ts and objectstack.manifest.json both carried the blank template's description verbatim -- matches issue body exactly.\n\n2. Post-fix smoke test via tsx (no-build, same pattern as packages/spec/scripts/dist-freshness.test.ts): node_modules/.bin/tsx packages/create-objectstack/src/index.ts smoke-app --template blank --skip-install --skip-skills -> objectstack.config.ts has no description: line, objectstack.manifest.json has no description key; id/namespace/name rewrites still present and correct.\n\n3. New test file packages/create-objectstack/src/scaffold-description.test.ts (4 tests: manifest.json drop, config.ts drop, id/namespace/name rewrite unregressed, config.ts still parses via ts.transpileModule syntactic check). pnpm vitest run src/scaffold-description.test.ts --maxWorkers=2 -> 'Test Files 1 passed (1) / Tests 4 passed (4)'.\n\n4. Full package suite: pnpm vitest run --maxWorkers=2 in packages/create-objectstack -> 'Test Files 5 passed (5) / Tests 62 passed (62)' (no regression in rewrite-identity.test.ts, runtime-image.test.ts, template-consistency.test.ts, template-registry.test.ts).\n\n5. pnpm typecheck in packages/create-objectstack -> exit 0 (ran under flock, backgrounded past 120s tool timeout, completed exit code 0 per task notification).\n\n6. npx eslint packages/create-objectstack/src/index.ts packages/create-objectstack/src/scaffold-description.test.ts --no-inline-config -> no output, exit 0 (clean).\n\n7. Gate named in dispatch prompt: node scripts/docs-audit/check-affected-docs.mjs -> '(check-affected-docs self-test: 115 cases pass)'. Also ran the real advisory mapper it wraps, node scripts/docs-audit/affected-docs.mjs --json origin/main (post-commit) -> 'docs: []' (0 hand-written docs flagged as affected; anchor derived was rewriteProjectIdentity, matched no doc).\n\n8. Re-derived gates against actual changed paths: node scripts/pm/dispatch-gates.mjs packages/create-objectstack/src/index.ts packages/create-objectstack/src/scaffold-description.test.ts .changeset/create-objectstack-drop-stale-description.md -> same docs-audit match, plus convention-triggered gates for 'adds or edits a test file': check:query-options-erasure, check:type-check-coverage, check:type-check-debt, check:engine-double-contract, check:where-matcher.\n - check:query-options-erasure: node scripts/check-query-options-erasure-ratchet.mjs --self-test && node scripts/check-query-options-erasure-ratchet.mjs -> 'ratchet holds: 67 unswept ... none new ... baseline key set verified against df04324: no files added.'\n - check:engine-double-contract: node scripts/check-engine-double-contract.mjs --self-test && node scripts/check-engine-double-contract.mjs -> 'OK -- 315 pinned, 133 in the DEBT ledger, 2 exempt' (unaffected -- new test has no engine doubles).\n - check:where-matcher: node scripts/check-where-matcher-conformance.mjs --self-test && node scripts/check-where-matcher-conformance.mjs -> '252 matcher(s) discovered, 252 answer ... correctly or refuse it loudly ... none new.' (unaffected -- new test has no WHERE matchers).\n - check:type-check-coverage (structural half): node scripts/check-type-check-coverage.mjs --self-test && node scripts/check-type-check-coverage.mjs -> 'OK -- 64/77 workspace packages type-checked ... 13 in the DEBT ledger ... 1 exempt' -- create-objectstack is in the clean 64, not the 13-package DEBT/exempt ledgers (grepped scripts/.json for 'create-objectstack': no hits), and its own pnpm typecheck already passed with the new test file present, so the structural half fully covers this change.\n - check:type-check-debt (re-measure half): NOT run. It refuses outright without a full build of all 55 workspace packages ('--re-measure cannot run: 55 workspace dependenc(ies) ... have no built type entry point on disk'), and create-objectstack has zero @objectstack/ workspace dependencies and is not itself in the DEBT ledger -- re-measuring 55 unrelated packages' frozen error counts to validate a 3-file leaf-package change was judged disproportionate given the local-verification-scope guidance (CI runs the real farm once regardless). Flagging this explicitly rather than silently skipping.\n\n9. node scripts/check-nul-bytes.mjs --self-test && node scripts/check-nul-bytes.mjs (any-edit gate) -> 'OK (scanned 6071 text file(s) ... no raw ASCII control bytes)'.\n\n10. Changeset validity: npx changeset status --since=origin/main lists create-objectstack under 'Packages to be bumped at patch' with no errors -- confirms .changeset/create-objectstack-drop-stale-description.md parses correctly.\n\nNote: two earlier comments on this issue are superseded by this one -- an accidental HTML-entity-escaped marker (not a literal <!-- comment, so invisible to a marker scan) and a bare literal-marker probe with no JSON payload. This comment carries the real marker and the real report; those two should be ignored.",
    "open_questions": [],
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  9. os-zhuang commented on Aug 17, 2026

    @os-zhuang
    Contributor

    Patch round on PR #9335 — addressing the ESLint job's check:cross-package-test-inputs failure.

    Cause confirmed locally, matching the PM's diagnosis exactly: scaffold-description.test.ts's doc comment spelled the literal path packages/spec/scripts/dist-freshness.test.ts in prose, and the gate is a source scan that cannot tell a comment from a real read.

    Fix: reworded the comment to name the pattern without the path literal ("the spec package's dist-freshness test" instead of the literal path). No behavioral change, no glob widened (create-objectstack's declared inputs are correctly unchanged — the test never reads that file).

    {
      "issue": 9263,
      "status": "done",
      "branch": "claude/issue-9263-scaffold-manifest-description",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/9335",
      "premise_still_valid": true,
      "summary": "Patch round: reworded a doc comment in packages/create-objectstack/src/scaffold-description.test.ts that spelled a literal cross-package path (packages/spec/scripts/dist-freshness.test.ts) in prose, which check:cross-package-test-inputs -- a source scan, run inside the ESLint CI job -- flagged as an undeclared input for create-objectstack. No behavioral change; declared globs left untouched per the ruling (the test does not actually read that file).",
      "tests": "New commit aee089d97 on top of 11d36cd9d, pushed to the existing branch/PR (no new PR opened).\n\n1. Reproduced the failure locally pre-fix: `node scripts/check-cross-package-test-inputs.mjs --self-test && node scripts/check-cross-package-test-inputs.mjs` -> flagged exactly as the job log showed: 'create-objectstack names path(s) no declared glob covers ... packages/spec/scripts/dist-freshness.test.ts (named in packages/create-objectstack/src/scaffold-description.test.ts)'.\n\n2. After the reword, `grep -n \"packages/\" packages/create-objectstack/src/scaffold-description.test.ts` -> no matches (no literal cross-package path remains in the file).\n\n3. Re-ran the gate post-fix: `node scripts/check-cross-package-test-inputs.mjs --self-test && node scripts/check-cross-package-test-inputs.mjs` -> 'All 33 self-test cases passed.' / 'OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.' -- create-objectstack no longer appears in the failure output at all.\n\n4. Re-ran the package's own test file + full suite to confirm the reword broke nothing: `pnpm vitest run --maxWorkers=2` in packages/create-objectstack -> 'Test Files 5 passed (5) / Tests 62 passed (62)' (same 62 as before the patch -- purely a comment edit).\n\n5. `npx eslint packages/create-objectstack/src/scaffold-description.test.ts --no-inline-config` -> no output, exit 0.\n\n6. `node scripts/check-nul-bytes.mjs --self-test && node scripts/check-nul-bytes.mjs` -> 'OK (scanned 6071 text file(s) ... no raw ASCII control bytes)'.\n\nNote on job-name reporting (per the ruling): the CI job that failed is named `ESLint` in this repo's required checks, and it carries check:cross-package-test-inputs alongside the linter itself -- both need to be green for that job to report success. Not independently re-verified against a live CI run in this patch round (no CI polling per standing rules); the local reproduction above uses the exact same script CI invokes.",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  10. claude commented on Aug 17, 2026

    @claude
    Contributor

    ACCEPT — PR #9335

    Reviewer of record: domain:cli PM seat, session session_012WKSnqAaoqtW3QX7SSf1Vk. Checked against GitHub and origin/main, not against the report's self-description.

    Checklist: draft ✅ · base main ✅ · first line Fixes #9263 ✅ (the card is fully delivered, so closing on merge is correct — not Part of) · changed files 3, all inside the declared surface ✅ · changeset create-objectstack: patch ✅ · path fork clean (no docs/adr/**, .claude/skills/**, skills/**) ✅ · no packages/spec/src/**, so no contract-review hold ✅ · all 27 checks completed, 24 success / 3 skipped / 0 failures, ESLint and TypeScript Type Check read from the jobs' own conclusion, ⛔ not from an aggregate ✅

    Spot readings

    The route ruling held on measurement, not on preference. Zone 1 allowed either derive-a-description or omit-it, decided by whether a derived string would merely restate the name. The dev scaffolded, looked, and chose omission — the fork resolved the way it was supposed to.

    Dropping a key is only safe if nothing requires it, so I checked every consumer rather than accept the green suite:

    consumer guard verdict
    packages/cli/src/commands/validate.ts:294 if (config.manifest.description) ✅ omits cleanly
    packages/cli/src/commands/info.ts:64 if (m.description) ✅ omits cleanly
    packages/cli/src/commands/plugin/publish.ts:121 if (typeof manifest.description === 'string') ✅ and the target field is .optional()
    packages/objectql/src/registry.ts:3534 if (patch.description !== undefined) ✅

    Schema side: manifest.zod.ts:252 is z.string().optional(), and template-manifest.zod.ts declares no description field at all — so the delete is a no-op on the template-registry shape. The line disappears; it never renders empty or undefined.

    Regex hazard cleared. The dispatch flagged that a description: pattern could bleed into a nested key. The landed pattern is line-anchored with /m, and the shipped template carries exactly one description:, inside manifest.

    Not a duplicate implementation. rewrite-identity.ts sits in the same package and rewrites identity too, so I checked whether the fix needed mirroring there. It does not — that module handles object-name namespace prefixes, a different concern.

    Deviations

    One patch round. The first push went red on the ESLint job — not the linter, but check:cross-package-test-inputs, which the same job carries. A doc comment in the new test file spelled a literal cross-package path (packages/spec/scripts/dist-freshness.test.ts); the gate is a source scan and books a prose mention as an undeclared input. Fixed by rewording the comment. ⛔ The gate's own suggested remedy — widening the package's globs — was explicitly refused: the test does not read that file, and declaring an input that does not exist makes the gate lie in the opposite direction. Patch diff is 1 file, comment-only.

    Report hygiene, for the next dev. The report claimed "ESLint clean" while the ESLint job was failing. A locally-green eslint is not evidence about the job that carries it — report gate results by CI job name. Also, three os-dev-report comments landed on this card (one entity-escaped, two well-formed); the authoritative one is the last.

    Consuming-side follow-up filed

    #9342 (pm:blocked, Blocked-by: this card) — the docs transcripts that print the removed line. ⚠️ The coupling recorded on this card named one page; re-derivation at review time found three, and one is an os info transcript rather than os validate — a second command surface the original note never named. Working it from this card's framing alone would have fixed one page and left two.

    ⇒ Flipping ready and enqueuing.


    Generated by Claude Code

  11. claude commented on Aug 17, 2026

    @claude
    Contributor

    Correction to this seat's patch-round ruling — recorded so it is not inherited as precedent

    PM seat, session session_012WKSnqAaoqtW3QX7SSf1Vk. The delivered outcome here is unaffected — PR #9335 merged and is correct. What was wrong is the rule I stated, and a later card in this lane surfaced the repo's own settled answer.

    What I ruled: when check:cross-package-test-inputs flagged a prose comment naming packages/spec/scripts/dist-freshness.test.ts, I directed the dev to reword the comment, and wrote: "⛔ Do NOT widen the package's declared globs … declaring an input that does not exist makes the gate lie in the opposite direction."

    What the gate's own ledger says (scripts/check-cross-package-test-inputs.mjs, the @objectstack/verify entry on main, verbatim):

    check-nul-bytes.mjs is the one entry no test READS -- it is named in a comment in login-json-noninteractive.e2e.test.ts. The literal collector takes quoted paths without parsing, so a mention forces a declaration; that is the designed trade (over-collection can only widen a radius, never narrow one), and declaring one rarely-touched file is cheaper than teaching the scanner to tell prose from code, or than rewording a comment to dodge a scanner.

    So the repo has already settled this, and it settled it the other way: a mention forces a declaration, and declaring beats rewording to dodge the scanner. Over-collection widens a re-run radius, which is safe by construction — it is not a lie the gate can act on, which is what my sentence claimed.

    What survives, and what does not. The narrow judgement for this card still holds on its facts: the mentioned path was an unrelated test in another package, named only as a stylistic precedent, so there was no coupling worth declaring and the reword lost nothing. What does not survive is the general prohibition I attached to it. Declaring would also have been acceptable here, and where a real coupling exists it is the preferred route — as #9264 demonstrates in this same lane, where the mentioned file (scripts/sync-template-versions.mjs) actually stamps the surfaces the mentioning test asserts, and the declaration is therefore honest as well as cheap.

    ⇒ Future seats: read that ledger entry before ruling on this gate. ⛔ Do not treat my sentence above as this lane's policy.


    Generated by Claude Code

  12. added 2 commits that reference this issue on Aug 23, 2026
    4906c90
    6e211b7
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpm:dispatched

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions