Repository navigation
Description
Restart-when: any PR changes the getPublished member of IMetadataService in packages/spec/src/contracts/metadata-service.ts, or a topology ships a non-MetadataManager metadata slot, or any PR touches the /published arities in packages/rest/src/rest-server.ts
Recorded while implementing #8278 (overlay-first resolution on the REST /published arities). The card names this as a latent, independent second failure mode and fences it out of scope; this issue is that fence made durable, plus the one thing #8278's measurement changed about it.
The observation
packages/rest/src/rest-server.ts, both /published route arities, refuses before it reads:
const svc = await this.resolveMetadataService(environmentId, req);
if (typeof (svc as any)?.getPublished !== 'function') {
res.status(501).json({
error: { code: 'NOT_IMPLEMENTED', message: 'metadata.getPublished() is not available in this kernel' },
});
return;
}getPublished is an optional member of IMetadataService with exactly one implementation in the repo (MetadataManager). Its store (publishedDefinition) is written by exactly one caller, MetadataManager.publishPackage, reachable only via POST /packages/:id/publish. So on any topology whose metadata slot is filled by something other than MetadataManager, this route is simply a 501.
What #8278 changed about it — the reason this is worth recording rather than dropping
#8278 puts the state:'active' overlay consult ahead of that arm, so the blast radius is now strictly narrower and the remaining 501 means something more specific than it used to.
Measured, as arms §8 and §9 of packages/rest/src/meta-published-overlay.test.ts:
- §9 — a metadata slot with no
getPublished, and a runtime-published item: now 200, served from the overlay. The optional member is not on that path at all. - §8 — the same slot with a null overlay: still 501, byte-identical to before.
So post-#8278 the 501 no longer means "this kernel cannot answer /published". It means "nothing is runtime-published and this kernel has no code/package store". That is a materially different (and much rarer) condition than the one the message describes.
Why this is a finding and not a bug
No topology in this repo reaches it today — the one implementation is the one that gets wired. Nothing is broken in a shipped configuration. What is recorded is: (a) an optional contract member with one implementation, one writer and one door, which is the shape that rots quietly; and (b) a 501 message that now over-states its own condition.
If someone picks this up
The interesting question is not "add a second implementation" — it is whether getPublished should remain optional at all, or whether the code/package snapshot it reads is still load-bearing now that the ADR-0027 overlay is the authoritative published store for anything authored at runtime. That is a contract question for the spec/metadata owner, not a REST-side patch. The getPublished fallback semantics are deliberate and documented (an existing-but-never-published item answers 200 with its current definition) and must not be collapsed into a 404 by anyone touching this — see #8278's trap section.
Related
#8278 (the overlay-first fix; records this as out of scope) · #8031 / PR #8254 (the dispatcher-side original) · packages/rest/src/rest-server.ts · packages/rest/src/meta-published-overlay.test.ts §8/§9
Generated by Claude Code
Activity
hotlong commentedon Aug 13, 2026
Triage:
findingheld (correctly self-graded — no shipped topology reaches the 501 today), routeddomain:spec, type Task.Anchoring rationale: the load-bearing question the card itself poses — whether
getPublishedremains an optional member ofIMetadataServicenow that the ADR-0027 overlay is the authoritative store for anything runtime-published — lands onpackages/spec/src/contracts/metadata-service.ts(location verified via code search), the spec seat's package. The REST-side 501 message overstatement is a consequence of that contract question, not the fix's landing point, so this does not routedomain:cli.For the spec seat's next finding-triage round: post-#8278 the 501 means "nothing runtime-published and no code/package store" — a much rarer condition than the message claims; weigh that nothing is broken in any shipped configuration when grading. Guard carried from the card: the deliberate
getPublishedfallback semantics (existing-but-never-published ⇒ 200 with current definition) must not be collapsed into a 404 by whoever eventually touches this — see #8278's trap section.本评论来自分诊座位 Routine。
Generated by Claude Code
hotlong commentedon Aug 13, 2026
Concentrated findings round (maintainer-directed, 2026-08-13): HELD (
finding+domain:specunchanged, per the earlier routing).Why held: no shipped topology reaches the 501 (the one
getPublishedimplementation is the one that gets wired), and the load-bearing question — shouldgetPublishedremain an optional member ofIMetadataServicenow that the ADR-0027 overlay is the authoritative runtime-published store — is a contract-shape call that should ride the contract work already in flight rather than open a second front.Named restart conditions: ① the in-flight IMetadataService contract-statement revision (the spec seat's dispatched card on the superseded register ruling) lands — re-read this card against the revised contract text and decide optional-vs-required there; ② any topology ships a non-
MetadataManagermetadata slot (the 501 becomes reachable — at that moment the message's overstatement matters and the reword rides the fix); ③ anyone touches the/publishedarities — the #8278 trap section's fallback semantics (existing-but-never-published ⇒ 200) remain binding on them.Generated by Claude Code
hotlong commentedon Aug 13, 2026
State-machine migration, maintainer-authorized (2026-08-13, live triage session: 「我授权你先迁标签」; semantics on #8449): this card is a graded hold — verdict and restart conditions are in the grading comment(s) above — so
finding→pm:on-hold. Verdict, restart conditions, domain unchanged.Generated by Claude Code
os-zhuang commentedon Aug 19, 2026
Hold released → decision inbox (triage seat, session
session_014qTKTqjme5Fp5BH9iRmy6t, rider-clause audit): restart ① fired the same day the hold was written — the IMetadataService contract-statement revision it named landed as PR #8481 (2026-08-13, ~2.5h after the hold) — and the promised re-read never happened. Re-read done now on origin/main:getPublishedis unchanged and still optional (metadata-service.ts:572), so REST/meta/:type/:name/publishedstill 501s on any topology whosemetadataslot lacks it. What remains is not a code fix but the contract question the hold deferred: optional-vs-required. That is a declared-contract shape change → human floor, soneeds-user-decision(not queue), assigned to the inbox queue per the #9976 protocol.<!-- os-decision-facets -->
/publishedmay 501; a declared verdict (required method, or documented 501 semantics on optional) is checkable either way. Required-method is the louder contract.getPublished.Options: A — keep
getPublishedoptional, declare the 501 in the route's contract/docs (cheapest, honest). B — makegetPublishedrequired on IMetadataService (breaking for custom topologies; louder contract). C — keep optional but have the route degrade togetMeta+published-filter semantics (new behavior; widest change).Recommendation: A, on zero measured pull and scope discipline. Confidence gap: this analysis has not enumerated how many real topologies lack
getPublished(only MetadataManager was checked historically); if every shipped topology already implements it, B costs nothing and is the better contract.Generated by Claude Code
os-zhuang commentedon Aug 19, 2026
Self-correction (same triage session): assignee cleared — the #9976 assign-to-inbox routing was retired by skill PR #9994 (merged 13:00Z today; decision cards are not pushed, the inbox is digested periodically). The
needs-user-decisionlabel and the facet block above are the operative record; nothing else changes.Generated by Claude Code
os-zhuang commentedon Aug 20, 2026
Maintainer ruling recorded (2026-08-20, live decision-inbox session with the triage seat, session
session_01PjAP6vbcsg2yMtvySPv1Qo)Ruled: minimal action. Provenance: maintainer accepted the batch, verbatim: 「其他接受你的建议。」
packages/restserves/meta/:type/:name/publishedfrom the code snapshot too — #8031's fix does not reach the REST transport #8278 condition ("nothing is runtime-published AND this kernel has no code/package store"), not the stale "getPublished is not available in this kernel".getPublishedstays optional onIMetadataService— one implementation, one wiring, no topology reaches the 501 today; no contract movement.packages/restserves/meta/:type/:name/publishedfrom the code snapshot too — #8031's fix does not reach the REST transport #8278 trap section stands.S-tier mechanical; Clause-②: no expected. State transition in the same stroke:
needs-user-decision→pm:queue.Generated by Claude Code
fix(rest): the 501 on /meta/:type/:name/published now states its true…