Found while implementing #9326 (PR #9425), by the sibling sweep that card's dispatch fence asked for. Filed rather than ridden on that PR, per the fence: "Any sibling is a finding to file, not a rider."
The measurement
packages/rest/src/rest-server.ts, the GET /meta/:type/:name/audit handler (auditMetaItem probe, around line 5296 on origin/main @ 51a46a440 — locate it by text, not by this line number; this file absorbs several merges a day):
if(typeof(pasany).auditMetaItem!=='function'){res.json({events: []});return;}This is the same shape #9326 is about, one route over: a capability gap rendered as a well-formed empty answer. ADR-0110 D3 — a miss and a fault are different facts — and the two facts merged here are "the audit trail was read and this item has no entries" and "this deployment cannot read an audit trail at all".
It is arguably worse than the references case by consequence. The route's own comment describes it as the "compliance trail for the metadata-protection layer ... so Studio's 审计日志 / Audit log tab can show who tried what and whether a lock blocked it". An empty answer there reads as nobody touched this item, which is exactly the claim a compliance reader must not be given on false pretenses.
The sweep this came from, with its control
Every feature-detection limb on the resolved protocol in rest-server.ts, classified by how it answers absence:
| limb | answer on absence |
|---|
getMetaDiagnostics | 501NOT_IMPLEMENTED |
listDrafts | 501NOT_IMPLEMENTED |
migrateStoredMetadata | 501NOT_IMPLEMENTED |
getMetaItemLayered | 501NOT_IMPLEMENTED |
historyMetaItem | 501 (bare-string error, no code — an envelope-debt item, but it does refuse) |
findReferencesToMeta | 200 {references: []} — #9326, fixed in PR #9425 |
auditMetaItem | 200 {events: []} — this card |
Control: the same scan found five limbs that do refuse, so "no sibling" was a possible outcome of this sweep rather than a foregone one. The remaining typeof p.X === 'function' sites in the file (getMetaItems, getObjectSchema, getPackagedObjectBase, getMetaItemLayered under ?layers=) are optional-enrichment fallbacks, not answers to a question the caller asked — a different class, deliberately not listed above.
Reachability, measured the same way #9326's was
auditMetaItem is not a member of RestProtocol (= DataProtocol & MetadataProtocol) and is not declared in packages/spec at all — it is an ADR-0076 D9 server-only extension, which is why the route reaches it through a runtime cast. So the branch is not reachable from any in-repo assembly today (ObjectStackProtocolImplementation is the only registered implementation and defines the method), but it is reachable from any host that implements the declared contract exactly, with no type error. Same reachability profile as #9326.
What would close it
Most likely the same fix #9326 took, which is also what four of its five siblings already do: refuse with 501NOT_IMPLEMENTED in the ADR-0112 nested{ error: { code, message } } envelope that #7035 converged the /meta 501 refusals onto.
Two things worth checking before assuming that, rather than asserting them here:
- Whether the audit route's empty answer is load-bearing for an unprovisioned table. The route's comment says "Empty array on environments where the table is not yet provisioned" — that is a different condition from the missing-method one, handled further down, but a fix should confirm the two are actually separate paths and not conflated. If they are conflated, the honest answer may need to distinguish three states rather than two.
- The envelope ratchets.
check:route-envelope holds rest-server.ts to two shrink-only dialect counts (stringError, siblingCode). The nested shape is counted by neither; the flat sibling-code shape that /layers uses is counted by both, so copying /layers would push a ratchet up.
⚠️ A wire-level coverage discriminator is not the route to take here without a spec decision — that was fenced to packages/spec on #9326 and the same fence applies.
Related
#9326 / PR #9425 (the references limb, same defect class, same file) · #8896 (the empty-accumulator harm shape) · #7035 (the /meta 501 envelope convergence) · ADR-0110 D3 · ADR-0076 D9
Dedup
Searched open issues for auditMetaItem, for capability-gap-as-empty-answer on REST routes, and for the audit route generally. Nearest existing cards are #8747 (auditMetaItem's organizationId scope filter — closed, a different defect on the same method) and #9326 (the references limb). Neither covers the missing-capability limb on the audit route. No duplicate.
Found while implementing #9326 (PR #9425), by the sibling sweep that card's dispatch fence asked for. Filed rather than ridden on that PR, per the fence: "Any sibling is a finding to file, not a rider."
The measurement
packages/rest/src/rest-server.ts, theGET /meta/:type/:name/audithandler (auditMetaItemprobe, around line 5296 onorigin/main@51a46a440— locate it by text, not by this line number; this file absorbs several merges a day):This is the same shape #9326 is about, one route over: a capability gap rendered as a well-formed empty answer. ADR-0110 D3 — a miss and a fault are different facts — and the two facts merged here are "the audit trail was read and this item has no entries" and "this deployment cannot read an audit trail at all".
It is arguably worse than the references case by consequence. The route's own comment describes it as the "compliance trail for the metadata-protection layer ... so Studio's 审计日志 / Audit log tab can show who tried what and whether a lock blocked it". An empty answer there reads as nobody touched this item, which is exactly the claim a compliance reader must not be given on false pretenses.
The sweep this came from, with its control
Every feature-detection limb on the resolved protocol in
rest-server.ts, classified by how it answers absence:getMetaDiagnostics501NOT_IMPLEMENTEDlistDrafts501NOT_IMPLEMENTEDmigrateStoredMetadata501NOT_IMPLEMENTEDgetMetaItemLayered501NOT_IMPLEMENTEDhistoryMetaItem501(bare-stringerror, no code — an envelope-debt item, but it does refuse)findReferencesToMeta200 {references: []}— #9326, fixed in PR #9425auditMetaItem200 {events: []}— this cardControl: the same scan found five limbs that do refuse, so "no sibling" was a possible outcome of this sweep rather than a foregone one. The remaining
typeof p.X === 'function'sites in the file (getMetaItems,getObjectSchema,getPackagedObjectBase,getMetaItemLayeredunder?layers=) are optional-enrichment fallbacks, not answers to a question the caller asked — a different class, deliberately not listed above.Reachability, measured the same way #9326's was
auditMetaItemis not a member ofRestProtocol(= DataProtocol & MetadataProtocol) and is not declared inpackages/specat all — it is an ADR-0076 D9 server-only extension, which is why the route reaches it through a runtime cast. So the branch is not reachable from any in-repo assembly today (ObjectStackProtocolImplementationis the only registered implementation and defines the method), but it is reachable from any host that implements the declared contract exactly, with no type error. Same reachability profile as #9326.What would close it
Most likely the same fix #9326 took, which is also what four of its five siblings already do: refuse with
501NOT_IMPLEMENTEDin the ADR-0112 nested{ error: { code, message } }envelope that #7035 converged the/meta501 refusals onto.Two things worth checking before assuming that, rather than asserting them here:
check:route-envelopeholdsrest-server.tsto two shrink-only dialect counts (stringError,siblingCode). The nested shape is counted by neither; the flat sibling-codeshape that/layersuses is counted by both, so copying/layerswould push a ratchet up.coveragediscriminator is not the route to take here without a spec decision — that was fenced topackages/specon #9326 and the same fence applies.Related
#9326 / PR #9425 (the references limb, same defect class, same file) · #8896 (the empty-accumulator harm shape) · #7035 (the
/meta501 envelope convergence) · ADR-0110 D3 · ADR-0076 D9Dedup
Searched open issues for
auditMetaItem, for capability-gap-as-empty-answer on REST routes, and for the audit route generally. Nearest existing cards are #8747 (auditMetaItem'sorganizationIdscope filter — closed, a different defect on the same method) and #9326 (the references limb). Neither covers the missing-capability limb on the audit route. No duplicate.