Skip to content
Back to skills

Proposal Create

ASecurity

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.

  • 74 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 3, 2026
ai-agentsrustgobashexpressdockerapisecurity

Works with

  • api

Security analysis

A100/100

Scanned October 3, 2026

npx -y skills add gtapps/hermitd --skill proposal-create --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Proposal Create?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Proposal Create
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/gtapps-proposal-create-hermitd/badge)](https://www.skillsdirectory.com/skills/gtapps-proposal-create-hermitd)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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.
---

Record notes only inside an open record's turn, using `bun ${CLAUDE_PLUGIN_ROOT}/scripts/task.ts note .hermit <id>` with the note on stdin. Otherwise skip record notes. Never edit a task file directly.

# Create Proposal

**Options:** `--no-artifacts` (alias `--no-artifact`) skips the final artifact refreshes and artifact URL announcement. Useful for batches or callers that refresh afterward.

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

A routine invoking `reflect --check-id <id> --check <namespaced skill>` supplies findings through the normal judge and triage gates with `Evidence Source: scheduled-check/<id>` and `Sessions: none`. Preserve that provenance when creating the proposal.

## Commands
- `artifact-render`: `bun ${CLAUDE_PLUGIN_ROOT}/scripts/artifact.ts render <type> .hermit`

## Three-Condition Rule

Only create a proposal if all three are true:
1. **Repeated pattern** — observed more than once, across sessions. Recurrence is already verified upstream for every evidence source except `archived-session` (by the routine-invoked check's own analysis, the `reflection-judge`, the brainstorm pass, a cited `state/observations.jsonl` graduation, or a cited machine-written state file with the measured values), so re-establish it here only for `archived-session` candidates. Procedure-capture candidates meeting the ephemerality exception (ephemeral artifacts + quantified cost, single current session) also count (see reflect § Procedure capture).
2. **Meaningful consequence** — something goes wrong without fixing it
3. **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 open record notes and revisit after more sessions."

## Pre-Creation Gate

Pin the hermit root before dispatching:
```bash
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts anchor .hermit
```
Its stdout is one whole `Anchor: root=… memory_dir=…` line, already carrying the `Anchor:` prefix — paste it verbatim as the first line of the agent prompt, do not re-prefix it. On a non-zero exit there is no line to paste: do not dispatch, rerun with the absolute state dir the error names in place of `.hermit`.

Before creating the proposal, call `hermitd:proposal-triage`. Pass `Evidence Source:` and `Evidence Origin:` when known:
```
Anchor: root=<absolute hermit root> memory_dir=<absolute auto-memory dir>
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:
```bash
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts gate .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 <PROP-ID>"
- `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. When inside an open task record turn, note it with the record id; otherwise report it to the caller:
  ```bash
  bun ${CLAUDE_PLUGIN_ROOT}/scripts/task.ts note .hermit <id> <<'HERMIT_LINE'
  gate-failed: proposal-triage — <title> — <the agent's line 1, verbatim>
  HERMIT_LINE
  ```
  The candidate re-surfaces on the next reflect cycle.

## How to Create

Call `proposal.ts create` with the full proposal as one heredoc — header lines, a bare `---` separator, then the raw markdown body:
```bash
bun ${CLAUDE_PLUGIN_ROOT}/scripts/proposal.ts create .hermit <<'HERMIT_PROPOSAL'
Title: <proposal title>
Source: manual
Session: T-...
Category: improvement
Tags: ["tag-1","tag-2"]
Related-Sessions: []
Findings: <optional one-line summary>
---
## Context
<clear description>

## Problem
<what's wrong or missing>

## Proposed Solution
<concrete steps>

## Impact
<effort vs benefit>

## Verification
<how this will be checked>

## References
<sources, or "n/a — <reason>">

## Success Signal
<predicate, or an HTML comment explaining why none>

## Operator Decision
HERMIT_PROPOSAL
```

The script assigns the canonical ID `PROP-NNN-<slug>-HHMMSS` (resolves the next `NNN`, generates the slug, stamps `HHMMSS` in `config.json`'s timezone, claims it atomically with a same-second collision-suffix letter on conflict), writes `.hermit/proposals/<id>.md`, records the `created` metrics event, and regenerates the proposals index and state summary — one transactional call.

- **stdout is the canonical ID** on success (e.g. `PROP-009-capability-brainstorm-103612`) — record it for all cross-references; it equals the filename stem, there is no separate short form.
- **`ERROR|<token>` on stdout** means nothing was created — report the token to the caller/operator; never retry with a guessed ID.
- **`WARN:` lines on stderr** mean the proposal file was created but a bookkeeping step (metrics, index/summary regen) failed — note the warning via `task.ts note .hermit <id>` when in an open task record turn; otherwise report it. Never retry the whole call.

Header fields:
- `Title:` — required.
- `Source:` — `manual` (default), `auto-detected` (when invoked by `reflect`), or `operator-request` (when triggered by a direct operator request). Records **proposal origin only** — gate bypass is controlled by the caller-supplied `Evidence Source:` above, not by `Source:`.
- `Self-Eval-Key:`: optional; preserve the exact `self_eval_key` supplied by heartbeat so later decisions remain linked to that checklist item. Omit for other proposals.
- `Session:` — optional; defaults to the active session from `state/runtime.json` when omitted.
- `Category:` — optional (default `improvement`); 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:` — JSON 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"]`. Omit or `[]` if none.
- `Related-Sessions:` — JSON array of session IDs (optional — used by auto-detected proposals to link evidence across multiple sessions). Omit or `[]` if none.
- `Findings:`; optional one-line summary. Inside an open record's turn, record a note with `task.ts note` separately.

Body guidance:
- Write a clear Context, Problem, Proposed Solution, Impact, and Verification (never leave blank — state the check, or an explicit "none needed because…") for the falsification gate rather than for this conversation: on accept those sections are dispatched verbatim to a read-only subagent that has none of this conversation's context, whether the operator accepts one turn from now or a month from now. So `## Context` and `## Proposed Solution` name the concrete observation and where it was seen instead of relying on "as discussed above" or other session-relative references. `## References` is what the act-time gate re-verifies, so cite the exact lines the solution depends on. If the caller passed `Evidence Origin: external-content`, open `## Context` 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 task records (`T-...`), proposals (`PROP-NNN`), or memory by name. If 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 `## Success Signal` 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/proposal.ts success-signal --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 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. (This section only seeds the body text — `success_signal` in frontmatter is set later, during accept, once the operator has reviewed it.)
- Leave `## Operator Decision` blank — the operator fills that in.
- Do NOT write bullet-point metadata (`- **Created:**`, etc.) — all metadata lives in the header lines / frontmatter only.

Skip this paragraph when either opt-out flag is supplied. Finally, 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 it for whatever flow announces this proposal to the operator: append **at most one** `📎 <url>` line to that flow's message, regardless of how many proposals it created in this run — never one per proposal, and never one at all when no URL was returned.

## Do NOT Create Proposals For

- Trivial fixes — just fix them directly
- Style preferences — memory records them; only a settled endpoint on a task-scoped output graduates to the owning skill (never propose OPERATOR.md as a destination — it is operator-authored)
- Things that auto-memory already handles — recording a decision is memory's job; *relocating* settled operative content into the skill that owns the task is not (that is a valid consolidation proposal)
- Hypothetical future needs — only real problems observed during work
- **Mirroring `config.json` into OPERATOR.md** — propose a `/hermitd: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`, and `escalation` 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 permission-rule 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, make the Suggested Plan self-contained:

**For a new sub-agent:**
1. Create `.claude/agents/<name>.md` with:
   - Frontmatter: name, description, model (the cheapest tier that handles the task), maxTurns, tools, disallowedTools, memory (project for shared team knowledge, user for personal cross-project knowledge)
   - System prompt: role, constraints from OPERATOR.md, output format
2. Test by delegating a representative task to the agent
3. Verify it produces correct output and respects constraints

**For a new skill:**
1. Create `.claude/skills/<name>/SKILL.md` with:
   - Frontmatter: name, description
   - Goal, constraints, and how to verify; numbered steps only where order is load-bearing
2. Test by invoking the skill with a representative input
3. 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` (Lane A) or `category: routine` (Lane B, when the brief carries `proposed_routine`), `tags: [procedure-capture]`, `source: auto-detected`. Do not write the SKILL.md here — the accept flow authors it in-main so the operator can review the final skill before install.
```markdown
## Skill Draft
- name: <skill-name>
- source_artifact: .hermit/compiled/procedure-brief-<slug>-YYYY-MM-DD.md
- install_target: .claude/skills/<name>/SKILL.md
- triggers: <comma-separated proposed trigger phrases>
```

When the brief carries `proposed_agent_name`, also include this block verbatim. Do not write the agent file here — the accept flow authors it in-main.
```markdown
## Agent Draft
- name: <agent-name>
- source_artifact: .hermit/compiled/procedure-brief-<slug>-YYYY-MM-DD.md
- install_target: .claude/agents/<name>.md
- model: <cheapest tier that handles the task>
- tools: <tool list>
```

When the brief carries `proposed_routine` (Lane B), include a `## Config` block holding the routine JSON — this is what `proposal-act` 3a consumes:
```markdown
## Config
{"id":"<slug>","schedule":"<cron>","skill":"<invocation>","enabled":true}
```

**For a heartbeat check:**
1. Add the check to `.hermit/HEARTBEAT.md` under the appropriate group
2. Run `/hermitd:heartbeat run` to verify it evaluates correctly

**For an OPERATOR.md refinement:**
1. Present the suggested addition to the operator
2. The operator decides where and how to add it — the agent never modifies OPERATOR.md directly

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…