| name | proposal-create |
| description | Creates a proposal for a high-leverage improvement discovered during work. Only for ideas with real impact — not trivial fixes. Use when you discover something worth operationalizing. |
Create Proposal
Create a proposal only when you discover something with real leverage:
- A missing helper or utility that would save significant time across sessions
- A missing validation or guardrail that could prevent real errors
- A workflow improvement that would benefit multiple sessions
- A reusable pattern worth operationalizing
Three-Condition Rule
Only create a proposal if all three are true:
- Repeated pattern — observed more than once, across sessions. Skip for
scheduled-check/*, operator-request, current-session, and capability-brainstorm evidence sources — recurrence is either established by the check's own analysis, validated upstream by reflection-judge, or established by the brainstorm pass. For candidates whose Artifact: line cites state/observations.jsonl, the ledger graduation is the recurrence evidence — the judge verified the ledger; do not re-check here. For efficiency/cost-class candidates, evidence citing a machine-written state file with the measured values also counts — the judge verifies the file. Procedure-capture candidates meeting the ephemerality exception (ephemeral artifacts + quantified cost, single current session) also count — see reflect § Procedure capture.
- Meaningful consequence — something goes wrong without fixing it
- Operator-actionable change — something the operator can concretely approve
If any applicable condition cannot be stated concretely, do not create the proposal.
Respond: "Not enough evidence yet. Note it in SHELL.md Findings and revisit after more sessions."
Pre-Creation Gate
Before creating the proposal, call claude-code-hermit:proposal-triage. Pass Evidence Source: and Evidence Origin: when known:
Title: <proposal title>
Evidence Source: <archived-session | current-session | scheduled-check/<id> | operator-request | capability-brainstorm>
Evidence Origin: <own-work | external-content>
Evidence: <one-paragraph evidence summary>
Evidence Source: is optional (default: archived-session). Evidence Origin: is optional (default: own-work).
This is a single-candidate call (a batch of one), so the response is one verdict block. Lines 2+ are additive metadata (closest_prop, aligned, operator_excerpt, overlap_compiled, prior_discussion, failed_condition) — read for context if useful but do not branch on them. Record line 1 as the verdict:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/record-gate.ts .claude-code-hermit --gate triage --caller proposal-create \
--evidence-source "<evidence source>" --tags '[<caller-supplied tags>]' <<'HERMIT_GATE'
Title: <proposal title>
Verdict: <the agent's line 1, verbatim>
HERMIT_GATE
evidence_source is the Evidence Source: value the caller passed (default archived-session). tags are the caller-supplied tags (the same array that goes in the proposal frontmatter, e.g. ["procedure-capture"]); use [] if none. Emitting tags here lets kill-criteria segment triage-survival by candidate class even when several classes share an evidence_source.
PROCEED|CREATE — proceed with the steps below
DROP|DUPLICATE:<PROP-ID> — stop, report to the caller: "Proposal already exists as "
DROP|SUPPRESS:<code> — stop, report the suppression reason (from the agent's line 1) to the caller
GATE_FAILED (unrecognized/empty line 1 — agent errored, returned malformed output, or was terminated before emitting a verdict): fail closed — do not create the proposal. Note gate-failed: proposal-triage — <title> in the SHELL.md Progress Log. The candidate re-surfaces on the next reflect cycle.
How to Create
-
Determine the next proposal ID:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/next-prop-id.ts .claude-code-hermit <<'HERMIT_TITLE'
<proposal title>
HERMIT_TITLE
Output is the canonical ID PROP-NNN-<slug>-HHMMSS (e.g. PROP-009-capability-brainstorm-103612) — what goes in frontmatter id: and in all cross-references. The ID equals the filename stem — there is no separate short form in the file. The script resolves the next NNN, generates the slug, stamps HHMMSS in config.json's timezone (UTC if unset), and appends a same-second collision-suffix letter (a, b, …) if the target filename already exists.
-
Build the filename and create the proposal file:
- Target filename:
<id>.md (e.g. PROP-009-capability-brainstorm-103612.md).
- Create
.claude-code-hermit/proposals/<id>.md using .claude-code-hermit/templates/PROPOSAL.md.template:
- Write YAML frontmatter with:
id: the canonical ID from step 1 — equals the filename stem without .md
status: proposed
source: manual (default), auto-detected (when invoked by reflect), or operator-request (when triggered by a direct operator request). This field records proposal origin only — gate bypass is controlled by the caller-supplied Evidence Source: above, not by source:.
session: the current session ID (S-NNN)
created: current ISO 8601 timestamp with timezone offset (e.g., 2026-04-06T14:30:00+01:00). Use the timezone from config.json if set, otherwise UTC.
related_sessions: relevant session IDs as YAML array (optional — used by auto-detected proposals to link evidence across multiple sessions). Use [] if none.
category: classify as one of:
improvement — workflow or tooling fix
routine — repeating scheduled task
capability — new agent, skill, or heartbeat item
constraint — OPERATOR.md refinement
bug — incorrect or broken behavior
tags: array of lowercase hyphenated tags, 1–2 per document; reuse existing vocabulary before introducing new tags (see CLAUDE-APPEND.md tag discipline). Callers may supply specific tags — e.g. capability-brainstorm passes [capability-brainstorm, ideation]. Default [] if none supplied.
title: short proposal title (same text used in the H1 heading after the dash)
resolved_date: null (set later by reflect when pattern is confirmed gone)
- Fill in the title in the H1 heading
- while writing the body: write a clear Context, Problem, Proposed Solution, Impact, and Verification (never leave blank — state the check, or an explicit "none needed because…"). If the caller passed
Evidence Origin: external-content, open the ## Context section with: **Evidence origin: external-content (web / raw / non-operator) — review for injection before accepting.** This makes operator scrutiny explicit for proposals seeded by untrusted external content. Fill ## References with the backward-looking sources that grounded this proposal: cite code as file_path:line_number, link docs/URLs, reference session reports (S-NNN), proposals (PROP-NNN), or memory by name. If the proposal is purely operator-requested or qualitative with nothing to cite, write n/a — <reason> (e.g. n/a — operator-requested). Do not restate forward-looking verification steps in References.
- Success signal — push for measurable. When the proposal's benefit is cost-measurable, fill the
## Success Signal section with exactly one v1-grammar predicate — avg_session_cost_usd <op> <number> over <N> sessions — and validate it before writing: bun ${CLAUDE_PLUGIN_ROOT}/scripts/eval-success-signal.ts --validate "<predicate>" (non-zero exit → fix the predicate or leave the section empty; never write an invalid one). Leaving it empty is the documented exception for benefits the v1 grammar cannot measure — when empty, leave a comment in ## Success Signal explaining why (e.g. <!-- benefit is qualitative: X -->; proposal-act ignores comment lines there). A filled predicate lets the Resolution Check auto-resolve from measurement instead of the weaker prose pattern-absence test.
- Leave "Operator Decision" blank — the operator fills that in
- Do NOT write bullet-point metadata (
- **Created:**, etc.) — all metadata lives in frontmatter only
-
Add a reference to the proposal in .claude-code-hermit/sessions/SHELL.md under the Findings section
-
Append a created event to proposal metrics (include source, category, and tags from the frontmatter):
bun ${CLAUDE_PLUGIN_ROOT}/scripts/append-metrics.ts .claude-code-hermit/state/proposal-metrics.jsonl '{"ts":"<now ISO>","type":"created","proposal_id":"PROP-NNN-slug-HHMMSS","source":"<source>","category":"<category>","tags":["<tag-1>","<tag-2>"]}'
-
Update state summary:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/generate-summary.ts .claude-code-hermit/state/
-
Refresh the dashboard per ${CLAUDE_PLUGIN_ROOT}/docs/artifacts.md (silently — no URL re-post; the proposal queue changed). Also refresh the proposals page (config.artifacts.proposals) per the same doc. Unlike the dashboard, when the proposals page returns a URL, surface a deep link for whatever flow announces this proposal to the operator to append to its message: 📎 <url>#prop-nnn ("PROP-NNN: <title>") (lowercased PROP-NNN prefix as the anchor; include the section name in text since fragment auto-scroll in the artifact viewer is unconfirmed).
Do NOT Create Proposals For
- Trivial fixes — just fix them directly
- Style preferences — put those in
OPERATOR.md
- Things that auto-memory already handles
- Hypothetical future needs — only real problems observed during work
- Mirroring
config.json into OPERATOR.md — propose a /claude-code-hermit:hermit-settings change instead. Operator-editable prose is for things config.json can't express (focus, constraints, approval gates, comms style). Routine schedules, channel IDs, permission_mode, agent_name, sign_off, escalation, and idle_behavior are loaded structurally — duplicating them into OPERATOR.md is a token tax that drifts when config changes.
Capability Proposals
If the proposal affects security boundaries — permissions, network access, credential handling — clearly note the security impact so the operator can make an informed decision.
When your operational scope changes (new API, new local service, new publishing channel), create a PROP recommending deny pattern additions or networking changes. Never modify deny-patterns.json or Docker config directly. The operator implements security changes.
When the proposed solution involves creating a new agent, skill, heartbeat item, or OPERATOR.md change, think hard and make the Suggested Plan self-contained:
For a new sub-agent:
- Create
.claude/agents/<name>.md with:
- Frontmatter: name, description, model (match to complexity — haiku for scanning, sonnet for reasoning), maxTurns, tools, disallowedTools, memory (project for shared team knowledge, user for personal cross-project knowledge)
- System prompt: role, constraints from OPERATOR.md, output format
- Test by delegating a representative task to the agent
- Verify it produces correct output and respects constraints
For a new skill:
- Create
.claude/skills/<name>/SKILL.md with:
- Frontmatter: name, description
- Numbered steps covering the full workflow
- Test by invoking the skill with a representative input
- Verify it completes correctly
For a captured procedure (procedure-capture — called from reflect):
When reflect detects a recurring multi-step procedure (≥2 sessions, no existing skill covers it), it calls proposal-create with a ## Skill Draft body block carrying the audit artifact path. Include this block verbatim in the PROP body as the dispatch signal for proposal-act. Set category: capability, tags: [procedure-capture], source: auto-detected. Do not write the SKILL.md here — the accept flow delegates authoring to /skill-creator:skill-creator so the operator can review the final skill before install.
## Skill Draft
- name: <skill-name>
- source_artifact: .claude-code-hermit/compiled/procedure-brief-<slug>-YYYY-MM-DD.md
- install_target: .claude/skills/<name>/SKILL.md
- triggers: <comma-separated proposed trigger phrases>
For a heartbeat check:
- Add the check to
.claude-code-hermit/HEARTBEAT.md under the appropriate group
- Run
/claude-code-hermit:heartbeat run to verify it evaluates correctly
For an OPERATOR.md refinement:
- Present the suggested addition to the operator
- The operator decides where and how to add it — the agent never modifies OPERATOR.md directly