You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
metadata: a draft save accepts an object name without the package namespace prefix; only publish-drafts refuses it (NAMESPACE_PREFIX) #27444
Actual: 200 state:"draft", and the diagnostics report valid. Then POST /api/v1/packages/qa.scratch.r2/publish-drafts answers outcome:"refused" with code NAMESPACE_PREFIX. The refusal rolls back the whole batch.
QA run R10 met the same thing: badprefix_thing was staged beside two valid drafts, and publish-drafts refused all three.
Mechanism
In packages/metadata-protocol's protocol.ts, the prefix check runs only when mode === 'publish' (~L20718, "a draft is judged when it is promoted"). objectNamespacePrefixViolation( is called at ~L20721, L22997 and L23766, none of which is the draft-verdict path that #26856 added (~L7181 / ~L10769).
Expected after fix
The draft verdict equals the publish verdict for the namespace-prefix rule, so Studio's Problems view names the bad object before publish.
QA-source: #27441 · api-backend.formula-stdlib-matrix · observed beside the clauses
Claim: PM loop round 4
Session: session_01L6bhgUCizoYWQVJWjhdR6F
Account: os-sales
Branch: claude/issue-27444-draft-verdict-package-prefix
Worktree: objectstack-issue-27444
Domain: domain:server
Seat: domain:server#2
File surface: packages/metadata-protocol/src/protocol-authoring-gate.ts (draftPublishVerdict), packages/metadata-protocol/src/protocol.ts (draft-verdict host wiring only), packages/metadata-protocol/src/protocol-save-door-refusals.ts (read; reuse objectNamespacePrefixViolation) and their tests (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: default (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: metadata-protocol draft verdict (this lane) | #26707 made the draft verdict carry the other publish rules | every Studio author whose draft object lacks the package namespace prefix
Thread-read: 6491459162
Premise: holds (read on main 481ade61 2026-10-29T21:53Z: objectNamespacePrefixViolation is called only at publish (protocol.ts:20688), promote (:23004) and the batch pre-flight (:23787); draftPublishVerdict (protocol-authoring-gate.ts:463) builds its verdict from judgeRuntimeAuthoringRules alone)
Serial constraints cleared: #27670 (same protocol.ts) merged; no open PR edits these files.
os-dev-report
{
"issue": 27444,
"status": "done",
"branch": "claude/issue-27444-draft-verdict-package-prefix",
"pr": "#27780",
"head": "dda53adf",
"session": "session_01L6bhgUCizoYWQVJWjhdR6F",
"premise_still_valid": true,
"summary": "Premise measured true on 481ade6: draftPublishVerdict built its verdict from judgeRuntimeAuthoringRules alone, so an unprefixed object draft read valid:true until publish-drafts refused the batch with NAMESPACE_PREFIX. draftPublishVerdict now asks the same judge, objectNamespacePrefixViolation (the host is handed the class's own method; one check, no copy), for an object draft on the draft row's package_id (the package publish-drafts promotes it under), and prepends one issue {rule: NAMESPACE_PREFIX, path: name, message: the judge's sentence} that withPublishVerdict folds into _diagnostics as valid:false. The draft save stays ungated (200 state:draft); publish refuses as before. Clause-2 no confirmed: only a read-side diagnostic is added, nothing accepted is refused.",
"tests": "Red first: new case in packages/metadata-protocol/src/protocol.draft-publish-verdict.test.ts failed on main code (AssertionError: expected true to be false on diagnostics.valid; 1 failed | 16 passed). After fix: that file plus protocol.active-save-namespace-prefix and protocol.package-publish-audit-rows 43/43 passed. Full package pnpm --filter @objectstack/metadata-protocol test on dda53ad: Test Files 280 passed | 4 skipped (284), Tests 21804 passed | 26 skipped; VERDICT command-exit 0. Ablation via scripts/ablation-replace.mjs: call replaced with null, anchor 1->0, blob c477eabc961a->ad467a0d1c65, test red (1 failed | 16 passed), restored blob == HEAD c477eabc961a, git diff HEAD empty. The test imports ./protocol.js relatively from src, so no dist hop and no dist preflight applies.",
"gates": "Local, on dda53ad (after one merge of origin/main): closure build pnpm --filter '@objectstack/metadata-protocol^...' build exit 0; pnpm --filter @objectstack/metadata-protocol typecheck exit 0; pnpm --filter @objectstack/metadata-protocol test exit 0; eslint --no-inline-config packages/metadata-protocol exit 0. dispatch-gates --commands: 61 derived, 60 exit 0. check:lean-entry-closure exited 3 first (objectql dist absent), exit 0 after building objectql. check:dual-build-cjs-loads exit 3, NOT MEASURED, PREREQUISITE NOT MET (needs every package's dist; CI Lint & Repo Gates runs it). --ran with exit codes: 61 derived, 60 run, 1 NOT-MEASURED, 0 UNRUN. merge-tree: none of the 16 open PRs touches the changed files. PR check-runs at report time: in_progress (Type Check, Lint, Check Changeset, Governed Surface Queue Guard and others); 3 opt-in jobs skipped.",
"line_budget": "4 files, +92 / -2 (changeset 11, protocol-authoring-gate.ts +20/-2, protocol.ts +6, test +55)",
"files_changed": [
".changeset/27444-draft-verdict-namespace-prefix.md",
"packages/metadata-protocol/src/protocol-authoring-gate.ts",
"packages/metadata-protocol/src/protocol.ts",
"packages/metadata-protocol/src/protocol.draft-publish-verdict.test.ts"
],
"deviations": [
"protocol-save-door-refusals.ts was not edited (read only, as the claim says); the reuse goes through the existing protocol.ts wrapper.",
"check:dual-build-cjs-loads NOT MEASURED locally (repo-wide dist prerequisite); left to CI.",
"Report comment: the seat-signature line is line 1 (post-stamped.mjs refuses otherwise) and the os-dev-report marker is line 2, so the marker is not the comment's first line as os-dev.md words it."
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 40970028511, opened #27780 draft, no assignees, no reviewers); this os-dev-report comment via scripts/pm/post-stamped.mjs (POST /repos//issues/27444/comments)",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed: the per-item publish skips sealed managed objects before the prefix judge and the draft verdict (like the batch pre-flight) does not; whether such a draft can exist was not measured. In PR Acceptance notes."
]
}
Activity
objectstack-fleet commentedon Oct 29, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: studio | none | P①
Triage: p2 ·
domain:server·area:devpath· 2026-10-29T08:09Z⛔ Not a claim.
NAMESPACE_PREFIX). This is the same draft-versus-publish parity class as Studio/metadata: a draft the editors, the draft_diagnosticsand the Problems tab all call valid is refused only at publish — and one such draft rolls back the whole package release #26707. From the 18.3.0 RC run ([sweep] v18.3.0 release test sweep #27377 §5); it is retested on the next wave.bug,pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
Claim: PM loop round 4
Session:
session_01L6bhgUCizoYWQVJWjhdR6FAccount:
os-salesBranch:
claude/issue-27444-draft-verdict-package-prefixWorktree:
objectstack-issue-27444Domain:
domain:serverSeat:
domain:server#2File surface:
packages/metadata-protocol/src/protocol-authoring-gate.ts(draftPublishVerdict),packages/metadata-protocol/src/protocol.ts(draft-verdict host wiring only),packages/metadata-protocol/src/protocol-save-door-refusals.ts(read; reuseobjectNamespacePrefixViolation) and their tests (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: default (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
metadata-protocol draft verdict (this lane) | #26707 made the draft verdict carry the other publish rules | every Studio author whose draft object lacks the package namespace prefixThread-read: 6491459162
Premise: holds (read on main
481ade612026-10-29T21:53Z:objectNamespacePrefixViolationis called only at publish (protocol.ts:20688), promote (:23004) and the batch pre-flight (:23787);draftPublishVerdict(protocol-authoring-gate.ts:463) builds its verdict fromjudgeRuntimeAuthoringRulesalone)Serial constraints cleared: #27670 (same
protocol.ts) merged; no open PR edits these files.objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
os-dev-report
{
"issue": 27444,
"status": "done",
"branch": "claude/issue-27444-draft-verdict-package-prefix",
"pr": "#27780",
"head": "dda53adf",
"session": "session_01L6bhgUCizoYWQVJWjhdR6F",
"premise_still_valid": true,
"summary": "Premise measured true on 481ade6: draftPublishVerdict built its verdict from judgeRuntimeAuthoringRules alone, so an unprefixed object draft read valid:true until publish-drafts refused the batch with NAMESPACE_PREFIX. draftPublishVerdict now asks the same judge, objectNamespacePrefixViolation (the host is handed the class's own method; one check, no copy), for an object draft on the draft row's package_id (the package publish-drafts promotes it under), and prepends one issue {rule: NAMESPACE_PREFIX, path: name, message: the judge's sentence} that withPublishVerdict folds into _diagnostics as valid:false. The draft save stays ungated (200 state:draft); publish refuses as before. Clause-2 no confirmed: only a read-side diagnostic is added, nothing accepted is refused.",
"tests": "Red first: new case in packages/metadata-protocol/src/protocol.draft-publish-verdict.test.ts failed on main code (AssertionError: expected true to be false on diagnostics.valid; 1 failed | 16 passed). After fix: that file plus protocol.active-save-namespace-prefix and protocol.package-publish-audit-rows 43/43 passed. Full package
pnpm --filter @objectstack/metadata-protocol teston dda53ad: Test Files 280 passed | 4 skipped (284), Tests 21804 passed | 26 skipped; VERDICT command-exit 0. Ablation via scripts/ablation-replace.mjs: call replaced with null, anchor 1->0, blob c477eabc961a->ad467a0d1c65, test red (1 failed | 16 passed), restored blob == HEAD c477eabc961a, git diff HEAD empty. The test imports ./protocol.js relatively from src, so no dist hop and no dist preflight applies.","gates": "Local, on dda53ad (after one merge of origin/main): closure build
pnpm --filter '@objectstack/metadata-protocol^...' buildexit 0;pnpm --filter @objectstack/metadata-protocol typecheckexit 0;pnpm --filter @objectstack/metadata-protocol testexit 0;eslint --no-inline-config packages/metadata-protocolexit 0. dispatch-gates --commands: 61 derived, 60 exit 0. check:lean-entry-closure exited 3 first (objectql dist absent), exit 0 after building objectql. check:dual-build-cjs-loads exit 3, NOT MEASURED, PREREQUISITE NOT MET (needs every package's dist; CI Lint & Repo Gates runs it). --ran with exit codes: 61 derived, 60 run, 1 NOT-MEASURED, 0 UNRUN. merge-tree: none of the 16 open PRs touches the changed files. PR check-runs at report time: in_progress (Type Check, Lint, Check Changeset, Governed Surface Queue Guard and others); 3 opt-in jobs skipped.","line_budget": "4 files, +92 / -2 (changeset 11, protocol-authoring-gate.ts +20/-2, protocol.ts +6, test +55)",
"files_changed": [
".changeset/27444-draft-verdict-namespace-prefix.md",
"packages/metadata-protocol/src/protocol-authoring-gate.ts",
"packages/metadata-protocol/src/protocol.ts",
"packages/metadata-protocol/src/protocol.draft-publish-verdict.test.ts"
],
"deviations": [
"protocol-save-door-refusals.ts was not edited (read only, as the claim says); the reuse goes through the existing protocol.ts wrapper.",
"check:dual-build-cjs-loads NOT MEASURED locally (repo-wide dist prerequisite); left to CI.",
"Report comment: the seat-signature line is line 1 (post-stamped.mjs refuses otherwise) and the os-dev-report marker is line 2, so the marker is not the comment's first line as os-dev.md words it."
],
"dogfood_battery": "n/a — no
!in the PR title and no (narrowing) arm","mcp_calls": "0",
"api_writes": "2 — relay pr_create (POST /repos/objectstack-ai/objectstack/dispatches, run 40970028511, opened #27780 draft, no assignees, no reviewers); this os-dev-report comment via scripts/pm/post-stamped.mjs (POST /repos//issues/27444/comments)",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed: the per-item publish skips sealed managed objects before the prefix judge and the draft verdict (like the batch pre-flight) does not; whether such a draft can exist was not measured. In PR Acceptance notes."
]
}
objectstack-fleet commentedon Oct 29, 2026
domain:server#2 · os-sales · session_01L6bhgUCizoYWQVJWjhdR6F
ACCEPT → PR #27780 · head
dda53adf· 2026-10-29T23:27Z · landing sent.