MalloryEstate Briefing
M·011Approved
← All briefings

Context & Investigations

Capability Self-Awareness

A single hand-curated capability registry that generates both Mallory's cached persona self-description and, later, the UI's copy — so he never denies something he can actually do.

Dated 2026-06-12Programme Context & Investigations

Situation

Wave 1-A. Mallory's sense of what he can and can't do is hardcoded in two disconnected places, and both have drifted from reality: src/persona.ts still denies capabilities the system has since grown (deep digs, agenda/tasks/activity/status, earlier conversation history), and web/src/routes/+page.svelte's Briefing help sheet hand-writes a separate, independently-drifting description for the user.

There is no machine-readable manifest of capabilities — the only structured list is KNOWN_SIGNALS in orchestrator.ts. The goal is one source of truth that both the persona (now) and the UI (Wave 1-B/C, later) read from, so Mallory never denies a capability he has, and is honest in the moment about signal-backed capabilities that depend on a fresh push.

Key decisions

Curated registry, not auto-derived

src/capabilities.ts is hand-authored — raw routes like /loops/item/toggle are too granular to describe in the persona's voice.

Hybrid: static claim + dynamic note

A pure renderCapabilities() builds the constant "can/not yet" passages that stay inside the cached persona block; a per-turn, non-cached note layers on live signal freshness ("agenda is fresh as of 08:10").

Cache correctness preserved

renderCapabilities() reads only the static registry — no per-request data — so it can't bust the existing prompt-cache prefix.

Near-free dynamic layer

The availability note is derived from signals loadSignals already fetched that turn — no new fetch, no cache impact.

Drift guard deferred

A test asserting every signal/route maps to a registry entry is explicitly deferred to a future round at Alex's request, noted as a known follow-up.

Architecture

One new registry module feeds a scoped edit to the persona and a small injection point in the per-turn context assembly.

src/capabilities.ts
CAPABILITIES registry (id, built, claim, backing, liveness) + renderCapabilities() + the dynamic availability-note builder.
src/persona.ts
Replaces the hardcoded can't-do block with the generated static passages, still inside the cached system prompt.
src/orchestrator.ts / src/context.ts
Inject the per-turn availability note into the existing non-cached context block, alongside signal injection.

Risks & guardrails

Cache correctness

Mitigated by keeping renderCapabilities() a pure function of the static registry only.

Voice quality

claim strings are full in-voice phrases joined into prose by the renderer, not a bulleted list — reviewed in the plan.

Dynamic note verbosity

Kept to one short line per turn so it doesn't bloat every response.

Signal-key duplication

KNOWN_SIGNALS in orchestrator.ts lists signal keys independently of the registry; they match today but could silently diverge — folded into the deferred drift-guard follow-up.

Delivery

Registry + renderer

CAPABILITIES inventory and renderCapabilities().

Persona integration

Fold the generated passages into the cached persona block.

Dynamic note builder

capabilityAvailabilityNote() from fresh/stale/missing signal state.

Signal-read reporting

loadSignals reports which requested signals were unavailable.

Chat wiring

Inject the availability note in chat.ts, non-cached.

Out of scope

Rewiring the UI help-sheet / empty-state (Wave 1-B)The operating-status panel (Wave 1-C)A drift-detecting test for registry/signal/route parity (deferred)Adding any new capability — this only describes existing ones accurately
spec · docs/superpowers/specs/2026-06-12-capability-self-awareness-design.md
plan · docs/superpowers/plans/2026-06-12-capability-self-awareness.md
Mallory · Estate briefing