mikeparcewski

wicked-garden-domain-extractor

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).

mikeparcewski 9 2 Updated 1mo ago
GitHub

Install

npx skillscat add mikeparcewski/wicked-garden/wicked-garden-domain-extractor

Install via the SkillsCat registry.

SKILL.md

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:

  1. Run the harness (one Bash call):
    wicked-garden run scripts/domain/extract_loop.py --db "<estate-store>" --time-budget 780
    It seeds its worklist from wicked-core coverage's own unaccounted_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 writes annotate + semantics. Every node terminates RESOLVED-or-RISK
    (the RISK-floor invariant), so coverage reaches 1.0 deterministically; the model
    only upgrades RISK→RESOLVED quality.
  2. Watch stderr (coverage=… unaccounted=… processed=…). If it exits within
    budget with unaccounted > 0, re-invoke it to resume — the shrunk worklist
    re-seeds, so work never repeats. Stop when unaccounted hits 0 or stops shrinking.
    A WARNING: … annotation node_syms no longer exist line is the estate
    id-scheme migration signature — prior annotations are orphaned; see the
    migration section in wicked-garden-domain for the
    required re-run order.
  3. 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
    downstream domain-coverage phase (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, numeric confidence ∈ [0,1] (ISS-11
    hard-fail), grounded provenance{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 (default claude -p).
    Set-but-empty is the kill-switch → the harness's --dry-run deterministic stub only.

Hard invariants (fail-closed — enforced by the harness + validator)

  1. Every requirement has business_rules with minItems 1.
  2. Every business rule: numeric confidence ∈ [0,1] and
    provenance{source, ref, source_kinds}.
  3. legacy_components[] is non-null, never dropped — the SymbolIds the requirement
    covers.
  4. disposition ∈ {keep, modify, drop, new}; a drop needs a disposition_reason.
  5. Rule ids: RULE-/VAL-/ERR- + 3–6 zero-padded digits, unique within a requirement.
  6. Facts REFERENCE SymbolIds; never embed code/file/line.
  7. metadata.schema_version == "1.0.0".

Depth

  • the wicked-garden-domain skill's refs/domain-model-emit.md — field map + the 7 invariants.
  • the wicked-garden-domain skill's refs/extraction-flow.md — the estate/core CLI surface + the _clients.py seam.