[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6D33MSP3QRT8HA8MYTW21RF":3,"skill-same:01M6D33MSP3QRT8HA8MYTW21RF":58},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":29,"linkOnly":30,"markdownContent":31,"markdownBody":32,"frontMatter":33,"refName":35,"commitSha":36,"skillDirectory":37,"forksCount":38,"repositoryHtmlUrl":39,"repositoryHomepageUrl":6,"ownerHtmlUrl":40,"ownerBlogUrl":41,"ownerDescription":42,"updatedAt":43,"install":44,"resources":57},"01M6D33MSP3QRT8HA8MYTW21RF","activation-review",null,"Review proposed actions surfaced by the B-1 Activation Engine. Gathers recent signals, extracts candidates, ranks them, drafts artifacts, and captures the user's response per offer. Standalone — does not modify \u002Fdaily-plan.","hemory\u002Famp-legacy-do-not-use","hemory","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F21179881?v=4","01M6D31HFJ391DN8N0JP8AQGFE","Hemory Phifer","01M6D31HKXVTEN27AT6R4PP2ZJ",3,"MIT","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Factivation-review\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28],"review","activation","activation review","artifacts","actions","plan","engine","user","daily","signals","2026-11-10 10:12:30",false,"---\nname: activation-review\ndescription: Review proposed actions surfaced by the B-1 Activation Engine. Gathers recent signals, extracts candidates, ranks them, drafts artifacts, and captures the user's response per offer. Standalone — does not modify \u002Fdaily-plan.\ncontext: fork\n---\n\n## Purpose\n\nThe Activation Engine (B-1) turns Amp's passive vault context into a small, ranked list of prepared actions. This skill is the human-in-the-loop ritual for reviewing those actions. `\u002Fdaily-plan` is intentionally untouched so the activation engine can be exercised independently before it is welded into the morning ritual.\n\nThe skill is a thin wrapper over the `python -m core.activation` CLI. All LLM calls are handshake-mediated: the CLI emits a JSON prompt, the agent runs the model, the CLI validates + writes the result. No shortcuts — the citation-required gate (§6.1 of the design doc) and the length-cap hallucination guard are enforced by `draft-apply`.\n\n---\n\n## Frontmatter \u002F config\n\nCLI surface used by this skill:\n\n| Stage | Command |\n|---|---|\n| 1 — gather | `python -m core.activation gather` |\n| 2a — extract prompt | `python -m core.activation extract-prompt` |\n| 2b — extract apply | `python -m core.activation extract-apply --input FILE --batch-id ID` |\n| 3 — rank | `python -m core.activation rank --days-since-install N [--acceptance-rate R] [--ghost]` |\n| 4a — draft prompt | `python -m core.activation draft-prompt --offer-id ID` (or `--all`) |\n| 4b — draft apply | `python -m core.activation draft-apply --offer-id ID --input FILE` |\n| 5 — acceptance rate | `python -m core.activation acceptance-rate [--window-days 14]` |\n| 6 — log response | `python -m core.activation log --offer-id ID --response {accepted\\|accepted_with_edits\\|rejected\\|never_again\\|snoozed\\|ignored\\|viewed} [--reason TEXT] [--ghost]` |\n| 7 — ghost status | `python -m core.activation ghost-status [--json]` |\n| 7 — ghost review | `python -m core.activation ghost-review [--window-days N] [--mark-complete] [--notes TEXT]` |\n| 7 — ghost exit | `python -m core.activation ghost-exit --acknowledge` |\n\nRun all commands from the repo root with the repo's venv: `.venv\u002Fbin\u002Fpython -m core.activation ...`.\n\n---\n\n## Safety notes\n\n- **Kill switch:** `System\u002Factivation\u002Fkill.yaml` with `disabled: true` halts everything. Check it before starting.\n- **Quiet mode:** `System\u002Factivation\u002Fquiet-mode.yaml` with an `until:` date suspends activation until the date passes.\n- **Ghost mode:** Enter ghost mode if the install is \u003C7 days old (pass `--days-since-install N`) OR if `--ghost` is supplied to `rank`. In ghost mode, offers are logged but clearly labeled as non-actionable; `log` entries are tagged `ghost`.\n- **Citation gate:** `draft-apply` rejects any draft citing a signal that wasn't attached to the offer. Do not try to work around a rejection — re-run the LLM with the original handshake.\n- **Never auto-send.** Every offer produces a draft. the user presses send. Always.\n\n---\n\n## Process\n\n### Step 0: Safety preflight\n\n1. Read `System\u002Factivation\u002Fkill.yaml`. If `disabled: true` → stop, tell the user activation is off, exit.\n2. Read `System\u002Factivation\u002Fquiet-mode.yaml`. If `until` is in the future → stop, tell the user quiet mode is active until that date, exit.\n3. Determine `days_since_install`:\n   - Use the mtime of `System\u002Factivation\u002FREADME.md` or the first line of `System\u002Factivation\u002Fghost-log.md` as the install anchor.\n   - If \u003C7, you will be in ghost mode for Step 3.\n\n### Step 1: Gather fresh signals\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation gather\n```\n\nRead the summary line (total signals, by source). If 0 signals, stop with a short message: \"No fresh signals — nothing to review.\"\n\n### Step 2: Extract candidates\n\n1. Emit the handshake: `.venv\u002Fbin\u002Fpython -m core.activation extract-prompt` → capture stdout, note the `batch_id`.\n2. Call the LLM with `system_prompt` + `user_prompt` from the handshake. The LLM must return a JSON array of Candidate objects matching the provided `schema`.\n3. Save the response to a temp file inside the repo workspace (do NOT use `\u002Ftmp`), e.g. `System\u002Factivation\u002F.last-extract-response.json`.\n4. Apply: `.venv\u002Fbin\u002Fpython -m core.activation extract-apply --batch-id \u003Cid> --input \u003Cpath>`\n5. Note the `accepted=N rejected=M` line. If >0 rejected, surface the first reject reason to the user so he can see how the gate is working.\n6. Repeat for additional batches only if `extract-prompt --batch-index N` returns more batches; Sprint 4 ships batch 0 by default.\n\n### Step 3: Rank\n\nFirst compute the acceptance rate for the throttle:\n\n```bash\nRATE=$(.venv\u002Fbin\u002Fpython -m core.activation acceptance-rate)\n```\n\n- If `RATE == \"insufficient_data\"` OR `days_since_install \u003C 7` → use `--days-since-install $N` (ghost mode will engage automatically for new installs).\n- Otherwise → pass both `--days-since-install $N --acceptance-rate $RATE`.\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation rank --days-since-install $N --acceptance-rate $RATE\n```\n\nOutput line is `surfaced=X ghost=Y dropped=Z`. Remember: in ghost mode `surfaced=0` is correct.\n\n### Step 4: Draft per offer\n\nFor each offer in `System\u002Factivation\u002Foffers.jsonl` where `shown: true` (or all ghost offers if ghost mode — see Step 6):\n\n1. `.venv\u002Fbin\u002Fpython -m core.activation draft-prompt --offer-id \u003Cid>` → capture stdout.\n2. Call the LLM with the handshake. Respect the `length_cap_words` in the handshake.\n3. Save response to `System\u002Factivation\u002F.last-draft-response.json` (rewrite for each offer).\n4. `.venv\u002Fbin\u002Fpython -m core.activation draft-apply --offer-id \u003Cid> --input \u003Cpath>`\n5. If `rejected=1`, read the reason on stderr. Most common causes: hallucinated citation, over-length, missing field. Re-run the LLM with the same handshake and tighter guidance. Do not mutate the handshake itself.\n\n### Step 5: Present offers to the user\n\nRender a clean numbered summary:\n\n```\nActivation review — {{date}}   ({{mode: live | ghost (day N of 7)}})\n\n1. [meeting_followup] Send workshop followup to D.Lin\n   Why: Monday's 1:1 — committed to send recap by Friday.\n   Draft: System\u002Factivation\u002Fdrafts\u002F{{offer_id}}.md\n\n2. [commitment_reminder] Q2 narrative due tomorrow\n   ...\n```\n\nRules:\n- Show at most what `rank` surfaced. Do not expose budget-held offers.\n- Ghost mode: show the same list but with a clear banner up top: \"? Ghost mode — Amp is learning your patterns. Nothing will be acted on. Mark each offer anyway; your judgments feed the self-throttle.\"\n\n### Step 6: Capture response per offer\n\nFor each numbered offer, ask the user: accept \u002F edit \u002F reject (with reason?) \u002F snooze \u002F ignore.\n\nFor each answer run:\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation log --offer-id \u003Cid> --response \u003Cresponse> [--reason \"\u003Creason>\"] [--ghost]\n```\n\n- Pass `--ghost` when you are in ghost mode so the `ghost-log.md` entry is tagged correctly.\n- `rejected` records a \"not now\" Event. The same pattern is hard-suppressed for 14 days (Sprint 7 H1) but no Tombstone is created — the candidate can resurface after the window if the underlying signal is still relevant.\n- `never_again` is the permanent stop. It appends a Tombstone (the user won't see that pattern again) **and** records an Event. Use this when the user says \"stop suggesting this kind of thing\".\n- All responses now also append to `System\u002Factivation\u002Fresponse-events.jsonl` (Sprint 7 H3, append-only). Throttle, day-7 acceptance, and weekly metrics are computed from this log.\n\n### Sprint 7 audit \u002F housekeeping commands\n- `python -m core.activation handshake-gc --older-than-days 7` — sweep stale extract\u002Fdraft handshake JSONs from `System\u002Factivation\u002Fhandshakes\u002F`.\n- `python -m core.activation policy-check [--acknowledge] [--json]` — sha256 hash of weights+grounding+prompts+identity+rubric. If it changed since baseline, `post-review-pause.yaml` is auto-set. `--acknowledge` clears the pause and rebaselines.\n- `python -m core.activation weekly-metrics [--week-ending YYYY-MM-DD] [--json]` — emits the §11 review summary (offers proposed\u002Fsurfaced\u002Fheld\u002Fdecided, draft adoption, response latency p50\u002Fp95, grounding pass rate, throttle\u002Fghost active days).\n- `python -m core.activation ghost-status --check-exit-ready [--json]` — prints the H4 predicate matrix (P1 install window, P2 manual, P3 pause, P4 distinct review days, P5 decided offers, P6 day-7 acceptance) and the overall `ready` flag. Use BEFORE running `ghost-exit --acknowledge`.\n- `python -m core.activation ghost-exit --acknowledge` — refuses unless all H4 predicates pass. `--force` bypasses the gate (manual audit required, audit row recorded).\n- `snoozed` is a re-rank next run, not a hard re-surface (per design doc §10.3).\n\n### Step 7: Close out\n\nSummarize for the user:\n\n- Total offers surfaced\n- Accepted \u002F rejected \u002F snoozed \u002F ignored counts\n- New tombstones count (if any)\n- Next review suggested date\n\nIf ghost mode: remind the user that ghost exits when `days_since_install >= 7` AND ≥5 days of ghost offers exist AND at least one review has happened.\n\n---\n\n## Output\n\nThis skill does not produce a markdown file in the vault. Its outputs are:\n- Updated `System\u002Factivation\u002Foffers.jsonl` with user_response per row\n- Appended rows in `System\u002Factivation\u002Ftombstones.jsonl` for rejects\n- Appended lines in `System\u002Factivation\u002Fghost-log.md` for every response\n- Draft artifacts under `System\u002Factivation\u002Fdrafts\u002F{offer_id}.md`\n\nThe spine is the log. If Amp vanishes tomorrow, `offers.jsonl` + `drafts\u002F` are still a clean, readable record of decisions the user made.\n\n---\n\n## Graceful Degradation\n\n- **No identity files:** `draft-prompt` emits a warning to stderr; drafting proceeds with generic voice. Drafts may feel flatter until `System\u002Fidentity\u002F` is populated.\n- **No signals:** Step 1 bails early.\n- **No candidates after extract:** Step 3 produces no offers; say so and exit.\n- **LLM unavailable:** Abort after Step 1 with the user's signals preserved. Activation is a per-ritual concern; there is no \"partial run\" state to clean up.\n\n---\n\n## Calibration mode (Sprint 5)\n\nThe engine ships an **offline replay harness** at `System\u002Factivation\u002Freplay\u002F`. Replay is how we exercise the full pipeline *without* running against the live vault, the network, or an LLM — responses are pre-recorded in fixtures. This is the instrument that produces the §13 success-criterion #1 measurement (\"mean grade ≥2.0 across ≥30 offers\") before B-1 is allowed to go live.\n\nUse replay when:\n- the user is grading a batch (the first-30-offers pass per §10 locked decision #4).\n- You're tuning `weights.yaml` and want to know whether a change helped or hurt.\n- You're investigating a production regression — reproduce it with a fixture, then iterate.\n\nCLI surface:\n\n| Stage | Command |\n|---|---|\n| Run + score a fixture | `.venv\u002Fbin\u002Fpython -m core.activation replay --fixture PATH [--write-run] [--json]` |\n| Append a human grade | `.venv\u002Fbin\u002Fpython -m core.activation grade --fixture PATH --offer-id ID --score 0..1 --reason \"TEXT\" [--grader user]` |\n| Score a live offer | `.venv\u002Fbin\u002Fpython -m core.activation rubric-check --offer-id ID [--json]` |\n\nReplay is read-only on `System\u002Factivation\u002F*.jsonl` unless `--write-run` is passed, in which case outputs land under `System\u002Factivation\u002Freplay\u002Fruns\u002F\u003Cfixture_id>\u002F\u003Ctimestamp>\u002F` — never in the live activation files. The kill switch and quiet-mode file still apply: replay refuses to run if the engine is disabled or in quiet mode.\n\n**daily-plan guard (unchanged):** This skill still does not modify `\u002Fdaily-plan`. Calibration mode is a sibling ritual, not a front-end.\n\n---\n\n## Self-grading (Amp applies the rubric)\n\nPer design doc §10 locked decision #4, Amp may apply the rubric *after* the user has graded the first 30 live offers and calibration has been verified. Until then, Amp surfaces offers but does not publish rubric scores as judgments — only the user's grades count for acceptance metrics.\n\nOnce calibration is established, Amp's self-grading flow inside the daily review:\n\n1. After the user responds to each live offer, run `rubric-check --offer-id \u003Cid> --json`.\n2. Report the `overall` score and any dimension below 0.6 to the user as part of the close-out summary. Example: *\"Rubric gave this offer 0.72 overall — flagged `grounding=0.55` because the draft referenced a figure not present in the cited signals. Confidence noted.\"*\n3. Do **not** use the rubric to silently suppress offers. The rubric is a reporting instrument for now; throttling decisions still come from acceptance-rate telemetry per §4.3.\n4. If Amp's rubric disagrees materially with the user's grade on a fixture (|delta| > 0.3 across ≥3 offers in a fresh replay), stop self-grading and raise the discrepancy to the user. That is a calibration failure, not a style disagreement.\n\nThe rubric is defined in `core\u002Factivation\u002Frubric.py` and scores six dimensions: grounding, specificity, staleness, novelty, length discipline, citation discipline. Equal weights for v1 — per §9 the weighting is intentionally left unlearned so that calibration exposes which dimensions actually predict the user's judgment.\n\n\n---\n\n## Ghost-mode flow (Sprint 6)\n\nGhost mode is the §7 \u002F §10-#2 safeguard: the engine runs the full pipeline but does NOT surface offers. This skill is ghost-aware as of Sprint 6. The **\u002Fdaily-plan ritual remains untouched** — ghost mode lives entirely inside `\u002Factivation-review`.\n\n### Detect ghost state\n\nBefore Step 5 (presentation), call:\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation ghost-status --json\n```\n\nParse the JSON. If `active: true`, the engine is in ghost mode and `reason` will be one of:\n\n- `install_window` — first 7 days since `install.yaml::install_date`. `expected_end` tells you when the window ends.\n- `manual` — `System\u002Factivation\u002Fghost-mode.yaml` has `active: true`. May have an `until: YYYY-MM-DD`.\n- `post_review_pause` — `System\u002Factivation\u002Fpost-review-pause.yaml` exists (Sprint 7 will populate this; Sprint 6 only honors it as a flag).\n\n### When in ghost mode\n\n1. Skip the live presentation (Step 5). Instead run:\n   ```bash\n   .venv\u002Fbin\u002Fpython -m core.activation ghost-review --window-days 7\n   ```\n   This emits the digest to stdout and archives a copy under `System\u002Factivation\u002Fghost-review-{YYYYMMDD}.md`. Present the digest verbatim to the user.\n2. For each held offer in the digest, ask the user: accept \u002F edit \u002F reject (with reason?) \u002F snooze \u002F ignore. **Even though offers are not actioned in ghost, recording responses calibrates the engine.**\n3. Run `log` per response. The `log` CLI now infers ghost mode from the offer's `hold_reason`, so you no longer need to pass `--ghost`:\n   ```bash\n   .venv\u002Fbin\u002Fpython -m core.activation log --offer-id \u003Cid> --response \u003Cresponse>\n   ```\n   The ghost-log entry will be tagged `mode=ghost` automatically.\n4. After all decisions are recorded, call:\n   ```bash\n   .venv\u002Fbin\u002Fpython -m core.activation ghost-review --mark-complete --notes \"\u003Cshort summary>\"\n   ```\n   This appends a structured `ghost-review-complete` marker to `ghost-log.md`. The `ghost-exit` ritual requires ≥1 such marker in the past 7 days.\n\n### Suggesting ghost exit\n\nAfter ≥3 days of completed ghost reviews (count the marker payloads with `find_recent_ghost_reviews` or eyeball `ghost-log.md`), AND the install window has elapsed (`days_since_install >= 7`), suggest to the user:\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation ghost-exit --acknowledge\n```\n\n`ghost-exit` will refuse if:\n\n- `--acknowledge` is missing (no accidental exits).\n- The install window has not elapsed.\n- No ghost-review-complete marker exists in the past 7 days.\n- `ghost-mode.yaml::active: true` (the user must clear it himself).\n\nOn success it writes `ghost_exited_at` to `install.yaml` and the next `rank` run will surface offers normally.\n\n### \u002Fdaily-plan guard (still unchanged)\n\nThis skill still does NOT modify `\u002Fdaily-plan`. Ghost mode lives entirely inside `\u002Factivation-review`; `\u002Fdaily-plan` is untouched.\n","## Purpose\n\nThe Activation Engine (B-1) turns Amp's passive vault context into a small, ranked list of prepared actions. This skill is the human-in-the-loop ritual for reviewing those actions. `\u002Fdaily-plan` is intentionally untouched so the activation engine can be exercised independently before it is welded into the morning ritual.\n\nThe skill is a thin wrapper over the `python -m core.activation` CLI. All LLM calls are handshake-mediated: the CLI emits a JSON prompt, the agent runs the model, the CLI validates + writes the result. No shortcuts — the citation-required gate (§6.1 of the design doc) and the length-cap hallucination guard are enforced by `draft-apply`.\n\n---\n\n## Frontmatter \u002F config\n\nCLI surface used by this skill:\n\n| Stage | Command |\n|---|---|\n| 1 — gather | `python -m core.activation gather` |\n| 2a — extract prompt | `python -m core.activation extract-prompt` |\n| 2b — extract apply | `python -m core.activation extract-apply --input FILE --batch-id ID` |\n| 3 — rank | `python -m core.activation rank --days-since-install N [--acceptance-rate R] [--ghost]` |\n| 4a — draft prompt | `python -m core.activation draft-prompt --offer-id ID` (or `--all`) |\n| 4b — draft apply | `python -m core.activation draft-apply --offer-id ID --input FILE` |\n| 5 — acceptance rate | `python -m core.activation acceptance-rate [--window-days 14]` |\n| 6 — log response | `python -m core.activation log --offer-id ID --response {accepted\\|accepted_with_edits\\|rejected\\|never_again\\|snoozed\\|ignored\\|viewed} [--reason TEXT] [--ghost]` |\n| 7 — ghost status | `python -m core.activation ghost-status [--json]` |\n| 7 — ghost review | `python -m core.activation ghost-review [--window-days N] [--mark-complete] [--notes TEXT]` |\n| 7 — ghost exit | `python -m core.activation ghost-exit --acknowledge` |\n\nRun all commands from the repo root with the repo's venv: `.venv\u002Fbin\u002Fpython -m core.activation ...`.\n\n---\n\n## Safety notes\n\n- **Kill switch:** `System\u002Factivation\u002Fkill.yaml` with `disabled: true` halts everything. Check it before starting.\n- **Quiet mode:** `System\u002Factivation\u002Fquiet-mode.yaml` with an `until:` date suspends activation until the date passes.\n- **Ghost mode:** Enter ghost mode if the install is \u003C7 days old (pass `--days-since-install N`) OR if `--ghost` is supplied to `rank`. In ghost mode, offers are logged but clearly labeled as non-actionable; `log` entries are tagged `ghost`.\n- **Citation gate:** `draft-apply` rejects any draft citing a signal that wasn't attached to the offer. Do not try to work around a rejection — re-run the LLM with the original handshake.\n- **Never auto-send.** Every offer produces a draft. the user presses send. Always.\n\n---\n\n## Process\n\n### Step 0: Safety preflight\n\n1. Read `System\u002Factivation\u002Fkill.yaml`. If `disabled: true` → stop, tell the user activation is off, exit.\n2. Read `System\u002Factivation\u002Fquiet-mode.yaml`. If `until` is in the future → stop, tell the user quiet mode is active until that date, exit.\n3. Determine `days_since_install`:\n   - Use the mtime of `System\u002Factivation\u002FREADME.md` or the first line of `System\u002Factivation\u002Fghost-log.md` as the install anchor.\n   - If \u003C7, you will be in ghost mode for Step 3.\n\n### Step 1: Gather fresh signals\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation gather\n```\n\nRead the summary line (total signals, by source). If 0 signals, stop with a short message: \"No fresh signals — nothing to review.\"\n\n### Step 2: Extract candidates\n\n1. Emit the handshake: `.venv\u002Fbin\u002Fpython -m core.activation extract-prompt` → capture stdout, note the `batch_id`.\n2. Call the LLM with `system_prompt` + `user_prompt` from the handshake. The LLM must return a JSON array of Candidate objects matching the provided `schema`.\n3. Save the response to a temp file inside the repo workspace (do NOT use `\u002Ftmp`), e.g. `System\u002Factivation\u002F.last-extract-response.json`.\n4. Apply: `.venv\u002Fbin\u002Fpython -m core.activation extract-apply --batch-id \u003Cid> --input \u003Cpath>`\n5. Note the `accepted=N rejected=M` line. If >0 rejected, surface the first reject reason to the user so he can see how the gate is working.\n6. Repeat for additional batches only if `extract-prompt --batch-index N` returns more batches; Sprint 4 ships batch 0 by default.\n\n### Step 3: Rank\n\nFirst compute the acceptance rate for the throttle:\n\n```bash\nRATE=$(.venv\u002Fbin\u002Fpython -m core.activation acceptance-rate)\n```\n\n- If `RATE == \"insufficient_data\"` OR `days_since_install \u003C 7` → use `--days-since-install $N` (ghost mode will engage automatically for new installs).\n- Otherwise → pass both `--days-since-install $N --acceptance-rate $RATE`.\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation rank --days-since-install $N --acceptance-rate $RATE\n```\n\nOutput line is `surfaced=X ghost=Y dropped=Z`. Remember: in ghost mode `surfaced=0` is correct.\n\n### Step 4: Draft per offer\n\nFor each offer in `System\u002Factivation\u002Foffers.jsonl` where `shown: true` (or all ghost offers if ghost mode — see Step 6):\n\n1. `.venv\u002Fbin\u002Fpython -m core.activation draft-prompt --offer-id \u003Cid>` → capture stdout.\n2. Call the LLM with the handshake. Respect the `length_cap_words` in the handshake.\n3. Save response to `System\u002Factivation\u002F.last-draft-response.json` (rewrite for each offer).\n4. `.venv\u002Fbin\u002Fpython -m core.activation draft-apply --offer-id \u003Cid> --input \u003Cpath>`\n5. If `rejected=1`, read the reason on stderr. Most common causes: hallucinated citation, over-length, missing field. Re-run the LLM with the same handshake and tighter guidance. Do not mutate the handshake itself.\n\n### Step 5: Present offers to the user\n\nRender a clean numbered summary:\n\n```\nActivation review — {{date}}   ({{mode: live | ghost (day N of 7)}})\n\n1. [meeting_followup] Send workshop followup to D.Lin\n   Why: Monday's 1:1 — committed to send recap by Friday.\n   Draft: System\u002Factivation\u002Fdrafts\u002F{{offer_id}}.md\n\n2. [commitment_reminder] Q2 narrative due tomorrow\n   ...\n```\n\nRules:\n- Show at most what `rank` surfaced. Do not expose budget-held offers.\n- Ghost mode: show the same list but with a clear banner up top: \"? Ghost mode — Amp is learning your patterns. Nothing will be acted on. Mark each offer anyway; your judgments feed the self-throttle.\"\n\n### Step 6: Capture response per offer\n\nFor each numbered offer, ask the user: accept \u002F edit \u002F reject (with reason?) \u002F snooze \u002F ignore.\n\nFor each answer run:\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation log --offer-id \u003Cid> --response \u003Cresponse> [--reason \"\u003Creason>\"] [--ghost]\n```\n\n- Pass `--ghost` when you are in ghost mode so the `ghost-log.md` entry is tagged correctly.\n- `rejected` records a \"not now\" Event. The same pattern is hard-suppressed for 14 days (Sprint 7 H1) but no Tombstone is created — the candidate can resurface after the window if the underlying signal is still relevant.\n- `never_again` is the permanent stop. It appends a Tombstone (the user won't see that pattern again) **and** records an Event. Use this when the user says \"stop suggesting this kind of thing\".\n- All responses now also append to `System\u002Factivation\u002Fresponse-events.jsonl` (Sprint 7 H3, append-only). Throttle, day-7 acceptance, and weekly metrics are computed from this log.\n\n### Sprint 7 audit \u002F housekeeping commands\n- `python -m core.activation handshake-gc --older-than-days 7` — sweep stale extract\u002Fdraft handshake JSONs from `System\u002Factivation\u002Fhandshakes\u002F`.\n- `python -m core.activation policy-check [--acknowledge] [--json]` — sha256 hash of weights+grounding+prompts+identity+rubric. If it changed since baseline, `post-review-pause.yaml` is auto-set. `--acknowledge` clears the pause and rebaselines.\n- `python -m core.activation weekly-metrics [--week-ending YYYY-MM-DD] [--json]` — emits the §11 review summary (offers proposed\u002Fsurfaced\u002Fheld\u002Fdecided, draft adoption, response latency p50\u002Fp95, grounding pass rate, throttle\u002Fghost active days).\n- `python -m core.activation ghost-status --check-exit-ready [--json]` — prints the H4 predicate matrix (P1 install window, P2 manual, P3 pause, P4 distinct review days, P5 decided offers, P6 day-7 acceptance) and the overall `ready` flag. Use BEFORE running `ghost-exit --acknowledge`.\n- `python -m core.activation ghost-exit --acknowledge` — refuses unless all H4 predicates pass. `--force` bypasses the gate (manual audit required, audit row recorded).\n- `snoozed` is a re-rank next run, not a hard re-surface (per design doc §10.3).\n\n### Step 7: Close out\n\nSummarize for the user:\n\n- Total offers surfaced\n- Accepted \u002F rejected \u002F snoozed \u002F ignored counts\n- New tombstones count (if any)\n- Next review suggested date\n\nIf ghost mode: remind the user that ghost exits when `days_since_install >= 7` AND ≥5 days of ghost offers exist AND at least one review has happened.\n\n---\n\n## Output\n\nThis skill does not produce a markdown file in the vault. Its outputs are:\n- Updated `System\u002Factivation\u002Foffers.jsonl` with user_response per row\n- Appended rows in `System\u002Factivation\u002Ftombstones.jsonl` for rejects\n- Appended lines in `System\u002Factivation\u002Fghost-log.md` for every response\n- Draft artifacts under `System\u002Factivation\u002Fdrafts\u002F{offer_id}.md`\n\nThe spine is the log. If Amp vanishes tomorrow, `offers.jsonl` + `drafts\u002F` are still a clean, readable record of decisions the user made.\n\n---\n\n## Graceful Degradation\n\n- **No identity files:** `draft-prompt` emits a warning to stderr; drafting proceeds with generic voice. Drafts may feel flatter until `System\u002Fidentity\u002F` is populated.\n- **No signals:** Step 1 bails early.\n- **No candidates after extract:** Step 3 produces no offers; say so and exit.\n- **LLM unavailable:** Abort after Step 1 with the user's signals preserved. Activation is a per-ritual concern; there is no \"partial run\" state to clean up.\n\n---\n\n## Calibration mode (Sprint 5)\n\nThe engine ships an **offline replay harness** at `System\u002Factivation\u002Freplay\u002F`. Replay is how we exercise the full pipeline *without* running against the live vault, the network, or an LLM — responses are pre-recorded in fixtures. This is the instrument that produces the §13 success-criterion #1 measurement (\"mean grade ≥2.0 across ≥30 offers\") before B-1 is allowed to go live.\n\nUse replay when:\n- the user is grading a batch (the first-30-offers pass per §10 locked decision #4).\n- You're tuning `weights.yaml` and want to know whether a change helped or hurt.\n- You're investigating a production regression — reproduce it with a fixture, then iterate.\n\nCLI surface:\n\n| Stage | Command |\n|---|---|\n| Run + score a fixture | `.venv\u002Fbin\u002Fpython -m core.activation replay --fixture PATH [--write-run] [--json]` |\n| Append a human grade | `.venv\u002Fbin\u002Fpython -m core.activation grade --fixture PATH --offer-id ID --score 0..1 --reason \"TEXT\" [--grader user]` |\n| Score a live offer | `.venv\u002Fbin\u002Fpython -m core.activation rubric-check --offer-id ID [--json]` |\n\nReplay is read-only on `System\u002Factivation\u002F*.jsonl` unless `--write-run` is passed, in which case outputs land under `System\u002Factivation\u002Freplay\u002Fruns\u002F\u003Cfixture_id>\u002F\u003Ctimestamp>\u002F` — never in the live activation files. The kill switch and quiet-mode file still apply: replay refuses to run if the engine is disabled or in quiet mode.\n\n**daily-plan guard (unchanged):** This skill still does not modify `\u002Fdaily-plan`. Calibration mode is a sibling ritual, not a front-end.\n\n---\n\n## Self-grading (Amp applies the rubric)\n\nPer design doc §10 locked decision #4, Amp may apply the rubric *after* the user has graded the first 30 live offers and calibration has been verified. Until then, Amp surfaces offers but does not publish rubric scores as judgments — only the user's grades count for acceptance metrics.\n\nOnce calibration is established, Amp's self-grading flow inside the daily review:\n\n1. After the user responds to each live offer, run `rubric-check --offer-id \u003Cid> --json`.\n2. Report the `overall` score and any dimension below 0.6 to the user as part of the close-out summary. Example: *\"Rubric gave this offer 0.72 overall — flagged `grounding=0.55` because the draft referenced a figure not present in the cited signals. Confidence noted.\"*\n3. Do **not** use the rubric to silently suppress offers. The rubric is a reporting instrument for now; throttling decisions still come from acceptance-rate telemetry per §4.3.\n4. If Amp's rubric disagrees materially with the user's grade on a fixture (|delta| > 0.3 across ≥3 offers in a fresh replay), stop self-grading and raise the discrepancy to the user. That is a calibration failure, not a style disagreement.\n\nThe rubric is defined in `core\u002Factivation\u002Frubric.py` and scores six dimensions: grounding, specificity, staleness, novelty, length discipline, citation discipline. Equal weights for v1 — per §9 the weighting is intentionally left unlearned so that calibration exposes which dimensions actually predict the user's judgment.\n\n\n---\n\n## Ghost-mode flow (Sprint 6)\n\nGhost mode is the §7 \u002F §10-#2 safeguard: the engine runs the full pipeline but does NOT surface offers. This skill is ghost-aware as of Sprint 6. The **\u002Fdaily-plan ritual remains untouched** — ghost mode lives entirely inside `\u002Factivation-review`.\n\n### Detect ghost state\n\nBefore Step 5 (presentation), call:\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation ghost-status --json\n```\n\nParse the JSON. If `active: true`, the engine is in ghost mode and `reason` will be one of:\n\n- `install_window` — first 7 days since `install.yaml::install_date`. `expected_end` tells you when the window ends.\n- `manual` — `System\u002Factivation\u002Fghost-mode.yaml` has `active: true`. May have an `until: YYYY-MM-DD`.\n- `post_review_pause` — `System\u002Factivation\u002Fpost-review-pause.yaml` exists (Sprint 7 will populate this; Sprint 6 only honors it as a flag).\n\n### When in ghost mode\n\n1. Skip the live presentation (Step 5). Instead run:\n   ```bash\n   .venv\u002Fbin\u002Fpython -m core.activation ghost-review --window-days 7\n   ```\n   This emits the digest to stdout and archives a copy under `System\u002Factivation\u002Fghost-review-{YYYYMMDD}.md`. Present the digest verbatim to the user.\n2. For each held offer in the digest, ask the user: accept \u002F edit \u002F reject (with reason?) \u002F snooze \u002F ignore. **Even though offers are not actioned in ghost, recording responses calibrates the engine.**\n3. Run `log` per response. The `log` CLI now infers ghost mode from the offer's `hold_reason`, so you no longer need to pass `--ghost`:\n   ```bash\n   .venv\u002Fbin\u002Fpython -m core.activation log --offer-id \u003Cid> --response \u003Cresponse>\n   ```\n   The ghost-log entry will be tagged `mode=ghost` automatically.\n4. After all decisions are recorded, call:\n   ```bash\n   .venv\u002Fbin\u002Fpython -m core.activation ghost-review --mark-complete --notes \"\u003Cshort summary>\"\n   ```\n   This appends a structured `ghost-review-complete` marker to `ghost-log.md`. The `ghost-exit` ritual requires ≥1 such marker in the past 7 days.\n\n### Suggesting ghost exit\n\nAfter ≥3 days of completed ghost reviews (count the marker payloads with `find_recent_ghost_reviews` or eyeball `ghost-log.md`), AND the install window has elapsed (`days_since_install >= 7`), suggest to the user:\n\n```bash\n.venv\u002Fbin\u002Fpython -m core.activation ghost-exit --acknowledge\n```\n\n`ghost-exit` will refuse if:\n\n- `--acknowledge` is missing (no accidental exits).\n- The install window has not elapsed.\n- No ghost-review-complete marker exists in the past 7 days.\n- `ghost-mode.yaml::active: true` (the user must clear it himself).\n\nOn success it writes `ghost_exited_at` to `install.yaml` and the next `rank` run will surface offers normally.\n\n### \u002Fdaily-plan guard (still unchanged)\n\nThis skill still does NOT modify `\u002Fdaily-plan`. Ghost mode lives entirely inside `\u002Factivation-review`; `\u002Fdaily-plan` is untouched.\n",{"name":5,"context":34,"description":7},"fork","main","5417cad9215b767627c7c947dcb3a0bbe3ebe52d",".claude\u002Fskills\u002Factivation-review",0,"https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use","https:\u002F\u002Fgithub.com\u002Fhemory","https:\u002F\u002Fwww.heminthehat.com\u002F","The People Developer | L&D Program Manager | Software Engineer","2026-06-04 23:46:30",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add hemory\u002Famp-legacy-do-not-use --skill activation-review",{"tool":50,"command":51},"bunx","bunx skills add hemory\u002Famp-legacy-do-not-use --skill activation-review",{"tool":53,"command":54},"pnpm","pnpm dlx skills add hemory\u002Famp-legacy-do-not-use --skill activation-review","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Factivation-review\u002FSKILL.md",true,[],[59,95,104,118,132,144],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":75,"publishedAt":29},"01M6D3DVEAHJTTK4W21B15ZZKK","zoom-setup","Connect Zoom to Amp for meeting recordings, scheduling, and transcript context","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fzoom-setup\u002FSKILL.md",[65,70],{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",{"categoryNo":71,"categoryName":72,"taxonomyType":73,"taxonomyTypeDesc":74},"01JBSEEDCAT000000000000034","行政与办公人员","PROFESSION","适用职业",[76,77,78,79,19,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94],"zoom setup","setup","schedule","MCP","connect","transcript","search","stats","oauth2","confirmation","context","meetings","process","recordings","surfaces","scheduling","granola","time","distribution",{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":29},"01M6D3DRAK8VWESYDZDF8JJDSH","xray","Understand what just happened under the hood - learn AI by seeing it in action","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fxray\u002FSKILL.md",[],[97,102,103],"learn","just",{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":111,"publishedAt":29},"01M6D3DN7BZQDY6143A2QSDP9A","week-review","Review week's progress with concrete accomplishments (not fake percentages), pattern detection, and goal tracking.","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fweek-review\u002FSKILL.md",[110],{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},[112,19,113,114,115,116,117],"week review","pattern detection","detection","tracking","goal","pattern",{"skillNo":119,"name":120,"nameZh":6,"description":121,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":122,"categories":123,"keywords":124,"publishedAt":29},"01M6D3DJ7F1TCFXBBSTQW82WE7","week-plan","Set weekly priorities and plan the week ahead with intelligent suggestions based on goals, calendar shape, and task effort.","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fweek-plan\u002FSKILL.md",[],[125,24,126,127,128,129,130,131],"week plan","calendar","SET","shape","goals","task","priorities",{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":138,"publishedAt":29},"01M6D3DF90D7RC8ZJE4AW2P9VC","triage","Strategically route orphaned files and extract scattered tasks","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftriage\u002FSKILL.md",[],[134,139,140,141,142,143],"tasks","fast","extract","files","route",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":154,"publishedAt":29},"01M6D3DC9BBHK5TASE34SQYXSQ","trello-setup","Connect Trello to Amp for visual Kanban task sync","https:\u002F\u002Fgithub.com\u002Fhemory\u002Famp-legacy-do-not-use\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ftrello-setup\u002FSKILL.md",[150,153],{"categoryNo":151,"categoryName":152,"taxonomyType":68,"taxonomyTypeDesc":69},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":66,"categoryName":67,"taxonomyType":68,"taxonomyTypeDesc":69},[155,156,77,157,80,79,158,130,159,160,161,162,163],"trello","trello setup","sync","token","kanban","bun","visual","api","server"]