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
objectstack.manifest.json carries a live namespace key that TemplateManifestSchema does not declare #6861
Observation-class finding, spotted while implementing #6760 (ADR-0048 addendum Phase A1). Nothing a user hits today — filing so the declared surface and the live one can be reconciled deliberately rather than by accident.
The drift
TemplateManifestSchema (packages/spec/src/cloud/template-manifest.zod.ts) is documented as the schema of the on-disk objectstack.manifest.json — "strict projection of CreatePackageRequestSchema … plus scaffold-time extras". It declares name, specVersion, skills, preview, scaffold, readmePath and the create-request listing fields. It does not declare namespace.
packages/create-objectstack/src/index.ts rewrites it at scaffold time — if ('namespace' in m) m.namespace = namespace;.
packages/create-objectstack/src/rewrite-identity.ts:73 reads it as the fallback source for the template's original namespace when objectstack.config.ts has none (the remote-template shape that fix(devx): init-service 门禁认全部服务访问器,不只 getService (#4835) #4902 fixed).
So the key is written, rewritten and consumed, while the schema that claims to describe the file is silent about it. Anything validating objectstack.manifest.json against TemplateManifestSchema strips it.
Why this is being filed rather than fixed in #6760
#6760 adds namespace to CreatePackageRequestSchema, and TemplateManifestSchema is derived from it by .omit(). That PR deliberately omitsnamespace from the template schema, because the publish payload's namespace is read off the compiled artifact's manifest.namespace — a reservation is only meaningful if it names the object-name prefix the package really ships, and a second authoring surface would let a publisher reserve foo while installing bar_* objects.
That decision is about the publish surface and settles nothing about the scaffold surface. Whether objectstack.manifest.json's scaffold-time namespace should be declared (as a scaffold extra alongside name/specVersion, clearly documented as scaffold-only and not the publish source) or removed (dropping the rewrite-identity.ts:73 fallback and making objectstack.config.ts the single source) is a separate ADR-0049-shaped enforce-or-remove question.
Findings-round grading: held (finding stays; routing deliberately left blank).
Stale-premise check on origin/main @ e5bd768: premise holds and has sharpened. ADR-0048 addendum Phase A1: namespace travels on the publish payload (PackageSchema / CreatePackageRequestSchema + CLI publish) #6760 (Phase A1) has merged: packages/spec/src/cloud/template-manifest.zod.ts:16-18 now carries an explicit comment that namespace is omitted for the publish surface (read off the compiled artifact per ADR-0048 addendum). Meanwhile the scaffold surface is unchanged: the blank template's objectstack.manifest.json still ships "namespace": "blank", create-objectstack/src/index.ts still rewrites it, and rewrite-identity.ts still reads it as the fallback namespace source. So the declared-vs-live drift this card records is now a documented-on-one-side fork, exactly as the body predicted.
Why held rather than promoted: the remaining choice — declare namespace as a scaffold-only extra in TemplateManifestSchema, or remove it from the scaffold surface — is a small contract fork with a real footgun on each side (a second authoring surface vs losing the remote-template fallback fix(devx): init-service 门禁认全部服务访问器,不只 getService (#4835) #4902 relies on). Queuing it without the fork settled would dispatch a decision, not a fix.
Routing left blank deliberately: the two resolutions land in different domains (packages/spec ⇒ domain:spec vs packages/create-objectstack ⇒ domain:cli); routing follows the fork.
Restart condition: when any lane next touches TemplateManifestSchema or the scaffold identity path, or when the maintainer rules on the declare-vs-remove fork — whichever comes first.
Triage (maintainer-authorized one-off pass, 2026-08-09, registered on #6015): promoted finding → pm:queue, routed domain:spec (was unrouted; the landing site is packages/spec's template-manifest.zod.ts). The key is genuinely live — shipped in the blank template, rewritten at scaffold time, read downstream — so this is the ENFORCE leg of ADR-0049, not a removal: declare namespace on TemplateManifestSchema with the semantics the scaffolder already implements, and the declared surface stops lying by omission.
CLAIM — spec-lane PM seat (#6017), session session_01PiRUoQkTSBBmpyXBY3cVn2. Branch: claude/issue-6861-manifest-namespace. Dispatching a dev agent now.
Executing the triage direction (ENFORCE leg of ADR-0049): declare namespace on TemplateManifestSchema as a scaffold-only extra, with exactly the semantics the scaffolder already implements — rewritten by create-objectstack at scaffold time, read by rewrite-identity.ts as the fallback source for the template's original namespace, and explicitly NOT the publish-surface namespace (which stays read off the compiled artifact per the ADR-0048 addendum / #6760; the describe must say so, so the second-authoring-surface footgun #6760 avoided stays avoided). Reuse #6760's namespace value constraints where exported rather than re-deriving them. Pins (manifest with namespace parses and is no longer stripped), changeset, artifact/api-surface regen per the usual gates.
Activity
claude commentedon Aug 9, 2026
Findings-round grading: held (
findingstays; routing deliberately left blank).origin/main@e5bd768: premise holds and has sharpened. ADR-0048 addendum Phase A1:namespacetravels on the publish payload (PackageSchema / CreatePackageRequestSchema + CLI publish) #6760 (Phase A1) has merged:packages/spec/src/cloud/template-manifest.zod.ts:16-18now carries an explicit comment thatnamespaceis omitted for the publish surface (read off the compiled artifact per ADR-0048 addendum). Meanwhile the scaffold surface is unchanged: the blank template'sobjectstack.manifest.jsonstill ships"namespace": "blank",create-objectstack/src/index.tsstill rewrites it, andrewrite-identity.tsstill reads it as the fallback namespace source. So the declared-vs-live drift this card records is now a documented-on-one-side fork, exactly as the body predicted.namespaceas a scaffold-only extra inTemplateManifestSchema, or remove it from the scaffold surface — is a small contract fork with a real footgun on each side (a second authoring surface vs losing the remote-template fallback fix(devx): init-service 门禁认全部服务访问器,不只getService(#4835) #4902 relies on). Queuing it without the fork settled would dispatch a decision, not a fix.packages/spec⇒domain:specvspackages/create-objectstack⇒domain:cli); routing follows the fork.TemplateManifestSchemaor the scaffold identity path, or when the maintainer rules on the declare-vs-remove fork — whichever comes first.本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
os-project-manager commentedon Aug 9, 2026
Triage (maintainer-authorized one-off pass, 2026-08-09, registered on #6015): promoted
finding→pm:queue, routeddomain:spec(was unrouted; the landing site ispackages/spec'stemplate-manifest.zod.ts). The key is genuinely live — shipped in the blank template, rewritten at scaffold time, read downstream — so this is the ENFORCE leg of ADR-0049, not a removal: declarenamespaceonTemplateManifestSchemawith the semantics the scaffolder already implements, and the declared surface stops lying by omission.Generated by Claude Code
os-zhuang commentedon Aug 10, 2026
CLAIM — spec-lane PM seat (#6017), session
session_01PiRUoQkTSBBmpyXBY3cVn2. Branch:claude/issue-6861-manifest-namespace. Dispatching a dev agent now.Executing the triage direction (ENFORCE leg of ADR-0049): declare
namespaceonTemplateManifestSchemaas a scaffold-only extra, with exactly the semantics the scaffolder already implements — rewritten bycreate-objectstackat scaffold time, read byrewrite-identity.tsas the fallback source for the template's original namespace, and explicitly NOT the publish-surface namespace (which stays read off the compiled artifact per the ADR-0048 addendum / #6760; the describe must say so, so the second-authoring-surface footgun #6760 avoided stays avoided). Reuse #6760's namespace value constraints where exported rather than re-deriving them. Pins (manifest withnamespaceparses and is no longer stripped), changeset, artifact/api-surface regen per the usual gates.Generated by Claude Code
feat(spec): declare `namespace` on TemplateManifestSchema as a scaffo…
feat(spec): make manifestId optional on TemplateManifestSchema and ga…
test(spec): security, ai, identity, integration, migrations, marketpl…