plugins/claude-code-hermit/skills/proposal-act/SKILL.md
Accept, defer, dismiss, or resolve a proposal. For accepted proposals, asks how to proceed: start implementing now, create a session task, or note for manual implementation. Activates on messages like "accept PROP-", "dismiss PROP-", "defer PROP-", "resolve PROP-".
npx skillsauth add gtapps/claude-code-hermit proposal-actInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Take action on a proposal: accept, defer, dismiss, or resolve.
If this skill was invoked from a channel-arrived message (the inbound prompt contains a <channel source="..."> tag), reply via that channel's reply tool. Otherwise emit to conversation. On a channel-tagged turn, step 4's bounded ask (below) also queues a durable micro-proposal entry via proposal.ts queue-micro — see channel-responder § Channel-safe ask bridge — so it survives compaction or a session restart.
/claude-code-hermit:proposal-act accept PROP-019
/claude-code-hermit:proposal-act defer PROP-015
/claude-code-hermit:proposal-act dismiss PROP-012
/claude-code-hermit:proposal-act resolve PROP-008
/claude-code-hermit:proposal-act accept PROP-019 --answer "session task"
The --answer form is not typed by an operator — it's how a channel-safe resolution re-enters step 4 after an out-of-band reply (see § Channel re-entry below).
If no action or ID is provided, ask the operator which proposal and action.
Before reading any proposal file, resolve the operator's input to a filename:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts resolve-id .claude-code-hermit "<operator input>"
MATCH|<filename> — proceed with that file.NONE|not-a-prop-id — error "Not a PROP id."NONE|no-match — error "No proposal matches [input]. Use /proposal-list to see available proposals."AMBIGUOUS|<json array of {file, title}> — show a disambiguation prompt:
Multiple proposals match PROP-NNN:
PROP-NNN-capability-brainstorm-103612 — [title of first match]
PROP-NNN-session-cost-tracking-104207 — [title of second match]
Reply with the full ID to continue.
Re-resolve with the operator's reply.All timestamps in frontmatter and Operator Decision text use ISO 8601 with timezone offset (e.g., 2026-04-06T14:30:00+01:00). Use the timezone from config.json if set, otherwise UTC. @now in a proposal.ts patch --set value or in a stdin Decision:/Set: line expands to this stamp — prefer it over composing the timestamp yourself.
Every flow below (accept, defer, dismiss, resolve) changes a proposal's status. After its final "Respond" step, refresh the dashboard and the proposals page (config.artifacts.proposals) per ${CLAUDE_PLUGIN_ROOT}/docs/artifacts.md — both silently, no URL re-post (unlike proposal-create's initial announcement, these status-change confirmations don't carry a deep link).
When the operator accepts a proposal:
Resolve the proposal file using the resolution algorithm above, then read it.
Determine what to set. Read state/runtime.json for session_id and session_state (both used below — session_state drives step 4's branch). From the file already read in step 1:
responded: if currently false, plan --set responded=true for the patch call below and fire the first-response event now, before that patch call, so its summary regen already reflects it:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts event .claude-code-hermit responded --id=PROP-NNN --action=accept
If responded is already true, skip both (prevents double-counting).accepted_in_session: if session_id is non-null, plan --set accepted_in_session=<session_id>. If no session is active (session_id is null), leave it unset (frontmatter default null stays).success_signal (optional): check whether the body has a ## Success Signal section with a non-empty predicate line (ignore comment lines starting with <!--). If found, validate it:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts success-signal --validate "<predicate line>"
Exit 0 → plan a stdin Set: success_signal=<predicate line> line for the patch call (free text — never argv --set). Exit non-zero → plan a proposal.ts shell-append warning: PROP-NNN success_signal ignored: <reason printed by the script>. No section, or empty/comment-only → leave success_signal unset. Never block accept regardless of outcome.Patch. One call applies the frontmatter flip, session tracking, success signal, and the Operator Decision timestamp — assembled from what step 2 determined:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts patch .claude-code-hermit <filename> \
--set status=accepted --set accepted_date=@now \
[--set responded=true] [--set accepted_in_session=<session_id>] <<'HERMIT_PATCH'
Decision: Accepted on @now.
[Set: success_signal=<predicate line>]
HERMIT_PATCH
Do NOT set resolved_date — resolution happens when reflect confirms the pattern is gone. OK|<id> confirms the write; ERROR|<reason> means nothing was patched — report it to the caller/operator and stop.
3a. Routine proposals. If the proposal metadata contains Type: routine and a ## Config section with a JSON block, upsert it into config.json:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts routine .claude-code-hermit <<'HERMIT_ROUTINE'
<the ## Config JSON block, verbatim>
HERMIT_ROUTINE
The script validates id/schedule/skill/enabled are present and upserts by id — OK|added / OK|updated, or ERROR|<reason> (nothing written; report it and stop).
/claude-code-hermit:hermit-routines load to register it immediately."Ask: "How should this be implemented?"
Channel-tagged turn: do not wait interactively for a reply in this turn. Send the question via the channel reply tool in plain voice with the three options numbered — "Suggestion #N — start now, queue it as a task, or leave it to you?" (derive #N per proposal-list §4a; never surface PROP-NNN or the title's bracket prefix to the channel). AND queue a pending micro-proposal entry:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts queue-micro .claude-code-hermit <<'HERMIT_MP'
{"tier":1,"question":"Suggestion #N accepted — how should it be implemented?","options":["implement now","session task","manual"],"on_resolve":"/claude-code-hermit:proposal-act accept PROP-NNN --answer {answer}"}
HERMIT_MP
(the on_resolve id stays PROP-NNN — internal, never shown). Then stop — steps 1-3a already ran, so status: accepted is a safe resting state until the operator answers (immediately in this same conversational turn, or later via the § Channel re-entry path below). The interactive terminal path below is unchanged.
"Start implementing now" (default, typical answer): run the falsification gate, then handle session lifecycle, then execute in this turn.
Falsification gate (runs first, before any session transition). Verify the proposal is actionable as written with a read-only pass. Skip only when the body contains ## Skill Improvement and /skill-creator:skill-creator is in the available-skills list (step (e) routes that to /skill-creator:skill-creator) — if ## Skill Improvement is present but skill-creator is absent, the proposal becomes a code-edit implementation, so the gate runs to produce a PROCEED file list for the dispatch. Also skip if the body contains ## Skill Draft — authoring is delegated to /skill-creator:skill-creator on accept, not a code-edit plan — but first check that the source_artifact path listed in ## Skill Draft exists and is readable (if the file is missing or unreadable, REJECT with code stale-paths — the procedure brief was removed or archived; the operator should re-run reflect to generate a fresh brief).
Agent selection — check the harness's available-skills list (never claude plugin list or disk checks):
feature-dev:feature-dev in available-skills → use feature-dev:code-explorer as the subagent.feature-dev:feature-dev absent → fall back to the native Plan agent. Read only the returned text; ignore any file it writes under ~/.claude/plans/.Invoke with the proposal's ## Context and ## Proposed Solution sections plus this fixed instruction:
"You are a read-only falsification gate. Verify every cited path and symbol against the current code. Return line 1 as exactly:
REJECT: <already-done | partially-done | stale-paths | nonexistent-symbols | too-vague> — <one-line evidence>orPROCEED(+ complete file list to modify). If REJECT, give file:line evidence. Do not produce a build plan for a rejected proposal. Do not write any files."
Append the returned line-1 verdict to the proposal's ## Operator Decision section as provenance, then branch:
PROCEED → continue to the session-lifecycle branch below (step (a)). Use the agent's complete file list over any files mentioned in the proposal body.REJECT (stop before any session transition — session_state and SHELL.md Task: stay untouched):
accepted. Operator re-scopes and re-runs /proposal-act accept PROP-NNN.session_state already read from state/runtime.json in step 2 to branch.
b. Idle: pipe Task: Implement PROP-NNN: <title> on stdin to bun ${CLAUDE_PLUGIN_ROOT}/scripts/session-archive.ts open --state-dir=.claude-code-hermit to transition to in_progress and fill SHELL.md Task. Proceed to (e).
c. In progress: confirm before switching: "Currently working on: <current task>. Switch to PROP-NNN? Y/N".[HH:MM] switched to PROP-NNN: <title> (prior task: <prior task>) to SHELL.md ## Progress Log; overwrite SHELL.md Task: field with "Implement PROP-NNN: <title>"; runtime.json session_state stays in_progress. Proceed to (e).## Skill Improvement and skill-creator:skill-creator is in the available-skills list, use /skill-creator:skill-creator for the implementation (in-main; continues to e.5). Before invoking skill-creator, parse the source_artifact: line from the ## Skill Improvement body; if it is present and the path is readable (search compiled/ then compiled/.archive/), read the brief and pass its content as input context to skill-creator improve — this anchors the improvement to the skill's original spec. Missing or unreadable anchor: proceed without it (no REJECT — an improve proposal is still actionable without the brief, unlike ## Skill Draft which hard-rejects stale paths). If the body contains ## Skill Draft, follow the procedure-capture install flow below (in-main; continues to e.5). Otherwise, dispatch the full implementation tail to the native general-purpose agent (this includes ## Skill Improvement proposals when skill-creator is absent):Dispatch (falsification gate returned PROCEED, no in-main skill handler):
Invoke general-purpose via the Agent tool with this prompt (fill in the bracketed value). The subagent inherits CLAUDE.md/CLAUDE.local.md, can invoke skills, and can spawn nested subagents — so it runs the whole tail (implement → quality gate → verification) in its own isolated context and returns one report.
Implement the accepted proposal at
<absolute path to PROP-NNN-*.md>, then run its quality gate and verification. Work entirely in this context; your final message is the only thing returned to the caller.
- Read the proposal file. The
## Operator Decisionsection contains aPROCEEDline from the falsification gate with the authoritative file list — use that list as your scope (over any files mentioned in the proposal body).- Do the edits and any test/fix loops yourself. You may spawn a nested Explore subagent if the proposal warrants a search.
- Quality gate. Ask the gate; do not judge the tier or the files yourself:
One JSON line back:bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts quality-gate .claude-code-hermit <absolute path to the PROP file> --files-json '<JSON array of the files you touched, repo-root-relative>'{"tier","action","reason","focus_files"}.SKIP→ no cleanup.RUN→ invoke/claude-code-hermit:simplifyfocused onfocus_files, and capture its totals line (applied N · deduped M · principle-rejected K · …). Best-effort: if the gate or/simplifyerrors, note it and continue — never block on this step.- Verification. Read the proposal's
## Verificationsection. If it has real steps (more than the HTML-comment placeholder), perform them. If a step fails, attempt one fix and re-verify; if it still fails, setVerification: failedwith the output and stop (do not loop further). If the section is empty or placeholder-only, setVerification: none defined.- You cannot prompt the operator — if you hit an ambiguous spec or an undecidable/destructive choice at any step, stop and return an escalation block rather than guessing.
Return exactly this structure as your final message (nothing else):
Status: implemented | escalated | blocked: <reason> Touched files: <relative paths, space-separated | none> Tests run: <commands + pass/fail summary | none> Quality gate: <tier> — simplify <totals line> | skipped: <reason> | n/a Verification: passed | failed: <output> | none defined Deferred for operator: <none | what was ambiguous and the safe no-op you took>
After the subagent returns (the dispatched path ran its own quality gate + verification, so it skips main's e.5/e.6 and is handled here):
Status: implemented and Verification: is passed or none defined → run /proposal-act resolve PROP-NNN, then notify the operator (interactive) or channel (autonomous), building the message from the Quality gate field: if it carries a simplify totals line → "PROP-NNN implemented and resolved. /simplify applied N edits (M deduped, K rejected on principle)." (use "… /simplify made no changes." when N == 0, and "… /simplify completed (totals unavailable)." if the line is unparseable); if it is skipped: or n/a → "PROP-NNN implemented and resolved."Verification: failed: <output> → do not resolve. Surface the failure output to the operator (interactive) or channel (autonomous). Proposal status stays accepted.Status: escalated or Status: blocked: <reason> → do not resolve. Surface the Deferred for operator block to the operator (interactive) or channel (autonomous). Proposal status stays accepted.If the body is vague and the falsification gate did not return PROCEED, ask the operator for clarification before proceeding.
Procedure-capture install flow (when body contains ## Skill Draft):
name, source_artifact, install_target, and triggers from the ## Skill Draft block.install_target (.claude/skills/<name>/SKILL.md) already exists, do not overwrite. Ask the operator: "Skill <name> already exists at <install_target>. Overwrite / Rename / Cancel?" Default = Cancel./skill-creator:skill-creator using source_artifact (the procedure brief in compiled/) as input. Pass the proposed name and triggers so it can author the correct frontmatter and trigger phrases. /skill-creator:skill-creator outputs a proposed SKILL.md.## Operator Decision section.
/proposal-act accept PROP-NNN after revising the procedure brief..claude/skills/<name>/ and write the authored SKILL.md there. The procedure brief in compiled/ stays as the permanent audit trail — do not move or delete it.<name> installed at <install_target>. Commit it if you want it tracked in version control."Verification for procedure-capture proposals (e.6 note): the ## Verification section of a procedure-capture PROP should instruct reading the installed file's frontmatter (name/description parse) rather than checking the live available-skills list — the harness only picks up new skills on the next session reload, so the live list is unreliable here. A missing or malformed installed file blocks resolution per the normal e.6 contract.
e.5. Quality gate. Applies to in-main implementations only (the ## Skill Improvement → skill-creator and ## Skill Draft → procedure-capture branches). Dispatched implementations ran the same gate inside the subagent (step (e)) and are resolved there.
Build a touched-files list from the writes made during the in-main implementation, written repo-root-relative (the frame `git diff --name-only` uses). If you can't reliably enumerate it (multi-turn work), omit `--files-json` and the gate falls back to the working-tree diff.
```bash
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts quality-gate .claude-code-hermit <path to the PROP file> [--files-json '["path/a","path/b"]']
```
One JSON line back: `{"tier","action","reason","focus_files"}`. The script owns tier resolution, the session-bookkeeping filter, and the RUN/SKIP call — the same code the dispatched path runs, so the two cannot disagree. Act on `action`:
- **`SKIP`** → no cleanup. Proceed to (f). Notification: "PROP-NNN implemented and resolved." (add `Skipped cleanup: <reason>` when the reason is more specific than the budget tier).
- **`RUN`** → invoke `/claude-code-hermit:simplify` focused on `focus_files`:
```
/claude-code-hermit:simplify focus on PROP-NNN implementation: path/a, path/b
```
It runs three parallel reviewers (reuse, quality, efficiency), applies the edits it picks, and ends with a totals line: `applied N · deduped M · principle-rejected K · stale-anchor skips L · parse failures P`. Notification: "PROP-NNN implemented and resolved. /simplify applied N edits (M deduped, K rejected on principle)." Use "… /simplify made no changes." when `N == 0`, and "… /simplify completed (totals unavailable)." if the line is unparseable — never block resolution.
**The quality gate is cleanup, not correctness** — `/simplify` does not check that the proposal works. Correctness is the `## Verification` gate in step (e.6); proposals with no defined verification still resolve, but the skip is recorded.
Best-effort throughout: if the gate or `/simplify` errors, log a one-line warning to SHELL.md Findings and fall back to skip. The gate never blocks resolution.
e.6. Verification gate (in-main implementations only — dispatched implementations verify inside the subagent). Read the proposal's ## Verification section.
- If it contains real steps (more than the HTML-comment placeholder), perform them now — after the quality gate has applied any /simplify edits — before resolving. If a defined step fails, do not resolve: report the failure to the operator (or channel in autonomous mode) and stop.
- If the section is empty, missing, or contains only its placeholder comment, append Verification: none defined for PROP-NNN — skipped. to SHELL.md ## Findings and proceed. The omission is recorded, not blocked.
Unlike the e.5 quality gate (best-effort, never blocks), e.6 **blocks resolution when a defined verification step fails** — that is the correctness check the quality gate does not provide.
f. (in-main path) When verifiably done: run /proposal-act resolve PROP-NNN, then notify the operator (or channel in autonomous mode) with the tier-appropriate message from (e.5). (Dispatched implementations resolve + notify in the step (e) post-return handling.)
"Create a session task" → assemble the full NEXT-TASK.md content (Task/Context/Suggested Plan derived from the proposal), appending any of the following bullets to the end of the Suggested Plan, in order, numbered sequentially from 4. (quality-gate bullet is last so /claude-code-hermit:simplify reviews any skill-creator output):
## Skill Improvement AND /skill-creator:skill-creator is available) Use /skill-creator:skill-creator to build and validate the skill.## Skill Draft) Use /skill-creator:skill-creator to author the captured procedure from the source_artifact (see ## Skill Draft), present the final SKILL.md to the operator for confirmation, then install it to the install_target only on confirmation.quality_gate.tier in .claude-code-hermit/config.json is not "budget" — i.e. "balanced" or "quality") Before committing, run: bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts quality-gate .claude-code-hermit <this PROP file>. On "action":"RUN", run /claude-code-hermit:simplify focused on its focus_files, then commit.
The bullet defers the call rather than making it here: at queue time the implementation hasn't happened, so there is no diff to classify. The future session runs the same verb the other two paths run, with no --files-json — the working-tree diff is the evidence by then.Then create it — the script's exclusive create makes the "already pending" check atomic (no separate existence pre-check needed):
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts next-task .claude-code-hermit <<'HERMIT_NEXT_TASK'
# Next Task (from PROP-NNN)
## Task
[One-line task derived from the proposal's Proposed Solution]
## Context
[Summary of the pattern/problem from the proposal, including Related Sessions]
## Suggested Plan
1. [Step derived from Proposed Solution]
2. [Step derived from Proposed Solution]
3. Verify the fix resolves the pattern
[any appended bullets from above, numbered from 4.]
HERMIT_NEXT_TASK
OK — confirm: "Task prepared. The next /session-start will offer this as the default task."ERROR|next-task-exists — another proposal's task is already pending; nothing was written. Status still flips to accepted (operator intent is recorded, via the step 3 patch above). Notify: "PROP-NNN accepted. NEXT-TASK is already pending another proposal. Run /session-start to consume it first, then re-run /proposal-act accept PROP-NNN and pick 'Start implementing now' or manual.""I'll handle it manually" → Just mark accepted. Respond: "Marked as accepted. No further action taken."
Notify the operator: "PROP-NNN accepted: [title]". On a channel-tagged turn (Step 0), use plain voice instead, matching the step-4 branch actually taken: start now → "Got it — starting on Suggestion #N."; session task → "Queued Suggestion #N as a task for the next session."; manual → "Marked Suggestion #N as accepted — leaving it to you." (#N derivation and the never-surface-PROP-NNN rule are canonical in proposal-list §4a — don't restate them here.)
Note: There is no "Update OPERATOR.md" path. OPERATOR.md is operator-owned — the agent reads it but does not modify it. If the operator wants to update OPERATOR.md based on a proposal, they do it themselves.
--answer)When invoked as accept PROP-NNN --answer "<label>" (channel-responder resolving the micro-proposal entry queued by step 4's channel branch, either later in the same turn or in a fresh session): the proposal's frontmatter status is already accepted from the original turn, so skip steps 1-3a entirely — do not re-append a duplicate "Accepted on …" timestamp or re-fire the responded event. Match <label> case-insensitively by prefix against the three step-4 options and jump straight into the matching branch:
implement now → "Start implementing now" (falsification gate onward; the autonomous-mode channel notifies already present in that branch apply as usual).session task → "Create a session task".manual → "I'll handle it manually".responded field. If false, fire the event now — before the patch call below, so its summary regen reflects it:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts event .claude-code-hermit responded --id=PROP-NNN --action=defer
Skip if already true.bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts patch .claude-code-hermit <filename> \
--set status=deferred --set deferred_date=@now [--set responded=true] <<'HERMIT_PATCH'
Decision: Deferred on @now. Reason: [operator's note]
HERMIT_PATCH
Do NOT set resolved_date — deferral is not a terminal state. Omit the Decision: line entirely if no note was given. OK|<id> confirms; ERROR|<reason> means nothing was patched — report it and stop.Deferred proposals still appear in /proposal-list but are sorted below open proposals.
responded field. If false, fire the event now — before the patch call below, so its summary regen reflects it:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts event .claude-code-hermit responded --id=PROP-NNN --action=dismiss
Skip if already true.bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts patch .claude-code-hermit <filename> \
--set status=dismissed --set dismissed_date=@now --set resolved_date=@now [--set responded=true] <<'HERMIT_PATCH'
Decision: Dismissed on @now. Reason: [operator's reason]
HERMIT_PATCH
Omit the Decision: line entirely if no reason was given. OK|<id> confirms; ERROR|<reason> means nothing was patched — report it and stop.
4b. Dismissal learning — only when a reason was provided in step 3. Judge whether the reason states a durable preference, rule, or taste that applies to a family of future proposals (e.g. "don't propose process changes for things I do twice a year", "stop suggesting test-coverage proposals on docs-only changes") versus a one-off or proposal-specific response ("not now", "already did this manually", "the analysis is wrong", "duplicate of last week"). If generalizable, issue the standard "remember it" reflection framed as a feedback-type entry: state the preference as a rule, add a brief Why: and How to apply: so proposal-triage and reflection-judge can match it in their memory cross-check. Apply auto-memory discipline: respect WHAT_NOT_TO_SAVE (no file paths, no debugging recipes, no facts derivable from grep), keep it concise. The native auto-memory flow writes feedback_<slug>.md and updates the MEMORY.md index — do not write those files directly. If the reason is one-off or sub-threshold, skip — save nothing.Dismissed proposals are hidden from the default /proposal-list view. Use "show all" with /proposal-list to see them.
Used when reflect has surfaced a sparse-cadence proposal as a resolution candidate (pattern absent from recent sessions but cadence too infrequent to auto-resolve). Also available directly: /claude-code-hermit:proposal-act resolve PROP-NNN.
Resolve the proposal file using the resolution algorithm above, then read it.
Append a resolved event to proposal-metrics.jsonl — before the patch call below, so its summary regen reflects it:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts event .claude-code-hermit resolved --id=PROP-NNN
Patch — frontmatter flip, Operator Decision timestamp, and the compaction-boundary marker in one call:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts patch .claude-code-hermit <filename> \
--set status=resolved --set resolved_date=@now --request-compact <<'HERMIT_PATCH'
Decision: Resolved on @now.
HERMIT_PATCH
Do NOT set dismissed_date. If the resolve was triggered by reflect's auto-resolve flow (pattern absent from recent sessions), the caller may append "Pattern confirmed absent." to the Decision line, but this is no longer the default — resolve also covers implementation completion via the Start-now branch.
--request-compact writes state/compact-requested.json ({"requested_at": <now>, "reason": "proposal-resolve"}, singleton — overwrite unconditionally). A resolved proposal's implementation is fully committed, so this is a safe moment for the watchdog's routine-hygiene compactor (maybeContextCompact) to waive its interval cooldown on the next tick. Both the dispatched-path post-return handling and the in-main path (f) route through this Resolve Flow, so one call here covers both; batched overwrites of the same singleton coalesce into a single compaction (existing operator-silence + quiescence guards).
OK|<id> confirms; ERROR|<reason> means nothing was patched — report it and stop.
Respond: "PROP-NNN resolved."
No first-response tracking on resolve — the proposal was already accepted and that event was already logged.
tools
Composes and delivers the daily fitness brief — a forward-looking morning read (readiness + today's plan) or a backward-looking evening read (today's training, or an earned-rest note, + tomorrow's setup) — in the operator's configured voice. Invoke with /claude-code-fitness-hermit:fitness-brief --morning|--evening|--slot <name>. Becomes the plugin's two daily beats — the morning Strava connectivity check and the evening activity sync, RPE binding, and Run deep-dive.
development
Renew the hermit's long-lived Claude login token over the channel, before it expires. Relays a one-time sign-in link to the operator, takes the code back, installs the new token, and restarts. Activates on messages like 'relogin', 'renew my login', 'reauth', 'the login is expiring', or when doctor's credential-expiry check flags setup-token.
development
Synthesizes the past 7 days of archived briefs into a weekly digest — top stories, emerging vs faded themes, category activity, and per-source performance built from archive frontmatter. Delivers to the operator's configured channel and archives a weekly note. Designed as a weekly routine. Invoke with /feed-hermit:weekly-digest.
development
Manage developing story arcs tracked across briefs — add, resolve, and list active arcs in compiled/story-arcs-*.md. Arc Watch keywords drive the feed-brief arc-tagging enrichment. Invoke with /feed-hermit:story-arcs add|resolve|list.