Bakes in the durable kernel of the agent reflection loop. Passive end-of-run capture of the doer's end-state as structured reflection.v1 data, plus a deterministic diff review risk-floor. The closed calibration / skill-synthesis loop (design §7–§8) stays gated behind Phase-0 experiments P1/P2/P3.
packages/types — reflection.v1 zod schemas + ReflectionSelfReportDto. 10 unit tests.
packages/mosaic/framework — fail-closed Stop hook (reflect-stop-hook.sh) writing the sidecar, registered as hooks.Stop in runtime/claude/settings.json. Strict no-op unless REFLECTION_MODE=solo|orchestrated; never blocks or fails a session, never emits a decision.
Stop hook smoke: fail-closed no-op, solo capture (degraded), self-report merge, re-fire lock guard, empty-diff still writes — all pass, always exit 0.
All bash shellcheck-clean.
Independent code review passed after remediating 2 findings (empty/all-.mosaic diff no longer aborts the write; session_id sanitized before path use).
Activation (post-merge, not a blocker)
Hook activates only when a launcher/profile sets REFLECTION_MODE; unset/off is a strict no-op, so global registration is safe. framework/install.sh rsyncs the hook; the mosaic launcher reflects the updated settings.json into ~/.claude/settings.json.
## Summary
Bakes in the **durable kernel** of the agent reflection loop. Passive end-of-run capture of the doer's end-state as structured `reflection.v1` data, plus a deterministic diff **review risk-floor**. The closed calibration / skill-synthesis loop (design §7–§8) stays **gated** behind Phase-0 experiments P1/P2/P3.
Spec: `docs/plans/agent-reflection-loop-PRD.md` · Tasks: `docs/tasks/544-agent-reflection-loop.md`
## What's included
- **`packages/macp`** — `evaluateRiskFloor` (pure, deterministic surface classifier; auth/data/infra → review) + `reflection.v1.schema.json`. 15 unit tests.
- **`packages/types`** — `reflection.v1` zod schemas + `ReflectionSelfReportDto`. 10 unit tests.
- **`packages/mosaic/framework`** — fail-closed Stop hook (`reflect-stop-hook.sh`) writing the sidecar, registered as `hooks.Stop` in `runtime/claude/settings.json`. **Strict no-op unless `REFLECTION_MODE=solo|orchestrated`**; never blocks or fails a session, never emits a `decision`.
- **`scripts/analysis`** — P1/P2/P3 experiment harnesses with pre-registered kill conditions + structured output.
## Design notes
- **Mechanical vs self-reported.** Hook writes mechanical fields (risk, files_changed, ids, provenance); self-report (confidence, most_likely_wrong, known_not_in_diff) is merged from an optional `$REFLECTION_INPUT`, else null + `provenance.degraded=true`.
- **Risk-floor authority** is the TS `evaluateRiskFloor`; the hook ports the same surface table inline to stay node/build-free, documented as kept in sync.
- **Hook registration** is in the canonical `settings.json` (the `settings-overlays/` dir has no merge mechanism — would be inert).
## Verification
- macp: 88 tests pass (15 new) · types: 64 tests pass (10 new).
- Root `pnpm typecheck` / `lint` / `format:check` / `build` — all green.
- Stop hook smoke: fail-closed no-op, solo capture (degraded), self-report merge, re-fire lock guard, empty-diff still writes — all pass, always exit 0.
- All bash shellcheck-clean.
- Independent code review passed after remediating 2 findings (empty/all-`.mosaic` diff no longer aborts the write; `session_id` sanitized before path use).
## Activation (post-merge, not a blocker)
Hook activates only when a launcher/profile sets `REFLECTION_MODE`; unset/`off` is a strict no-op, so global registration is safe. `framework/install.sh` rsyncs the hook; the `mosaic` launcher reflects the updated `settings.json` into `~/.claude/settings.json`.
Closes #544
Fixes #544
Build the durable kernel of the agent reflection loop. Passive end-of-run
capture of the doer's end-state as structured `reflection.v1` data, plus a
deterministic diff review risk-floor. The closed calibration/skill-synthesis
loop (design §7–§8) stays gated behind Phase-0 experiments P1/P2/P3.
- packages/macp: evaluateRiskFloor (pure, deterministic surface classifier)
+ reflection.v1 JSON Schema; 15 unit tests.
- packages/types: reflection.v1 zod schemas + self-report DTO; 10 unit tests.
- framework: fail-closed Stop hook (reflect-stop-hook.sh) writing the sidecar,
registered as hooks.Stop in runtime/claude/settings.json. Strict no-op unless
REFLECTION_MODE=solo|orchestrated; never blocks or fails a session.
- scripts/analysis: P1/P2/P3 experiment harnesses with pre-registered kill
conditions and structured output.
Mechanical fields (risk, files_changed, ids, provenance) are written by the
hook; self-report fields (confidence, most_likely_wrong, known_not_in_diff) are
merged from an optional $REFLECTION_INPUT, else null + provenance.degraded=true.
Independent review remediations: empty/all-.mosaic diff still writes a sidecar
(grep no-match no longer aborts); session_id sanitized before path use.
Refs #544
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Bakes in the durable kernel of the agent reflection loop. Passive end-of-run capture of the doer's end-state as structured
reflection.v1data, plus a deterministic diff review risk-floor. The closed calibration / skill-synthesis loop (design §7–§8) stays gated behind Phase-0 experiments P1/P2/P3.Spec:
docs/plans/agent-reflection-loop-PRD.md· Tasks:docs/tasks/544-agent-reflection-loop.mdWhat's included
packages/macp—evaluateRiskFloor(pure, deterministic surface classifier; auth/data/infra → review) +reflection.v1.schema.json. 15 unit tests.packages/types—reflection.v1zod schemas +ReflectionSelfReportDto. 10 unit tests.packages/mosaic/framework— fail-closed Stop hook (reflect-stop-hook.sh) writing the sidecar, registered ashooks.Stopinruntime/claude/settings.json. Strict no-op unlessREFLECTION_MODE=solo|orchestrated; never blocks or fails a session, never emits adecision.scripts/analysis— P1/P2/P3 experiment harnesses with pre-registered kill conditions + structured output.Design notes
$REFLECTION_INPUT, else null +provenance.degraded=true.evaluateRiskFloor; the hook ports the same surface table inline to stay node/build-free, documented as kept in sync.settings.json(thesettings-overlays/dir has no merge mechanism — would be inert).Verification
pnpm typecheck/lint/format:check/build— all green..mosaicdiff no longer aborts the write;session_idsanitized before path use).Activation (post-merge, not a blocker)
Hook activates only when a launcher/profile sets
REFLECTION_MODE; unset/offis a strict no-op, so global registration is safe.framework/install.shrsyncs the hook; themosaiclauncher reflects the updatedsettings.jsoninto~/.claude/settings.json.Closes #544
Fixes #544