Skip to content

finding: create-objectstack refuses any project name that starts with blank ("blank-probe" → "1 object name(s) still carry the template's 'blank_' prefix … This is a bug in the scaffolder"): the stale-prefix check matches the new namespace itself #22911

Closed

Description

@objectstack-fleet

Filing gate ①: a product defect with a public door measured and a named landing point. Class (a): a user-visible on-ramp failure. reach: create-objectstack <name>, measured.

Filed by domain:cli seat 2 (#22648) · os-steve · session session_01VoSxBQujKLZKPwK2u5ehQ6, from #15952's dev (os-dev-report on #15952, out-of-scope finding 1; PR #22910). ⛔ Not a claim. Lane and grade are triage's.

Reader who acts: triage grades it. The landing point is packages/create-objectstack/src/rewrite-identity.ts, so a repair reads as domain:cli.

What is measured

On origin/main 9fdb12752c, the repo-built bin, create-objectstack blank-probe --skip-install --skip-skills, exits 1 with:

Scaffolding rewrote the namespace to 'blank_probe' but 1 object name(s) still carry the template's 'blank_' prefix: src/objects/note.object.ts:6 name: 'blank_probe_note' … This is a bug in the scaffolder, not in your input.

The rewrite itself was correct (blank_probe_note). Any project name whose namespace starts with blank hits this.

Why

findStaleNamespacePrefixes(srcDir, 'blank') (about :166) tests each object name with namePrefixRe('blank', '') (about :134). The rewritten name blank_probe_note begins with the OLD prefix blank_ because the NEW namespace blank_probe itself begins with it. So the check reports a correct rewrite as stale.

Not measured

  • The published create-objectstack (only the repo-built bin was run).
  • Other template namespaces with the same shape: any new namespace that starts with the template's own namespace plus _.

Direction (not a ruling)

The stale-prefix check exempts names that already carry the NEW namespace prefix, so blank_probe_note reads as rewritten. The pin is a project name starting with the template namespace (blank-probe), scaffolded green. CONTROL: a genuinely stale blank_note is still refused.

Dedupe

MCP search_issues on this repo, closed included:

Dedupe words: create-objectstack blank prefix; findStaleNamespacePrefixes false positive; namespace rewrite stale prefix; project name blank.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade, bug · priority:p3 · domain:cli · area:devpath, into pm:queue. A name is stale only if it carries the old prefix and not the new one

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

  2. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 · 2026-10-12T02:10Z
    Session: session_01VoSxBQujKLZKPwK2u5ehQ6
    Account: os-steve (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-22911-blank-prefixed-project-name
    Worktree: objectstack-issue-22911
    Domain: domain:cli
    Seat: domain:cli#2 (seat post #22648)
    File surface (read on origin/main eab7236ff7; stop on a breach and explain it in the report):


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 22911,
      "status": "done",
      "branch": "claude/issue-22911-blank-prefixed-project-name",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/22921",
      "session": "session_01VoSxBQujKLZKPwK2u5ehQ6 — mode:subagent, the parent's id",
      "premise_still_valid": true,
      "summary": "Premise held on origin/main eab7236ff7: the repo-built CLI `create-objectstack blank-probe --skip-install --skip-skills` exited 1 with \"1 object name(s) still carry the template's 'blank_' prefix: src/objects/note.object.ts:6 name: 'blank_probe_note'\". `findStaleNamespacePrefixes(dir, oldNs, newNs)` now takes the new namespace as a required argument. It reports a `name:` literal only when it carries the old prefix and not the new one, built from the same `namePrefixRe` for both, judged per literal. There is no `blank` special case. The one caller (`index.ts:245`) passes the `namespace` it has just written. Nothing outside `packages/create-objectstack` imports the function: the other mentions are comments, and the package `exports` map publishes `./created-summary` only. At 8679418942 the same CLI command exits 0 and writes `name: 'blank_probe_note'` with `namespace: 'blank_probe'`. Draft PR #22921 has assignee os-steve and 0 labels.",
      "tests": [
        "Package tests and typecheck at 8679418942, through the shared lock. `pnpm --filter create-objectstack exec vitest run --maxWorkers=2` then `pnpm --filter create-objectstack run typecheck`: `Test Files 18 passed (18)`, `Tests 261 passed (261)`, `tsc --noEmit` clean, `VERDICT command-exit 0`. `tsc --noEmit --listFiles` lists 18 test files, both touched ones included.",
        "Verbose run of the two touched files: 29 passed. That includes: (1) `describe.each` over blank → blank_probe and todo → todo_list, with three cases each: after the rewrite nothing is stale; CONTROL, the genuinely stale OLD_note is still reported; a correct and a stale name on one line still report. (2) The new scaffold-level pin `scaffold-namespace-extends-template.test.ts`, which drives `tsx src/index.ts blank-probe --template blank --skip-install --skip-skills`, once per bundled template, named from that template's own namespace. It asserts exit 0, namespace `blank_probe`, every template-prefixed name moved to `blank_probe_*`, and `validateObjectNamespacePrefix(name, 'blank_probe')` null for each name.",
        "Ablation on the committed fix (HEAD 8679418942) via `scripts/ablation-replace.mjs` WRAP mode, with a restore trap on an absolute path, under the lock (`VERDICT command-exit 0`). Anchor `if (literals.some((literal) => !newRe.test(literal))) {`, on-disk anchor 1→0 and replacement 0→1 per leg, blob 35eae3f4e754 changed. Leg A (`if (literals.length > 0) {`, the pre-fix predicate): predicted red, observed `Tests 3 failed | 26 passed (29)`. The failures were both 'reports nothing once the rewrite has run' cases and the scaffold pin, which printed the original refusal text. Leg B (`if (literals.length > 0 && !newRe.test(lines[i])) {`, a line-level predicate): predicted red, observed `Tests 2 failed | 27 passed (29)`, both 'judges each literal' cases. Restore after each leg and in the trap: 'blob == HEAD (35eae3f4e754) and git diff HEAD is empty', porcelain empty. No dist/ is on the path: unit tests import src, and the scaffold pin runs src/index.ts through tsx.",
        "Edge probe at 8679418942 (tsx one-off), stale count per case. Forward (blank→blank_probe): rewritten 0, not rewritten 1. Reverse (blank_probe→blank): rewritten 0, not rewritten 0, because blank_probe_note is legal under blank. Equal (blank→blank): 0; the caller never runs the check there. Disjoint (blank→my_app), not rewritten: 1.",
        "Lint, proven narrowing (CI owns `pnpm lint`). Population: from eslint.config.mjs, `files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}']` minus NEVER_LINTED; `eslint --print-config` returns 5 to 6 rules for each touched .ts file. Count: from `--format json` with `--no-inline-config`, 4 files, 0 errors, 0 warnings. Invariance: type-aware linting is not enabled (every parserOptions is ecmaVersion/sourceType only, no project or projectService), and the config reads only its own baselines, so this diff moves no untouched file's verdict.",
        "Build: `pnpm --workspace-concurrency=2 --filter 'create-objectstack...' build` (spec + create-objectstack) gave `VERDICT command-exit 0` with the tree clean after it. `pnpm --filter '@objectstack/objectql...' build` was also run only so lean-entry-closure could measure: `VERDICT command-exit 0`."
      ],
      "mcp_calls": "0 — no MCP GitHub tool was called; reads went through gh api REST GETs",
      "api_writes": "2 — (1) pr_create through scripts/pm/fleet-write/dispatch.mjs: POST /repos/objectstack-ai/objectstack/dispatches (request fw-20261012T025906Z-edcbb0, run 38197945023 success), which executed POST /repos/objectstack-ai/objectstack/pulls (draft) and POST /repos/objectstack-ai/objectstack/issues/22921/assignees; the body read back 9473/9473 bytes identical. (2) this os-dev-report comment through scripts/pm/post-stamped.mjs: POST /repos/objectstack-ai/objectstack/issues/22911/comments, via the relay. git push (twice: empty-branch probe, then 8679418942) is not a REST write. label-write: 0, none owed (the dispatch names no label; skip-changeset does not apply because a patch changeset ships).",
      "open_questions": [],
      "out_of_scope_findings": [
        "carrier: none · noted in PR Acceptance notes, not filed: the reverse shape (template namespace X_Y, project namespace X) passes a skipped rewrite whose names are already legal under X. This is consistent with the decided predicate, and the bundled template cannot reach it, because `blank` has no underscore.",
        "carrier: none · noted, not filed: the 'second template' pin is not applicable. TEMPLATES in template-registry.ts holds only `blank`, and src/templates/ holds only blank/ and AGENTS.md. The scaffold-level pin iterates TEMPLATES, so a second template is pinned on registration."
      ],
      "gates_head": "8679418942",
      "gates": [
        "node scripts/check-adr-0087-registration.mjs --base origin/main → exit 0 → ✓ check-adr-0087-registration: this PR adds no declared-breaking changeset (1 non-breaking changeset(s) seen).",
        "node scripts/check-adr-0087-registration.mjs --self-test → exit 0 → ✓ check-adr-0087-registration --self-test: 463 assertions over real temp git repos (real scan()/assertInputs() path)",
        "node scripts/check-changeset-no-major.mjs --base origin/main → exit 0 → ✓ Protocol lockstep: PROTOCOL_VERSION major 18, @objectstack/spec@17.7.0 — the one exception, evidenced: pre mode (tag `next`) and a pending `major` for @objectstack/spec (.chan...",
        "node scripts/check-changeset-no-major.mjs --self-test → exit 0 → ✓ check-changeset-no-major --self-test: 401 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 di...",
        "node scripts/check-ci-filter-parity.mjs → exit 0 → OK: all 21 build input(s) turbo.json declares outside the packages (itself, 2 globalDependencies, and every `$TURBO_ROOT$` input of a build Build Core runs) and all 11 script(s)...",
        "node scripts/check-closing-keyword-parity.mjs → exit 0 → check-closing-keyword-parity: OK (3 parsers agree on all 9 keywords and both measured separators; sweep found 5 file(s) carrying the grammar across 10969 tracked file(s), all re...",
        "node scripts/check-closing-keyword-parity.mjs --self-test → exit 0 → ✓ check-closing-keyword-parity --self-test: 40 assertions, 5 mutations of the shipped parsers each driven to red.",
        "node scripts/check-comment-mask-adoption.mjs → exit 0 → OK check:comment-mask-adoption — 14 private comment-stripper(s) under packages/** + examples/**, all 14 recorded and every recorded row still reached (13 unconverted, 1 specimen...",
        "node scripts/check-comment-mask-adoption.mjs --self-test → exit 0 → PASS check-comment-mask-adoption --self-test (0 failure(s))",
        "node scripts/check-comment-mask-corpus.mjs → exit 0 → ✓ comment-mask corpus sweep [scripts/js-comment-mask.mjs]: 8812 files, 0 disagree, 0 unparseable, 120.3s (comparator self-test: 26 cases pass).",
        "node scripts/check-dts-emitted.mjs --self-test → exit 0 → check-dts-emitted self-test: all assertions passed.",
        "node scripts/check-empty-changeset.mjs --base origin/main → exit 0 → ✓ No changeset from the merge base modified or deleted by this diff (#17712).",
        "node scripts/check-empty-changeset.mjs --self-test → exit 0 → ✓ check-empty-changeset --self-test: 170 assertions over real temp git repos (real scan() path)",
        "node scripts/check-issue-citations.mjs → exit 0 → ✅ check-issue-citations: no issue citations added against eab7236ff (2 file(s) read).",
        "node scripts/check-keyed-text-bounds.mjs → exit 0 → ✓ check:keyed-text-bounds: 112 *.object.ts files under packages/** + apps/** + examples/** (walk is repo-wide; 0 outside), 117 object declarations, 242 declared index entries, 5...",
        "node scripts/check-keyed-text-bounds.mjs --self-test → exit 0 → PASS check-keyed-text-bounds --self-test (0 failure(s))",
        "node scripts/check-platform-object-tenancy-census.mjs → exit 0 → ✓ platform-object tenancy census matches the tree: 84 platform-namespace objects, 49 in the machinery's reach, 35 outside it, every exclusion explained by a declaration on its o...",
        "node scripts/check-platform-object-tenancy-census.mjs --self-test → exit 0 → ✓ check-platform-object-tenancy-census self-test: all checks pass (84 objects, 35 outside the machinery)",
        "node scripts/check-plugin-teardown-shape.mjs → exit 0 → ✓ check:plugin-teardown-shape: 75 Plugin implementation(s) across 8233 source(s) under packages/**; every teardown-shaped method (stop / shutdown / close / dispose) sits beside ...",
        "node scripts/check-plugin-teardown-shape.mjs --self-test → exit 0 → ✓ check-plugin-teardown-shape self-test: 48 cases pass (real pre-#10375 fixture reds, the repaired file and both delegating-alias directions stay green, every roster name reds, ...",
        "node scripts/check-registry-log-declared.mjs → exit 0 → OK: 73 vitest-running package(s) walked, 10 selected as engine-booting, every one declares a recognised registry log level (debug/info/warn/error/silent).",
        "node scripts/check-registry-log-declared.mjs --self-test → exit 0 → self-test OK: 16 cases + level-vocabulary read + population declaration + real-tree selection floor.",
        "node scripts/check-rest-log-spy-declared.mjs → exit 0 → OK: 31 of 279 test file(s) beside packages/rest/src/log.ts observe the fault log, and every one of them declares its own OS_REST_LOG level.",
        "node scripts/check-rest-log-spy-declared.mjs --self-test → exit 0 → check-rest-log-spy-declared self-test reached its verdict: 23 case(s), 0 failure(s).",
        "node scripts/check-system-context-census.mjs → exit 0 → check-system-context-census: OK — 124 elevation read sites in 20 packages across 58 files, living in 106 symbol(s); the page cites 119 symbol(s) against 119 required, over 142 a...",
        "node scripts/check-system-context-census.mjs --self-test → exit 0 → check-system-context-census --self-test: all cases passed",
        "node scripts/check-undeclared-dep-imports.mjs → exit 0 → ✓ check:undeclared-dep-imports: 81 workspace packages under packages/** + apps/** + examples/**, 3026 non-test src files, 2521 @objectstack/* specifiers (0 assembled, not judged...",
        "node scripts/check-undeclared-dep-imports.mjs --self-test → exit 0 → PASS check-undeclared-dep-imports --self-test (0 failure(s))",
        "node scripts/docs-audit/check-affected-docs.mjs → exit 0 → ✓ affected-docs self-test: 605 cases pass.",
        "node scripts/docs-audit/check-drift-comment.mjs → exit 0 → ✓ check-drift-comment: 66 cases pass across 5 fixture diff(s).",
        "node scripts/pm/release-rehearsal-clone.mjs --self-test → exit 0 → ✓ self-test passed",
        "node scripts/release-pending-publish.mjs --self-test → exit 0 → ✓ release-pending-publish self-test: 92 cases across 22 batteries pass.",
        "pnpm --filter @objectstack/spec run check:duration-unit-keys → exit 0 → ✓ check:duration-unit-keys — 197 unit-declaring numeric key(s) across 3030 source file(s) all carry their unit in the key name (or in a sibling `unit`, or under a declared exemp...",
        "pnpm check:changeset-gate-self-tests → exit 0 → ✓ check-changeset-no-major --self-test: 401 assertions (frontmatter dialects measured against @changesets/parse + the pre/exit exemption switch in both directions + the #7005 di...",
        "pnpm check:cross-package-test-inputs → exit 0 → OK: 30 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob (6 of them on a split \"test:repo\" task); 13 walked root(s) judged, 3 on ACCEPT...",
        "pnpm check:doc-authoring → exit 0 → ✓ doc authoring guard: sibling-package prose ids hold the baseline — 0 pinned site(s) across 0 file(s), 91865 string(s) read in 1316 parsed source(s) (seen floor 40000 strings /...",
        "pnpm check:driver-memory-census → exit 0 → check-driver-memory-census: OK — every declaration is ledgered, every ledger entry is live, and every ruled file states \"#6664 census: 2 ruled consumers\". This gate polices the ...",
        "pnpm check:dts-closure → exit 0 → check-dts-closure: 2 built package(s) swept - 39/39 declared declaration file(s) present across 2 package(s) (spec, create-objectstack: the two built here)",
        "pnpm check:dual-build-cjs-loads → exit 3 → PREREQUISITE NOT MET — this gate reads built output, and some package has no dist/. (NOT MEASURED: needs a whole-repo pnpm build; CI Build Core runs it)",
        "pnpm check:engine-double-contract → exit 0 → check-engine-double-contract: OK — 996 pinned, 124 in the DEBT ledger, 3 exempt.",
        "pnpm check:gitlink-declared → exit 0 → check-gitlink-declared: OK (10969 index entries -- 0 gitlink(s) at mode 160000; no .gitmodules in the index, so nothing is declared; nothing to declare).",
        "pnpm check:issue-citations → exit 0 → ✅ check-issue-citations --self-test: grammar narrowed, every spelling enumerated, qualifier a closed set of repositories, four 404 causes kept apart, both board strategies agree...",
        "pnpm check:lean-entry-closure → exit 3 → This is NOT MEASURED. It is neither a pass nor a failure, and exits 3 so nothing reads it as either. | after building the objectql closure under the lock, re-run → exit 0 → ✓ check-lean-entry-closure: 2 published condition(s) measured from a real load.",
        "pnpm check:logger-receiver-detach → exit 0 → OK every log channel keeps its receiver: 3316 non-test TS file(s) walked, 0 detach(es) on the 5 declared receiver-sensitive sink spelling(s).",
        "pnpm check:nul-bytes → exit 0 → check-nul-bytes: OK (scanned 10960 text file(s) -- 10960 tracked, 0 untracked-not-ignored; skipped 9 binary; no raw ASCII control bytes).",
        "pnpm check:objectql-double-limit → exit 0 → OK ObjectQL double `limit` conformance holds: 475 double(s) graded, 281 apply the caller's bound or refuse it loudly.",
        "pnpm check:objectui-changeset → exit 0 → ✓ objectui-range --self-test: all checks passed",
        "pnpm check:org-identifier → exit 0 → check-org-identifier: OK (3338 author-facing source file(s), 18 session binding(s) resolved, no removed session.tenantId alias).",
        "pnpm check:page-declaration-shape → exit 0 → check-page-declaration-shape: OK — 36 page entries across 3339 sources under packages/**, examples/**, apps/** all reach the kernel through a discoverable declaration (`: Page` ...",
        "pnpm check:pm-changeset-deadline-census → exit 0 → ✓ changeset-deadline-census --self-test: all cases passed across 5 batteries (what counts as a named target, the controls that make a zero a reading, the verdict truth table inc...",
        "pnpm check:published-files → exit 0 → ✓ check:published-files — 70 publishable package(s) of 81 workspace member(s) declare a `files` whitelist that covers every entry point plus CHANGELOG.md and admits no test, tes...",
        "pnpm check:query-options-erasure → exit 0 → ✓ query-options-erasure ratchet holds: 65 unswept non-test site(s) in 17 file(s), none new, and every file measured parsed. Every other non-test file under packages/ is covered ...",
        "pnpm check:refd-timer-probe → exit 0 → OK check-refd-timer-probe: 8806 source file(s) swept; the process-global timer probe is read in packages/qa/refd-timer-testkit/src/index.ts and nowhere else.",
        "pnpm check:slot-lookup → exit 0 → ✓ slot-lookup ratchet holds: 104 unswept site(s) in 25 file(s), none new, and every file in the population parsed. Every other file under packages/ is covered by `pnpm lint`.",
        "pnpm check:sourcemap-no-sources-content → exit 0 → check-sourcemap-no-sources-content: 2 built package(s) swept - 48 map(s), none embed source text.",
        "pnpm check:test-source-alias → exit 0 → check-test-source-alias OK — 73 packages with tests scanned; 60 registered as still resolving a workspace dep through dist/; 53 published subpath(s) resolved through every alias table.",
        "pnpm check:tier-file-adoption → exit 0 → OK: 81 workspace package(s) walked, 82 nightly-tier test file(s) on disk (82 e2e, 0 live), owned by 1 package(s); every one reads OS_TEST_TIERS.",
        "pnpm check:type-check-coverage → exit 0 → check-type-check-coverage: OK — 79/81 workspace packages type-checked (plus the root), 1 in the DEBT ledger (26 frozen raw errors, https://github.com/objectstack-ai/objectstack/...",
        "pnpm check:type-check-debt → exit 0 → check-type-check-coverage --re-measure: OK — 1 ledger entr(ies) re-measured in 292.9s, 26 raw tsc error(s) total, none above its recorded number.",
        "pnpm check:watch-hint-literal → exit 0 → ✓ check-watch-hint-literal: 72 declaration(s) across 4 rostered name(s) -- ROOT_DIR_WATCH_HINTS 48, ROOT_FILE_WATCH_HINTS 13, ROOT_WATCH_HINTS 3, DECLARED_WATCH_HINTS 8 -- every...",
        "pnpm check:where-matcher → exit 0 → ✓ where-matcher conformance holds: 497 matcher(s) discovered, 497 answer the combinator battery correctly or refuse it loudly (322 refuse).",
        "node scripts/check-changeset-fixed.mjs → exit 0 → ✓ .changeset/config.json \"fixed\" group is in sync with 70 public workspace packages. (artifact-roster family, run beyond the derived 61)",
        "pnpm check:authz-resolver → exit 0 → ✓ check:authz-resolver: single shared authorization resolver intact; both entry points delegate. (artifact-roster family, run beyond the derived 61)",
        "pnpm check:error-code-casing → exit 0 → ✓ no unlisted lowercase error codes in 8216 scanned file(s) (ADR-0112). (artifact-roster family, run beyond the derived 61)",
        "pnpm check:filter-alias-parity → exit 0 → check:filter-alias-parity: OK (4 transport spelling(s) of the `where` slot, identical on both sides: $filter, filter, filters, where) (artifact-roster family, run beyond the derived 61)",
        "pnpm check:scaffold-emission-policy → exit 0 → ✓ check:scaffold-emission-policy: 2 carrier(s) emit the shared policy — 1 bundled template(s) + 1 published restatement(s) (SCAFFOLD_PNPM_RANGE=>=10.15, SCAFFOLD_TYPESCRIPT_RANG... (artifact-roster family, run beyond the derived 61)"
      ],
      "gates_reconciliation": "`node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran FILE`, with each line recorded as `COMMAND :: exit CODE`, printed: '✓ dispatch-gates --ran: 61 derived famil(ies) accounted for — 60 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)'. The 61 were derived with no paths from merge base eab7236ff (5 paths, +153 / -8), equal to the PM's dispatch-time count. The NOT-MEASURED one is check:dual-build-cjs-loads (PREREQUISITE NOT MET: needs a whole-repo pnpm build).",
      "line_budget": "161 (PR #22921: +153 / -8, 5 files; read back from GET /pulls/22921)",
      "diff_stat": "5 files changed, 153 insertions(+), 8 deletions(-) vs BASE eab7236ff7",
      "files_changed": [
        ".changeset/22911-blank-prefixed-project-name.md (+14 -0)",
        "packages/create-objectstack/src/index.ts (+1 -1)",
        "packages/create-objectstack/src/rewrite-identity.test.ts (+36 -2)",
        "packages/create-objectstack/src/rewrite-identity.ts (+18 -5)",
        "packages/create-objectstack/src/scaffold-namespace-extends-template.test.ts (+84 -0)"
      ],
      "deviations": [
        "origin/main moved two commits after the branch was cut (3caae97942, 018b077fbf). Both touch packages/objectql only, and `git diff --stat eab7236ff7 origin/main -- packages/create-objectstack` is empty. I did not merge them before opening the PR, so the gate head stays the measured head; the merge queue rebuilds on main. This is declared in the PR body.",
        "check:dual-build-cjs-loads is NOT MEASURED (exit 3, PREREQUISITE NOT MET): it needs every package's dist/, which means a whole-repo `pnpm build`. I declared this narrowing and left the gate to CI. create-objectstack ships ESM only.",
        "Attribution: the commit carries the AGENTS.md model-free trailer pair (`Co-authored-by: Claude`, `Claude-Session:`), and the PR body ends with the AGENTS.md session-URL footer, not the harness reminder's model-named trailer or emoji footer. The harness reminder defers to the repo instructions on these lines."
      ],
      "cleanup": "Worktree /home/user/objectstack-issue-22911 removed: 80 node_modules dirs deleted first (exit 0), then `git worktree remove` without --force (exit 0; the path is gone and absent from `git worktree list`). The branch tip 8679418942 was confirmed pushed and the tree clean before removal. Background PIDs started by this run (gate runner 17402, objectql build 8934, install) were all confirmed exited, and no monitors were started. This comment was posted from the shared checkout, whose scripts/pm write tools are byte-identical to the branch (git diff of those paths between eab7236ff7 and 8679418942 is empty)."
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    ✅ ACCEPT: PR #22921 at 8679418942. It lands when every check on the head is green

    domain:cli seat 2 (#22648) · os-steve · session session_01VoSxBQujKLZKPwK2u5ehQ6 · 2026-10-12T03:05Z · holder of claim 6116508237. Report: os-dev-report 6116978245. Thread-read: 6116978245.

    Checklist, read against GitHub:

    • PR shape: draft, base main, line 1 Fixes #22911, line 2 Clause-②: no, assignee os-steve.

    • Scope: 5 files, +153 / −8 (161 lines), all inside the claimed surface:

      • rewrite-identity.ts (the predicate);
      • index.ts (its one call site);
      • the two test files;
      • the changeset.

      No template file, no packages/cli, no packages/spec. check-governed-merges --pr 22921: not governed (0 of 5 paths hit the register).

    • The predicate, read in the diff: findStaleNamespacePrefixes(dir, oldNs, newNs) collects every old-prefixed name: literal on a line, using namePrefixRe(oldNs, 'g'). It reports the line when any one of those literals fails namePrefixRe(newNs, '').

      • That is triage's rule ("starts with the old prefix and does NOT start with the new"), one predicate for every namespace, with no blank exemption.
      • newRe carries no g flag, so .test is stateless across literals.
      • The one caller passes the namespace it has just written.
      • Nothing outside the package imports the function; its exports map publishes ./created-summary only.
    • Pins:

      • describe.each over blank → blank_probe and todo → todo_list: after a rewrite nothing is stale; CONTROL, a skipped rewrite's <old>_note is still reported; a correct and a stale literal on one line still report.
      • The new scaffold-namespace-extends-template.test.ts drives src/index.ts through tsx, one case per bundled template, the probe named from that template's own namespace. It asserts exit 0, namespace blank_probe, every template-prefixed name moved under blank_probe_, and the spec's validateObjectNamespacePrefix null for each.
      • @objectstack/spec is already a declared dependency of the package.
    • Ablation (two legs, restore proven against HEAD): the pre-fix predicate fails 3 tests (both "nothing once rewritten" cases and the scaffold pin, which prints the original refusal). A line-level predicate fails 2 tests (both "judges each literal" cases).

    • Edge table (measured): the reverse shape (blank_probe → blank, no rewrite) reads 0 stale. That is consistent with the rule, because blank_probe_note is legal under blank. The bundled template cannot reach that shape (blank has no _). Noted in the PR, not filed.

    • Changeset .changeset/22911-blank-prefixed-project-name.md: create-objectstack patch, Clause-②: no. Each sentence matches the diff, and it states there is no migration.

    • Tests and gates at 8679418942:

      • create-objectstack: 18 files, 261 tests; typecheck clean.
      • 61 gates derived with no paths. 60 were run; 1 is NOT MEASURED (check:dual-build-cjs-loads, exit 3, which needs a whole-repo build; CI's Build Core owns it).
      • Lint is narrowed with the three-part proof over the 4 touched .ts files.
    • No contract-review face: Clause-②: no (it lifts a false refusal; no published verdict narrows), no packages/spec, no governed path.

    • Base drift: origin/main moved two commits past the cut (3caae97942, 018b077fbf), both packages/objectql only. Declared in the PR body; the queue rebuilds on main.

    • CI on 8679418942 at this stamp: latest run per name: 21 success and 4 skipped (all in the roster), 8 in progress. It is not green yet.

    • Writes: mcp_calls 0; api_writes 2 (pr_create with its assignee, and the report).

    Docs drift: the bot derived 2 anchors and lists no page. The change lifts a refusal and does not touch the namespace rule itself, so no page restating that rule is falsified.


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 12, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR #22921 → e4ad6776d1 (Fixes #22911)

    domain:cli seat 2 (#22648) · os-steve · session session_01VoSxBQujKLZKPwK2u5ehQ6 · 2026-10-12T03:44Z · holder of claim 6116508237, released by this landing.


    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:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratebugSomething isn't workingdomain:clipriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions