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, andcapability-brainstormevidence sources — recurrence is either established by the check's own analysis, validated upstream byreflection-judge, or established by the brainstorm pass. For candidates whoseArtifact:line citesstate/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).
Parse line 1 as the verdict. 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.
After receiving the verdict, append one event to state/proposal-metrics.jsonl:
bun ${CLAUDE_PLUGIN_ROOT}/scripts/append-metrics.ts \
.claude-code-hermit/state/proposal-metrics.jsonl \
'{"ts":"<now ISO>","type":"triage-verdict","verdict":"<CREATE|SUPPRESS|DUPLICATE>","caller":"proposal-create","evidence_source":"<evidence source>","tags":[<caller-supplied tags>]}'
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.
CREATE— proceed with the steps belowDUPLICATE:<PROP-ID> — <reason>: stop, report to the caller: "Proposal already exists as" SUPPRESS — <code>: <reason>: stop, report the suppression reason to the caller
How to Create
Determine the next proposal ID and creation timestamp:
- List all
.claude-code-hermit/proposals/PROP-*.mdfiles - Extract the integer from each filename (regex
PROP-(\d+)), take the max, add 1; zero-pad to 3 digits. If none exist, start at001. - Capture current time as
HHMMSS(6 digits, zero-padded) in thetimezonefromconfig.json, or UTC if unset. - Canonical ID:
PROP-NNN-<slug>-HHMMSS(e.g.PROP-009-capability-brainstorm-103612). This is what goes in frontmatterid:and in all cross-references. The ID equals the filename stem — there is no separate short form in the file.
- List all
Build the filename and create the proposal file:
- Generate a slug from the title:
a. Drop non-ASCII characters, lowercase.
b. Replace every run of non-
[a-z0-9]characters with a single space. c. Split into tokens; drop stopwords:a an the and or of for to in on with by from as is are. d. If filter leaves zero tokens, fall back to the pre-filter token list. e. Take the first 5 tokens; join with-; truncate to 40 chars at a word boundary (drop trailing tokens until ≤40 chars; if a single token exceeds 40, hard-cut it). f. If after all steps the slug is empty (title was all punctuation, all non-ASCII, or itself empty), use the literalproposalas the slug. The filename and id must never contain a double-dash likePROP-009--HHMMSS. - Target filename:
PROP-NNN-<slug>-HHMMSS.md(e.g.PROP-009-capability-brainstorm-103612.md). - If the target filename already exists (same-second collision), append
ato both the filename (...-HHMMSSa.md) and theidfield (PROP-NNN-slug-HHMMSSa). On further collisions, continue throughb,c, … in order. - Create
.claude-code-hermit/proposals/PROP-NNN-<slug>-HHMMSS.mdusing.claude-code-hermit/templates/PROPOSAL.md.template: - Write YAML frontmatter with:
id: the canonical IDPROP-NNN-<slug>-HHMMSS(orPROP-NNN-<slug>-HHMMSSaif the collision guard fired) — equals the filename stem without.mdstatus:proposedsource:manual(default),auto-detected(when invoked byreflect), oroperator-request(when triggered by a direct operator request). This field records proposal origin only — gate bypass is controlled by the caller-suppliedEvidence Source:above, not bysource:.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 fromconfig.jsonif 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 fixroutine— repeating scheduled taskcapability— new agent, skill, or heartbeat itemconstraint— OPERATOR.md refinementbug— 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-brainstormpasses[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## Contextsection 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. - Success signal — push for measurable. When the proposal's benefit is cost-measurable, fill the
## Success Signalsection 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 Signalexplaining 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
- Generate a slug from the title:
a. Drop non-ASCII characters, lowercase.
b. Replace every run of non-
Add a reference to the proposal in
.claude-code-hermit/sessions/SHELL.mdunder the Findings sectionAppend a
createdevent to proposal metrics (includesource,category, andtagsfrom 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/
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.jsoninto OPERATOR.md — propose a/claude-code-hermit:hermit-settingschange instead. Operator-editable prose is for thingsconfig.jsoncan't express (focus, constraints, approval gates, comms style). Routine schedules, channel IDs,permission_mode,agent_name,sign_off,escalation, andidle_behaviorare 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>.mdwith:- 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.mdwith:- 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.mdunder the appropriate group - Run
/claude-code-hermit:heartbeat runto 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