Skip to content

[Decision] Retire the @capabilities hook-body directive, or keep documenting it? Measured: it reaches the extractor from NO ordinary authoring path (ADR-0049 enforce-or-remove) #10917

Description

@os-elon

Filed unassigned from the domain:cli lane execution seat (session session_019bmVFqoQPq63zhKrxdYG1r), lifting an open_question out of PR #10912 (issue #10678) so it is graded on its own rather than buried in a delivery report.

This is a decision about the published authorable surface, so it is the maintainer's. Nothing here is being proposed for action by a seat.

What was measured

os build (via bundleRequire) runs esbuild on every config regardless of extension, and esbuild strips // line comments before the handler is ever a runtime value that String(fn) can read. The dev on #10678 tested the real authoring shapes with the real CLI against mkdtemp projects:

authoring shape@capabilities directive reaches the extractor?
objectstack.config.tsno
objectstack.config.jsno
objectstack.config.mjsno
handler imported from a local ./handlers.jsno

A documented feature does nothing on every path an app author would use. The build still succeeds, silently, shipping inferred capabilities alone.

⚠️ Triage's own dispatch note on #10678 stated the directive "only survives pre-bundled JS". That is more generous than reality — and PR #10912's dev flagged that documenting it verbatim would have pointed readers at a .js file that also does not work, i.e. a fresh false claim of exactly the class #10678 exists to close. The docs shipped in that PR state the measured reach instead.

The three options as the dev framed them

  • A — keep docs-truth as shipped (status quo after PR fix(cli): report only what the hook-body build gates establish #10912). The directive stays, documented as not reaching the build, with body.capabilities named as the escape hatch that is measured to survive. Zero surface change; leaves a directive that does nothing and that a reader may still copy.
  • B — retire it. Delete the override branch in extract-hook-body.ts, the docs block, and the two masking unit tests. body.capabilities already covers the need. This is a REMOVAL from the published surface.
  • C — give it a real surface. A hook-level config property alongside body. Makes the intent expressible on the real path, but expands the public authorable surface — which triage explicitly fenced as a maintainer decision.

The dev recommends B, falling back to A. ⛔ I am not endorsing a direction; the recommendation is recorded because it carries evidence, not to substitute for a ruling.

Why this is worth a decision rather than leaving it at A

⭐ The strongest argument in the report is the AI-authoring one, and it is specific to how this platform is used: an agent writing a metadata app reads the docs, copies the comment, and receives capabilities [] with no error and no warning. The failure then surfaces much later as a sandbox denial, far from its cause. A directive that cannot be typed wrongly-but-visibly is a directive that teaches a wrong convention silently.

Against that: B is a removal, and removals from a published surface are exactly what ADR-0049's enforce-or-remove framing and the spec-property-retirement playbook exist to govern. Both look directly applicable if B is chosen, and neither is a seat's call to invoke unilaterally.

Scope notes

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions