paqad-ai
Version:
Spec-driven development framework — AI agents that think before they type
65 lines (49 loc) • 3.99 kB
Markdown
---
name: rule-editor
description: "Adds, edits, removes or downgrades one rule in rules-as-scripts with a per-rule cascade and no global rebuild: mints or keeps the stable RL-hash id, regenerates only that rule's scripts, and writes the map through src/rule-scripts/apply.ts. Use when the user asks to add, edit or remove a rule, or to mark one unverifiable."
metadata:
model_tier: medium
cacheable: 'false'
output_format: markdown
paqad-meta: skill.meta.yaml
---
## What It Does
Owns the mutation cascade so adding, editing, or removing a rule recomputes only what changed: never a full regeneration:
| Mode | Effect |
| --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| add | Inserts the bullet into the target rule file, mints a stable `RL-<hash>` id, then classifies + generates scripts for **only the new rule**. |
| edit | Updates the bullet text, **preserves the id**, regenerates only that rule's scripts, and surfaces a behavior diff via Decision Pause when scripts change. |
| remove | Removes the bullet, moves the map entry to `archived:` (delayed delete); scripts pruned on the next regen pass. |
| downgrade | Keeps the rule, deletes its scripts, flips the map entry to `verifiability.kind: unverifiable` with a recorded reason. |
## Use This When
- A user prompt matches the priority-225 router rules `add rule`, `edit rule`, `remove rule`, or `mark rule as unverifiable`.
## Inputs
- The target rule file (for `add`) or the `RL-<id>` (for edit/remove/downgrade).
- The new rule text (`add`, `edit`) or downgrade reason (`downgrade`).
- `docs/instructions/rules/rule-script-map.yml` (written only via the bundled wrapper → `src/rule-scripts/apply.ts`).
## Procedure
1. Apply the deterministic mechanics:
```
node scripts/edit-rule.mjs add <project-root> <source-rel> "<text>"
node scripts/edit-rule.mjs edit <project-root> RL-<id> "<text>"
node scripts/edit-rule.mjs remove <project-root> RL-<id>
node scripts/edit-rule.mjs downgrade <project-root> RL-<id> "<reason>"
```
2. For `add` and `edit`: re-run `analyze rules` (idempotent, touches only the changed rule) then `generate rule scripts` with `only_rule_id` set to the affected id, so only that rule's scripts are regenerated.
3. For `edit`, diff the regenerated scripts against the prior ones; if behavior changed, surface a Decision Pause packet before accepting.
4. Present a `## Rule Change Summary` naming the id, the mode, and any scripts added/removed.
## Output Contract
- The rule markdown updated with a preserved/minted `<!-- @rule RL-<hash> -->` marker.
- `rule-script-map.yml` updated via `src/rule-scripts/apply.ts` (archive on remove, unverifiable on downgrade, script set on add/edit).
- A `## Rule Change Summary` markdown block.
## Escalate / Stop Conditions
- `edit` / `remove` / `downgrade` on an id not found on disk stops with a clear error: never guesses which rule was meant.
- Behavior-changing `edit` regenerations surface a Decision Pause diff before acceptance.
- Never edit `rule-script-map.yml` by hand; the wrapper is the only path.
- A new rule that contradicts an existing one is surfaced as a conflict (via `rule-analyzer`) before its scripts are written.
## Resources
- `references/edit-modes.md`: the four sub-modes + cascade contract.
- `runtime/base/skills/rule-editor/agents/openai.yaml`: agent interface metadata.
- `src/rule-scripts/editor.ts`: markdown add/edit/remove mechanics.
- `src/rule-scripts/mutate.ts`: per-rule map mutations.
- the Decision Pause Contract (in the framework bootstrap): packet semantics for edit diffs + conflicts.