Measured while implementing #11050 (the corpus-wide route-spelling detector). Filed unassigned; an observation from that card's population sweep, not a claim on anyone's time.
What was measured
packages/triggers/trigger-api/src/plugin.ts exports HOOKS_PATH = '/api/v1/automation/hooks/:flowName/:hookId' (line 25) and, per its own header, mounts POST on that path straight on the host Hono app (resolved via the http-server service) — the autonomous-mount pattern, bypassing both RestServer.getRoutes() and the dispatcher.
The route appears in no ledger:
- not in
packages/rest/src/rest-route-ledger.ts (its conformance test enumerates RestServer.getRoutes(), which never sees this mount); - not in
packages/runtime/src/route-ledger.ts (not a dispatcher branch, and NON_DISPATCH_MOUNT_PREFIXES pins only dispatcher-plugin's own host mounts); - no per-package ledger under
packages/triggers/trigger-api/src/ (grep -rn 'automation/hooks' over all four in-repo route ledgers: zero hits at a6eca9223).
It is also published teaching surface: skills/objectstack-automation/SKILL.md teaches the path twice (lines 60 and 676).
Why this is the known defect class, not a style gap
The runtime ledger's own header: a route surface a package serves that nobody reviewed the SDK disposition of is precisely what #3528 was. Services that mount autonomously on the host server carry per-package ledgers + guards since #3636 (service-storage, service-i18n); the /.well-known/objectstack case in #7526 was the same shape — reachable, documented, and in no ledger until a gate read it off a booted server. trigger-api's mount is that case again: reachable, HMAC-gated, taught in a published skill, and carrying no reviewed disposition (SDK? server-only? public?).
Secondary effect, measured on #11050's detector: the detector's authority is the ledger union, so this route can only ever land in its unmatched listing — every CI run records it as a shape no ledger declares, until a ledger owns it.
Suggested shape (the deciding precedent is #3636)
A per-package trigger-api route ledger + guard in the #3636 pattern (one row today), with the disposition question — this is an external-integration door like ADR-0121 endpoints, probably server-only/public-with-HMAC rather than SDK surface — answered in review rather than assumed.
Generated by Claude Code
Generated by Claude Code
Measured while implementing #11050 (the corpus-wide route-spelling detector). Filed unassigned; an observation from that card's population sweep, not a claim on anyone's time.
What was measured
packages/triggers/trigger-api/src/plugin.tsexportsHOOKS_PATH = '/api/v1/automation/hooks/:flowName/:hookId'(line 25) and, per its own header, mountsPOSTon that path straight on the host Hono app (resolved via thehttp-serverservice) — the autonomous-mount pattern, bypassing bothRestServer.getRoutes()and the dispatcher.The route appears in no ledger:
packages/rest/src/rest-route-ledger.ts(its conformance test enumeratesRestServer.getRoutes(), which never sees this mount);packages/runtime/src/route-ledger.ts(not a dispatcher branch, andNON_DISPATCH_MOUNT_PREFIXESpins only dispatcher-plugin's own host mounts);packages/triggers/trigger-api/src/(grep -rn 'automation/hooks'over all four in-repo route ledgers: zero hits ata6eca9223).It is also published teaching surface:
skills/objectstack-automation/SKILL.mdteaches the path twice (lines 60 and 676).Why this is the known defect class, not a style gap
The runtime ledger's own header: a route surface a package serves that nobody reviewed the SDK disposition of is precisely what #3528 was. Services that mount autonomously on the host server carry per-package ledgers + guards since #3636 (
service-storage,service-i18n); the/.well-known/objectstackcase in #7526 was the same shape — reachable, documented, and in no ledger until a gate read it off a booted server. trigger-api's mount is that case again: reachable, HMAC-gated, taught in a published skill, and carrying no reviewed disposition (SDK? server-only? public?).Secondary effect, measured on #11050's detector: the detector's authority is the ledger union, so this route can only ever land in its
unmatchedlisting — every CI run records it as a shape no ledger declares, until a ledger owns it.Suggested shape (the deciding precedent is #3636)
A per-package
trigger-apiroute ledger + guard in the #3636 pattern (one row today), with the disposition question — this is an external-integration door like ADR-0121 endpoints, probablyserver-only/public-with-HMAC rather than SDK surface — answered in review rather than assumed.Generated by Claude Code
Generated by Claude Code