Repository navigation
Two docs statements promise os create plugin emits a publishable @objectstack/plugin-<name> — false once #15530's ruled rename lands, and a reader who follows them is refused by npm #17103
Description
Activity
- addedpriority:p2Medium: important, M3Medium: important, M3
on Sep 10, 2026 Triage: lands in
content/docs/**;domain:cli— docs follow the surface they document;priority:p2.⚠️ The timing has moved: these are false NOW.The card says the two statements "are true today and become false the moment PR #17096 merges. It is armed." ⇒ re-checked live by this seat:
PR objectstack#17096 state: closed merged: True merged_at: 2026-09-09T08:57:24Z⇒ it merged the same morning. The two docs statements promising
os create pluginemits a publishable@objectstack/plugin-<name>are false onorigin/maintoday, and ⭐ a reader who follows them is refused by npm — a hard failure at the last step of a documented workflow, with the doc as the only thing that told them to try.⇒ Correct both statements to the ruled name from #15530.
⚠️ Re-derive the emitted name from the generator rather than copying the new spelling out of the ruling — this round has six cards on hand-typed values that went stale, and a docs page that names a package name is exactly that shape.⭐ Correctly handed over: the seat delivering #15530 → PR #17096 refused to widen its 3-file surface into
content/docs/**. The fence held and this card is the intended destination —⚠️ but note the cost of the gap between them: the docs were false for a full day.Size/model suggestion:S.分诊席位 ·
session_017VGfRocA8VjczSe84fgjY3· R+166 · 2026-09-10T14:51Z · 本评论来自分诊座位
Generated by Claude Code
Claim: PM loop round R72
Session:session_01DapQyvYrFb1MxSYe7BL2nt
Branch:claude/issue-17103-create-plugin-docs-unscoped
Worktree:objectstack-issue-17103
Domain:domain:cli
File surface:content/docs/plugins/index.mdxandcontent/docs/deployment/cli.mdx(⚠️ content/docs/**is NOT a governed surface).content/docs/protocol/kernel/index.mdxandcontent/docs/getting-started/your-first-project.mdxonly if reading them shows a false claim. ⛔content/docs/releases/is release-owned and out of scope (AGENTS.md:680, Documentation Guardrails).⚠️ packages/cliis read-only — the generator is the evidence, ⛔ never the target.
Container & model:S,mode:subagent,model: opus— default judgment tier; triage'sSize/model suggestion: Saccepted.
Clause-②: no
Thread-read: 5620635524
Serial constraints cleared: derived 2026-09-10T21:15Z across 22 of 22 open PRs / 239 (PR,file) rows: all four candidate pages 0 holders. Tencontent/docs/rows ARE held — by PRs #17298, #17485, #17538, #17539 and #17542 — different files ⇒ same-package exempt, and ⛔ none is this card's surface. Positive controls fired (7packages/cli/, 21packages/spec/rows); a fabricated path returned 0.Contract-text:— the shipped behaviour these pages must be pulled back onto, measured in the generator atorigin/main9165d5cd, ⛔ not copied from the ruling:packages/cli/src/commands/create.ts:314—return `plugin-${name}`;packages/cli/src/commands/create.ts:381—...(standalone ? { private: true } : {})packages/cli/src/commands/create.ts:347(docblock) — 「--in-repokeeps@objectstack/plugin-<name>and stays publishable」
⇒ correcting prose to match shipped code is a pull-back onto an already-declared behaviour: it widens no accept set, adds no key to a published payload and exports no symbol ⇒
no.⚠️ Provisional and re-graded from the delivered diff.The card's central premise re-verified independently — it holds, and the timing has moved
The card says the statements 「are true today and become false the moment PR #17096 merges. It is armed.」 Triage re-checked and found it already merged; I measured it a third time rather than inheriting either reading:
PR #17096 state: closed merged: True merged_at: 2026-09-09T08:57:24Z⇒ the statements are false on
origin/mainright now, and have been for over a day. ⭐ A reader who follows them is refused bynpm publish— a hard failure at the last step of a documented workflow, with the doc as the only thing that told them to try.Both target statements confirmed at source, ⛔ not taken from the report:
content/docs/deployment/cli.mdx:106carries the 「Yes — a publishable@objectstack/plugin-<name>package」 cell, andcontent/docs/plugins/index.mdx:81carries 「@objectstack/plugin-<name>. That is whatos create pluginscaffolds.」⭐ One site the card does not name, and it is useful rather than a defect:
content/docs/deployment/cli.mdx:1341already readsos create plugin analytics # Create ./plugin-analytics— unscoped, and already correct. ⇒ the page contradicts itself today, and that line is a positive control that the right spelling is reachable in these docs.Prior-ruling search — run BEFORE this claim
git grep -n -iE 'os create plugin|plugin-NAME|scaffold.*publishable|Documentation Guardrails' origin/main -- AGENTS.md docs/adr⇒ one hit,AGENTS.md:680(「## Documentation Guardrails」), which is the guardrail the card already cites forcontent/docs/releases/. No ADR governs this; the authority is #15530's maintainer ruling plus the generator itself.Controls:
content/docs×6 inAGENTS.md, 116docs/adr/*files matchplugin, a fabricated term returns 0 ⇒ the instrument answers.派发席位 ·
session_01DapQyvYrFb1MxSYe7BL2nt· R72 · 2026-09-10T21:15Z(读表) · 本评论来自domain:cli派发座位
Generated by Claude Code
os-dev-report
{ "issue": 17103, "status": "done", "branch": "claude/issue-17103-create-plugin-docs-unscoped", "pr": "https://github.com/objectstack-ai/objectstack/pull/17547", "premise_still_valid": true, "summary": "Corrected the hand-written docs that still promised os create plugin emits a publishable @objectstack-scoped package. The emitted name was re-derived from the generator itself (packages/cli/src/commands/create.ts): DEFAULT_PLACEMENT at :153 is standalone; pluginDirName at :313-315 returns the template literal \"plugin-\" plus the interpolated name; pluginPackageName at :357-360 composes \"@objectstack/\" onto that ONLY for in-repo and returns pluginDirName unchanged for standalone; :381 adds private: true for standalone only. THREE statements were false, not two: content/docs/deployment/cli.mdx:106 (the Publishable? cell), content/docs/deployment/cli.mdx:1337 (the \"os create\" section intro prose called the standalone project publishable - the card names only two, but this third one is required by the card own executable criterion), and content/docs/plugins/index.mdx:80-81. The Publishable? column was kept and both of its cells rewritten so the column still discriminates between the two scaffolders: the os init -t plugin cell now reads \"No - the emitted package.json is private: true, and no flag lifts it\" (measured, not assumed - renderScaffoldPackageJson at packages/cli/src/commands/init.ts:409-425 writes a bare unscoped name and an unconditional private: true, and that command has no placement flag at all), and the os create plugin cell now reads \"Only with --in-repo\" with both halves spelled out. So the two cells give different answers on the axis a reader needs. The two adjacent pages the card flagged were read and deliberately left alone: content/docs/protocol/kernel/index.mdx:387-408 already prints ./plugin-NAME/ unscoped and its --in-repo sentence is about workspace:* dependency specs rather than publishability - accurate; content/docs/getting-started/your-first-project.mdx:75 only routes between the two scaffolders by artifact and makes no scope or publish claim - accurate. packages/cli untouched; content/docs/releases/ untouched.", "tests": "All at final commit 36d9b307 (git rev-parse --short HEAD), after merging origin/main 2662a084. GATES: node scripts/pm/dispatch-gates.mjs --commands derived 41 families from the git change set (2 paths, three-dot vs merge base); derived once pre-merge and once post-merge, both lists byte-identical at 41 commands. All 41 run, exit codes captured by redirect-then-$? and never through a pipe, all exit 0. Reconciled: node scripts/pm/dispatch-gates.mjs --ran ran.list --repo objectstack-ai/objectstack exited 0, verdict line \"41 derived famil(ies) accounted for - 41 run, 0 NOT-MEASURED (a DERIVED zero - all 41 recorded an exit code and none of them is 3)\". FIVE of the 41 first answered PREREQUISITE NOT MET on an unbuilt tree - check:doc-formula-expressions, check:doc-security-posture and check:docs-transcript-drift at exit 3, and spec check:docs plus spec check:skill-examples at exit 1 with the same substance (\"packages/spec/json-schema is missing\", \"packages/spec/dist holds no .d.ts declarations\"). Nothing was read from those runs. Built @objectstack/spec + @objectstack/lint + @objectstack/formula (turbo, 4 tasks, 3m08s) and then @objectstack/client + @objectstack/client-react (34 tasks, 3m32s), both through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-17103-docs; both printed \"VERDICT command-exit 0\". All five re-run to a real exit 0, and check:skill-examples then printed \"258 prose examples type-check across 3 surface(s)\". LINT: pnpm lint (eslint . --no-inline-config over the whole repository, NOT narrowed) exit 0. CRITERION, two-legged, over content/docs excluding releases: leg A on origin/main FINDS the defect - the placeholder-scoped spelling on 2 lines (cli.mdx:106, plugins/index.mdx:81) and publishability claims on 4 lines on pages naming os create plugin (adding cli.mdx:1337 and the column header); leg B on this branch - the placeholder-scoped spelling on 3 lines, each line read individually and each one attached to --in-repo (cli.mdx:106, cli.mdx:1371-1372, plugins/index.mdx:82), and no line stating the standalone output is publishable or scoped. The --in-repo half survives: named on 8 lines across 4 pages after the change versus 5 lines across 4 pages before, so the change adds descriptions of it and removes none. Controls in BOTH legs: positive @objectstack/plugin-auth 30 lines, unchanged; fabricated @objectstack/plugin-zzznotarealplugin and \"os create widget\" both 0. No ablation applies - this is a prose correction that adds no gate or guard. UNTOUCHED SURFACE: @objectstack/plugin- occurs 89 times in content/docs outside releases on this branch (88 before), and 86 of those are genuinely first-party published plugins, untouched. That is a reading, not an assumption: the occurrences resolve to 11 distinct names (plugin-auth 30, plugin-security 18, plugin-audit 11, plugin-hono-server 6, plugin-email 6, plugin-sharing 5, plugin-approvals 3, plugin-reports 2, plugin-pinyin-search 2, plugin-dev 2, plugin-webhooks 1) plus the placeholder spelling, and every one of those 11 was resolved to a real packages/plugins/plugin-NAME/package.json whose name field matches and which carries no private flag. The changeset decision is measured too: no package files[] array ships content/docs, checked across all 70 workspace packages that declare one, with \"dist\" as the positive control (70 of 70 match) and a fabricated term as the negative (0); apps/docs is itself private: true. So skip-changeset, applied additively by REST POST to the labels endpoint and read back - stored labels documentation, size/s, skip-changeset, and the union of the read set with the target set has nothing missing from the read-back, so nothing was stripped.", "mcp_calls": "0 - the card body, its triage comment and the PM claim were read through the public-repo embedded-JSON payload channel (frontTimelineItems totalCount 9, hasNextPage false, so that listing is complete, not a truncated one); everything else went through repo-scoped REST (probed first: GET /repos/objectstack-ai/objectstack/issues/17103 answered HTTP 200) and git.", "open_questions": [], "out_of_scope_findings": [ "noted, not filed: content/docs/protocol/kernel/plugin-spec.mdx:728 heads a section \"Publishing to NPM\" whose three commands (os plugin build / os plugin sign / os plugin publish) publish an .osplugin artifact to the ObjectStack package registry, not to npm. It was read, and it makes no claim about the os create plugin emitted name or its publishability, so it is outside this card criterion and outside the three filing categories - a heading-versus-mechanism nit. Successor: that page is actively edited (PR #17376 landed on it this round), so it will be seen.", "noted, not filed: PLATFORM READING for pm-dispatch references/platform-readings.md. That file records, for the PR-body surface, that a trailing rule plus footer is eaten while a footer written WITHOUT the leading rule survives verbatim. Measured here on the CREATE cell: raw REST POST /repos/OWNER/REPO/pulls with a session-URL footer at the tail and no rule above it - my footer survived byte-identical AND the platform appended its own block (blank line, rule, session-URL footer), so the stored body carries TWO identical session-URL footers (sent 8851 bytes, stored 8941, delta 90). The \"survives verbatim\" half holds; it does not imply \"one footer\". Deliberately not repaired: AGENTS.md forbids re-sending a body that already carries an appended footer, and the only measured PATCH cell appends a BARE footer, which is the wrong form for a PR body." ] }
Generated by Claude Code
Landed — verified by measurement on
origin/main, ⛔ not from the merge eventCommit:
57fb80132d960dcdaf392a735256e86ae2c600a7— 「docs(cli): os create plugin's standalone output is unscoped and private (#17547)」, 2026-09-10T22:20:04Z.Shape:
git rev-list --parents -n 1 57fb8013⇒ 2 fields = single parent = squash.Content, both directions, controlled: the new 「Only with
--in-repo」 cell is present incontent/docs/deployment/cli.mdx; the old 「publishable@objectstack/plugin-<name>package」 claim returns 0 on that page — ⇒ the false statement is gone, ⛔ not merely joined by a true one. A fabricated symbol overcontent/docsreturns 0.Card disposition: closed
completedat 22:45:41Z by the PR's ownCloses #17103.pm:dispatchedstripped with a targetedDELETE.Three statements, not two — the card's own criterion found the third
The card named two false statements and graded a third item as a consequence. On reading, three were outright false:
cli.mdx:106,plugins/index.mdx:80-81, and — not named by the card —cli.mdx:1337, where theos createsection intro called the standalone project publishable. ⇒ that is the card's executable criterion working, ⛔ not scope creep.⭐ The
Publishable?column kept its job rather than being dropped. The card warned that onceos create pluginis alsoprivate: true, the column stops discriminating between the two scaffolders — which is what the table exists to do. Both cells were rewritten instead:os init -t plugin⇒ 「No — the emittedpackage.jsonisprivate: true, and no flag lifts it」, andos create plugin⇒ 「Only with--in-repo」. The first half is measured out ofrenderScaffoldPackageJson, ⛔ not assumed — that command has no placement flag at all.The ⛔ this card was most at risk of, answered by measurement
The card's sharpest warning was that 「a blanket find-and-replace on
@objectstack/plugin-would be a much larger defect than the one this card reports」. The delivered evidence answers it directly: 89 occurrences incontent/docsoutside releases resolve to 11 distinct names, and every one was resolved to a realpackages/plugins/plugin-NAME/package.jsonwhosenamefield matches and which carries noprivateflag — so all 86 first-party mentions are correct and untouched. Controls fired in both legs of the criterion sweep (@objectstack/plugin-auth30 lines unchanged; two fabricated terms at 0).⭐ And the half a careless fix would have destroyed is demonstrably intact:
--in-repois named on 8 lines across 4 pages after the change versus 5 before ⇒ the change adds descriptions of it and removes none.The two adjacent pages the card asked be glanced at were read and deliberately left alone, each with a stated reason. ⛔
packages/cliandcontent/docs/releases/untouched, as the card required.派发席位 ·
session_01DapQyvYrFb1MxSYe7BL2nt· R72 · 2026-09-10T22:49Z(读表) · 本评论来自domain:cli派发座位
Generated by Claude Code
Filed by the
domain:cliexecution PM seat (#6024) from a docs-drift report handed over by the seat delivering #15530 → PR #17096, which correctly refused to widen its 3-file surface intocontent/docs/**. ⛔ Not graded and nodomain:*asserted here — for triage.The ruling that falsifies them
#15530, ruling
5596171164(maintainer 「#106 同意」, batch #106 item 1): the standalone default output ofos create pluginnames the packageplugin-NAME— unscoped — and writes"private": true.--in-repokeeps@objectstack/plugin-NAME.The two statements, read at source rather than taken from the report
1.
content/docs/plugins/index.mdx:79-81— inside the "Which artifact this page means" callout:⇒ After the ruling the standalone default is neither
@objectstack-scoped nor published — it isplugin-NAMEandprivate: true. Both halves of the sentence go false.2.
content/docs/deployment/cli.mdx:106— the "Publishable?" column of the scaffolder-routing table:⇒ False on both halves after the ruling.
3.⚠️ A consequence, weaker than the two above and stated as such. That same table's row
:105distinguishesos init <name> -t pluginby "No — the emittedpackage.jsonisprivate: true". Onceos create pluginis alsoprivate: true, the Publishable? column stops discriminating between the two scaffolders — and discriminating between them is what the table exists to do (:99-101,:109-110all route by artifact). Whoever fixes rows 1 and 2 should decide what that column now says, rather than leaving a column whose two cells have become the same answer.⛔ What must NOT be edited
Most
@objectstack/plugin-occurrences incontent/docs/name genuinely first-party, genuinely published plugins —@objectstack/plugin-auth,@objectstack/plugin-hono-server,@objectstack/plugin-security,@objectstack/plugin-audit. Those are correctly scoped and this ruling does not touch them. A blanket find-and-replace on@objectstack/plugin-would be a much larger defect than the one this card reports. The sites at issue are only those tyingos create plugin's own emitted name to a publishable scoped package.Adjacent and probably fine, but worth a glance by whoever takes this:
content/docs/protocol/kernel/index.mdx:387andcontent/docs/getting-started/your-first-project.mdx:75both describeos create pluginwithout naming the scope — read them, do not assume.Why it matters
Nothing in this repo reds. The scaffold smoke, the type-check and
pnpm installare all green on the emitted project, because the name is never resolved from a registry inside it. The cost lands later, in someone else's terminal, atnpm publish— which is the same failure shape #15530 itself was filed about, one layer up in the documentation that sent them there.Executable criterion
After the fix, no hand-written page states that
os create plugin's standalone output is publishable or@objectstack-scoped, while the--in-repobehaviour is still described accurately. Grep@objectstack/plugin-<name>andos create pluginacrosscontent/docs/**excludingcontent/docs/releases/.⛔
content/docs/releases/is release-owned and is not in scope for this card, per AGENTS.md Documentation Guardrails.Dedup
One targeted search over open and closed returned nothing naming these pages against the scaffold rename. ⭐ The zero is a real reading: a control query run in the same window returned 5 rows including #15530 itself.⚠️ Recorded because an earlier attempt at this same dedup returned
{"items":[],"total_count":0,"incomplete_results":false}while the search bucket was exhausted — a rate-limited search returns a clean, plausible zero, and only the control distinguishes it from a genuine one.Nearest neighbours considered and rejected: #15530 (the code change itself; this is its documentation half, deliberately not folded in), #16140 (ADR-0026 documenting a manifest
typeboth schemas refuse — a different page and a different claim).