paqad-ai
Version:
Spec-driven development framework — AI agents that think before they type
71 lines (54 loc) • 4.05 kB
Markdown
---
name: rule-script-reconciler
description: 'Compares rule-script-map.yml with the rule markdown and the registered scripts, writes RS-* drift findings, and raises user-approvable deltas through the Decision Pause Contract, with no model judgement. Use when feature-development planning starts, or during analyze rules to confirm the map is in sync.'
metadata:
model_tier: fast
cacheable: 'false'
output_format: markdown
paqad-meta: skill.meta.yaml
---
## What It Does
Detects every form of rules-as-scripts drift and writes `.paqad/scripts/rules/.cache/drift.json`:
| Code | Meaning |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| `RS-RULE-ADDED` | A markdown bullet without a `<!-- @rule -->` marker, or a marked rule absent from the map: an ungated addition. |
| `RS-RULE-EDITED` | Marker present, but the text hash differs from the map entry. |
| `RS-RULE-REMOVED` | A map entry whose marker is gone from the markdown. |
| `RS-SCRIPT-STALE` | A rule was edited but its scripts were not regenerated. |
| `RS-FIXTURE-FAIL` | A registered script no longer passes its own fixtures. |
| `RS-CACHE-INVALID` | The findings report exists but its `rule_files_hash` no longer reconciles. |
Any code except `RS-CACHE-INVALID` blocks `feature-development` per the project's `escalation.rule_scripts_stale` setting.
## Use This When
- At `feature-development` planning entry (the planning stage instructions invoke it).
- During `analyze rules`, to confirm the map is in sync before classifying.
## Inputs
- `docs/instructions/rules/rule-script-map.yml` (read-only).
- The rule markdown under `docs/instructions/rules/**` (read-only: no marker embedding here).
- The registered `.paqad/scripts/rules/**/*.mjs` scripts and their fixtures.
- The cached `.paqad/scripts/rules/.cache/report.json` for the cache-validity check.
## Procedure
1. Run the reconciler:
```
node scripts/reconcile.mjs [project-root]
```
Exit 0 = clean. Exit 1 = drift present (blocking).
2. Group findings by code. For each, surface a Decision Pause packet:
- `RS-RULE-ADDED` → "Unmarked rule detected: treat as a new rule (run `analyze rules`) or as an edit of an existing rule?"
- `RS-RULE-EDITED` → "Rule text changed: `edit rule RL-…` (regenerate scripts) or accept as-is?"
- `RS-RULE-REMOVED` → "Marker gone: `remove rule RL-…`?"
- `RS-SCRIPT-STALE` / `RS-FIXTURE-FAIL` → "Regenerate scripts for `RL-…`?"
3. Apply the chosen resolution through `rule-editor` or `rule-script-generator`. Never edit the map directly.
## Output Contract
- `.paqad/scripts/rules/.cache/drift.json` written with findings + counts + `blocked`.
- A `## Drift Findings` markdown block listing each code, count, and one-line detail.
- A `## Pending User Decisions` block for each surfaced packet.
- Under `escalation.rule_scripts_stale: stop|ask`, block planning until resolved.
## Escalate / Stop Conditions
- Block `feature-development` planning on any RS-\* drift except `RS-CACHE-INVALID`, per `escalation.rule_scripts_stale`.
- Never embed markers or write the map from this skill: resolutions route through `rule-editor` / `rule-script-generator`.
- `RS-CACHE-INVALID` is informational; the runner recomputes the report on its next run.
## Resources
- `references/drift-codes.md`: the RS-\* vocabulary + resolution map.
- `runtime/base/skills/rule-script-reconciler/agents/openai.yaml`: agent interface metadata.
- `src/rule-scripts/reconciler.ts`: the drift-detection engine.
- the Decision Pause Contract (in the framework bootstrap): packet semantics.