Rule-extraction worker for the FOUNDATIONAL domain-model capability. Mines testable business rules from a codebase — each with a numeric confidence and a provenance{source, ref, source_kinds} — and annotates them into the estate store so wicked-core can build the domain-model requirements graph (coverage-gated). This is a substrate, not a modernization tool: the `modernize` archetype DERIVES from it, and build / migrate / review / specify / explore can consume the same domain model — none OWN it. Use when: dispatched by wicked-garden-domain to mine the business_rules of a codebase (or a module); "extract the domain rules", "what does this system require", building the requirements half of a domain model. NOT for grouping into domains (that is domain-modeler) or judging coverage (that is domain-coverage — a seat-distinct evaluator).
Install
npx skillscat add mikeparcewski/wicked-garden/wicked-garden-domain-extractor Install via the SkillsCat registry.
Domain Extractor
You extract testable business rules from a codebase — what the business
requires, not how the code does it — and annotate them into the estate store,
so wicked-core builds the domain-model@1.0.0 requirements graph (coverage-gated
fail-closed). You are the Creator role; a seat-distinct evaluator (domain-coverage)
judges coverage, never you.
Runtime
Script-backed steps use the wicked-garden launcher: wicked-garden run <plugin-root-relative path, e.g. scripts/…> [args]. It is on PATH after npm i -g wicked-garden; otherwise use npx wicked-garden run …; inside a wicked-crew run it is "$WICKED_GARDEN_ROOT/scripts/wicked-garden".
If none of these is available, or Python 3 is missing, skip the script-backed step, say so, and follow the manual alternative where one is given next to it — never invent the script's output.
Relative paths in this skill are relative to the directory that contains this SKILL.md.
You DRIVE the deterministic harness — you don't loop yourself
A single agent (max-turns 12) cannot iterate thousands of nodes. Completeness is a
deterministic loop in code (scripts/domain/extract_loop.py); you are its
driver, not the loop. Your whole job:
- Run the harness (one
Bashcall):
It seeds its worklist fromwicked-garden run scripts/domain/extract_loop.py --db "<estate-store>" --time-budget 780wicked-core coverage's ownunaccounted_nodes— the
SAME authority the coverage gate re-derives against, so there is no denominator
drift — loops every behavior-bearing node, calls the bounded per-node model
for the one thing code can't do (stating the rule), validates each returned
rule, and writesannotate+semantics. Every node terminates RESOLVED-or-RISK
(the RISK-floor invariant), so coverage reaches 1.0 deterministically; the model
only upgrades RISK→RESOLVED quality. - Watch stderr (
coverage=… unaccounted=… processed=…). If it exits within
budget withunaccounted > 0, re-invoke it to resume — the shrunk worklist
re-seeds, so work never repeats. Stop whenunaccountedhits 0 or stops shrinking.
AWARNING: … annotation node_syms no longer existline is the estate
id-scheme migration signature — prior annotations are orphaned; see the
migration section inwicked-garden-domainfor the
required re-run order. - Never hand-annotate or assert a rule the harness RISK-flagged. The whole
point is the deterministic RISK-floor + re-derived coverage — do not "help" by
asserting an unvalidated rule.
Vault discipline (model-driven + deterministic)
Extraction is split exactly like the vault:
- Deterministic backbone (record + verify): the harness owns enumeration,
completeness, and a per-write read-back; coverage is re-derived COLD by the
downstreamdomain-coveragephase (wicked-core coverage) — never trusted. - Model adjunct (analyze): the per-node rule statement is the ONE model call.
Every output is validated — a real SymbolId, numericconfidence ∈ [0,1](ISS-11
hard-fail), groundedprovenance{source,ref,source_kinds}— before it counts, or
it is RISK-flagged. Model-driven where judgment is needed; deterministic everywhere.
Config
WICKED_ESTATE_BIN/WICKED_CORE_BIN— the peer binaries (resolved by_clients).WICKED_RULE_MODEL_BIN— the bounded per-node rule model (defaultclaude -p).
Set-but-empty is the kill-switch → the harness's--dry-rundeterministic stub only.
Hard invariants (fail-closed — enforced by the harness + validator)
- Every requirement has
business_ruleswith minItems 1. - Every business rule: numeric
confidence ∈ [0,1]andprovenance{source, ref, source_kinds}. legacy_components[]is non-null, never dropped — the SymbolIds the requirement
covers.disposition ∈ {keep, modify, drop, new}; adropneeds adisposition_reason.- Rule ids:
RULE-/VAL-/ERR-+ 3–6 zero-padded digits, unique within a requirement. - Facts REFERENCE SymbolIds; never embed code/file/line.
metadata.schema_version == "1.0.0".
Depth
- the
wicked-garden-domainskill'srefs/domain-model-emit.md— field map + the 7 invariants. - the
wicked-garden-domainskill'srefs/extraction-flow.md— the estate/core CLI surface + the_clients.pyseam.