Brownfield (upstream of the pipeline)

The SKRAFT pipeline assumes two things a legacy codebase does not offer: an already-triaged backlog and code that is safe to change. The brownfield workflows manufacture both — upstream, on the human’s request.

Why — the pipeline assumes what brownfield lacks

The DISCOVER → DISCUSS → DESIGN → DISTILL → DELIVER pipeline starts from a backlog of prioritized issues and from code that a testing discipline makes safe to evolve. A legacy (“brownfield”) system arrives with no product documentation and, often, no test safety net. Dropping it into the pipeline as-is asks DISCOVER to triage a backlog that does not exist, or DELIVER to change code whose real behavior nobody knows.

SKRAFT answers with two standalone workflows, distinct from the pipeline: the human invokes them directly, they are not orchestrator phases, and they never touch its state. Each covers a need the pipeline presupposes.

Two workflows, two needs

Need Workflow What it produces
Understand undocumented code brownfield-analyst an HVE-format PRD, consumed by HVE agents to create issues
Secure then transform a legacy brownfield-harness-builderbrownfield-refactorer a characterization test safety net, then a refactor that keeps it green

Both start from scratch (neither depends on the other) and stay governed by the human at the moments that matter.

Workflow 1 — from existing code to a PRD

flowchart LR
    H(["human"]) --> BA[["brownfield-analyst"]]
    BA --> CB["characterize-brownfield<br/>(scan, confidence, coverage)"]
    CB --> G{"gate<br/>PASS / CONCERNS / FAIL"}
    G -->|CONCERNS/FAIL| CHK["human checkpoint<br/>(validation checklist)"]
    G -->|PASS| CP["compose-brownfield-prd<br/>(HVE PRD, 17 sections)"]
    CHK --> CP
    CP --> PRD[("docs/prds/name.md")]
    PRD -.-> HVE(["HVE agents<br/>GitHub Manager, prd-to-wit"])
    HVE -.-> DISCOVER(["pipeline: DISCOVER"])

characterize-brownfield reconstructs what the system does: stack, feature inventory, integration map, existing API contracts, technical debt. Its central rule is honesty about confidence: every claim is either a fact verified by a tool call, or an inference tagged High / Medium / Low. A brownfield PRD built on false certainty is worse than one that says “unknown.” An optional coverage traceability facet (adapted from test-architecture practice) rates each behavior FULL / PARTIAL / NONE and feeds a PASS / CONCERNS / FAIL gate; below the threshold, the human confirms or corrects before proceeding.

compose-brownfield-prd then maps that characterization onto the exact HVE PRD format (17 sections, FR-/NFR- IDs, traceability). This PRD is not a dead end: it is the deliverable the human hands to the HVE agents (GitHub Backlog Manager, prd-to-wit) that turn it into issues and user stories — the backlog DISCOVER expects.

Workflow 2 — secure then transform

flowchart LR
    H(["human"]) --> HB[["brownfield-harness-builder"]]
    HB --> CWC["characterize-with-contracts<br/>(contracts + Microcks)"]
    CWC --> GN{"net GREEN on<br/>current code?"}
    GN -->|no| FIX["fix the HARNESS<br/>never the code"]
    FIX --> CWC
    GN -->|yes| RF[["brownfield-refactorer"]]
    RF --> CH{"strategy<br/>(human's choice)"}
    CH -->|change in place| MK["mikado-method"]
    CH -->|replace| SF["strangler-fig-method"]
    MK --> RW["refactoring-worker<br/>per leaf / slice"]
    SF --> RW
    RW --> V[("GREEN commits<br/>net + build")]

The net first. characterize-with-contracts discovers (or reconstructs) the service’s API contract, stands up Microcks mocks for its dependencies, and writes characterization tests — a golden master that locks in the current behavior, bugs included. A bug captured here is a documented bug, not a test to fix. This net reuses the existing contract-testing-roster and mocking-strategy-roster skills as-is (v1 targets .NET; the roster keeps the stack extensible). The brownfield-harness-builder only clears its gate when the net is green on unmodified code: a red test before any refactoring means the harness is wrong, not the code.

« Code without tests is bad code. » — Feathers, M., Working Effectively with Legacy Code, 2004.

Once the net is green, the brownfield-refactorer recommends a strategy — never imposes it: a structural change this consequential stays a human decision.

Each leaf (Mikado) or slice (Strangler) goes to a fresh-context refactoring-worker that returns a terminal ADVANCE / EXPAND / DONE / BLOCKED signal. The net is the sensor: any behavioral regression at the API boundary becomes a red test — a discovered Mikado prerequisite, or a Strangler slice that cannot cut over.

How it feeds the pipeline

Both workflows sit upstream of the pipeline, not inside it: they run outside skraft-orchestrator, but their output closes the loop back into it.

flowchart LR
    subgraph BF ["brownfield (standalone, outside the orchestrator)"]
        BA[["brownfield-analyst"]] --> PRD[("docs/prds/name.md")]
    end
    PRD -->|"human hands off the PRD"| GHM(["GitHub Backlog Manager<br/>(HVE agent)"])
    GHM -->|"creates issues / user stories"| ISSUES[("GitHub backlog")]
    ISSUES -->|"triage"| ORCH(["skraft-orchestrator"])
    ORCH --> DISCOVER(["DISCOVER"]) --> DISCUSS(["DISCUSS"]) --> DESIGN(["DESIGN"]) --> DISTILL(["DISTILL"]) --> DELIVER(["DELIVER"])

What stays with the human

Nothing here is autonomous end to end. The human chooses the workflow, decides the refactoring strategy, confirms gates below threshold, and — for Mikado — runs the graph: the one step the method does not delegate, because deciding which prerequisite to attack is judgment, not execution.

Sources

Terms to know: golden master, characterization, contract, facade — defined in the glossary.