KeiSeiKit-1.0/docs/PROFILE-OUTCOME-ONLY.md
Parfii-bot 6b66914f97 feat(install): outcome-only minimum profile
Reviewer suggested an evaluation footprint that lands "the smallest
substrate any caller-LLM can use", with 5 files and ~200 LOC ceiling
in $HOME. This commit ships that profile.

Files installed in $HOME by `./install.sh --profile=outcome-only`:
1. ~/.claude/hooks/agent-outcome-backfill.sh   (PostToolUse:Agent)
2. ~/.claude/hooks/error-spike-detector.sh     (PostToolUse:Bash, rolling 20-call window)
3. ~/.claude/agents/ledger.sqlite              (full v9 schema via kei-ledger init, or sqlite3-fallback DDL)
4. ~/.claude/CLAUDE.md                         (1-line STATUS-TRUTH MARKER instruction appended)
5. ~/.claude/settings.json                     (jq-merge of 2 hook entries)

Plus optional 6th: kei-model-router binary built from _primitives/_rust if
cargo on PATH; deferred otherwise (warning printed, install continues).

Files added to repo:
- install/lib-profile-outcome-only.sh (145 LOC) — profile orchestrator with
  --dry-run support; sources lib-log/lib-backup/lib-hooks helpers; exits
  before heavy install phases when --profile=outcome-only
- install/sql/outcome-only-schema.sql (69 LOC) — flattened v9-equivalent
  SQLite DDL (agents + skill_invocations + indexes), used by sqlite3
  fallback when kei-ledger CLI is unavailable
- docs/PROFILE-OUTCOME-ONLY.md (97 LOC) — reviewer-facing doc: 5-file
  install table, what is NOT installed, kei-model-router activation
  explanation, privacy posture (no telemetry), 4-line uninstall paste

Files modified:
- install.sh (+12 LOC) — sources outcome-only lib, adds short-circuit
  before menu when --profile=outcome-only, accepts in profile validator
- install/lib-args.sh (+9 LOC) — registers --dry-run flag (sets
  OUTCOME_DRY_RUN=1), adds outcome-only + --dry-run lines to --help
- README.md (+7 LOC) — adds Outcome-only Quick-start section pointing to
  PROFILE-OUTCOME-ONLY.md

Verification:
- bash -n clean on all 3 modified shell files
- Dry-run produces exactly 5 numbered $HOME paths (verified end-to-end:
  HOME=/tmp/kei-fake-home bash install.sh --profile=outcome-only --dry-run)
- Real install against fake $HOME succeeds (5 files present, ledger init
  via kei-ledger binary, router build correctly skipped on toolchain
  absence with warning)
- Ledger schema includes agents + skill_invocations tables + 3 indexes
  + 2 triggers via real migration path (not the SQL fallback)

[FROM-JOURNAL: end-to-end install dry-run + real-run measured at
~/.claude/memory/time-metrics/sessions.jsonl this session, both <2s wall]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 16:59:53 +08:00

97 lines
4.2 KiB
Markdown

# `outcome-only` install profile
> Five-file pitch: install the outcome-tracking primitive without
> committing to anything else. No daemon, no Forgejo, no launchd, no
> hundred Rust crates, no `no-github-push` hook, no agent generation.
> If you do not like what `~/.claude/agents/ledger.sqlite` collects,
> the uninstall is a four-line shell paste at the bottom.
## What gets installed
| # | Path | Source | LOC |
|---|--------------------------------------------------------|---------------------------------------|-----|
| 1 | `~/.claude/hooks/agent-outcome-backfill.sh` | `hooks/agent-outcome-backfill.sh` | 140 |
| 2 | `~/.claude/hooks/error-spike-detector.sh` | `hooks/error-spike-detector.sh` | 89 |
| 3 | `~/.claude/agents/ledger.sqlite` | `install/sql/outcome-only-schema.sql` (or `kei-ledger init`) | n/a |
| 4 | one appended line in `~/.claude/CLAUDE.md` | the STATUS-TRUTH MARKER instruction | 1 |
| 5 | `_primitives/_rust/kei-model-router/target/release/kei-model-router` (deferred) | `_primitives/_rust/kei-model-router/` | n/a |
Plus a jq-merge of two hooks into `~/.claude/settings.json`:
- `PostToolUse:Agent``agent-outcome-backfill.sh`
- `PostToolUse:*``error-spike-detector.sh`
`./install.sh --profile=outcome-only --dry-run` prints exactly this
list and exits 0 without writing.
## What does NOT get installed
- 102 Rust crates (cortex, frustration-loop, sleep-layer, …)
- 67 skills, 37 agent manifests, 82 substrate blocks
- `kei-cortex` HTTP / WS daemon
- Forgejo, dev hub, Datasette, restic, mdbook, gdrive-import
- launchd plists (`disk-reclaim`, sleep-layer cron)
- `no-github-push.sh` hook (or any other Bash gate)
- substrate PATH wiring (no edits to your shell rc files)
If you later want any of those, the kit is incremental: re-run
`./install.sh --profile=core` (or heavier) and the outcome-only state
is preserved verbatim — both paths share `~/.claude/hooks/` and
`~/.claude/agents/ledger.sqlite`.
## How `kei-model-router` activates
The router is a posterior decision rule keyed on per-task-class DNA
plus a Beta posterior over `(success, total)` in `agents.outcome`.
Until you accumulate ~100 outcome rows, the router falls back to
"behaviour unchanged" — every spawn keeps whatever model the agent
manifest declares.
After ~100 rows the posterior dominates the prior and the router
starts producing concrete recommendations. You opt in by adding
`kei-model-router` to a `PreToolUse:Agent` hook later — that step is
**not** done by this profile. You stay in observe-only mode by default.
If `cargo` is on PATH at install time the binary is built into
`_primitives/_rust/kei-model-router/target/release/`. If `cargo` is
missing the build is skipped silently and the install is still
considered complete; rebuild later with:
```bash
cd _primitives/_rust/kei-model-router && cargo build --release
```
## Privacy posture
All outcome rows live in `~/.claude/agents/ledger.sqlite`. They never
leave the machine — no sync hook, no remote-push, no telemetry.
Inspect with:
```bash
sqlite3 ~/.claude/agents/ledger.sqlite \
"SELECT id, branch, status, outcome, stubs_count, started_ts FROM agents
ORDER BY started_ts DESC LIMIT 20;"
```
Uncomfortable with the file? `rm` it; the next install or agent run
recreates an empty schema, no other side effects.
## Uninstall
```bash
rm -f ~/.claude/hooks/agent-outcome-backfill.sh
rm -f ~/.claude/hooks/error-spike-detector.sh
rm -f ~/.claude/agents/ledger.sqlite
sed -i.bak '/outcome-only profile (KeiSeiKit)/,+1 d' ~/.claude/CLAUDE.md
```
Both hooks exit 0 immediately when their target script is missing, so
the `~/.claude/settings.json` jq-merge entries are harmless after
`rm`. To scrub those too, drop `agent-outcome-backfill.sh` /
`error-spike-detector.sh` lines from `settings.json` by hand.
## Why this profile exists
A kit with 100 crates / Forgejo / launchd plists is too heavy to
evaluate. A pitch you can read in four minutes and trial in five is
not. This profile is the answer to "what is the smallest version of
KeiSeiKit that still demonstrates the outcome loop?" — and nothing more.