Subchapter 25.32
references/phases/discover/discover.mdMarkdown10 KBView on GitHub
Inventory what exists on Azure into azure-resource-inventory.json in
$MIGRATION_DIR/, and derive azure-resource-clusters.json from it. This phase is
composed of FRAGMENTS (independent discoverers) plus one ASSEMBLER, declared in the
frontmatter _fragments/_assemble — the interpreter runs each fragment whose
_trigger is true (loading its _file only then), then the assembler. Read each
unit file for its own contract; this phase owns only lifecycle and the cross-cutting
_postconditions.
Two facts the frontmatter cannot express:
Fragments are additive, not redundant, and they may disagree. IaC carries
declared intent (module structure, naming, what is parameterized, and resources
declared but never deployed). Live az and RDfA carry actual state. When two
sources disagree about the same azure_id, the assembler records BOTH values and
which one won as a drift entry. A disagreement is never silently reconciled — the
drift is itself customer-visible value.
The canonical type vocabulary is ARM, not Terraform. Four of the five
discovery sources speak Microsoft.* natively; only Terraform needs translating.
That translation happens inside discover-iac.md, so every downstream table
keys off one vocabulary. azure_id is the full ARM resource ID, which embeds
subscription and resource group — one field supplies the cluster seed key, the
environment scope, and uniqueness with no derivation.
Terraform discovery is real and clustering is real. One fragment (discover-iac.md,
Terraform only) plus an assembler that writes both artifacts.
| Lands in | What |
|---|---|
| step 2 | Bicep + ARM inside discover-iac.md; the billing and app-code fragments |
| step 2 | The rdfa fragment, then the live az path — security contract, capture pre-work, parsing fragment, in that order |
| step 4 | patterns.md — pattern RECOGNITION only. Seed / split / merge / tier / primary / roles are implemented in references/clustering/; every cluster carries pattern_status: "catalog_absent" until the catalog exists |
The live az path will NOT be a plain fragment. This phase runs under
_exec: { _agent: rw } with _interactive: false, and a dispatched worker is
file-only — it cannot prompt for consent. Live capture therefore becomes
main-window pre-work invoked from this phase’s _preconditions prose, writing to
$MIGRATION_DIR/live-capture/, with the dispatched fragment merely parsing that
directory. RDfA needs no such split: reading an archive the customer already handed
over is not interactive.
_init state setup per INTERPRETER.md § _init: true._trigger holds.discover-assemble.md._postconditions. On all-pass emit HANDOFF_OK; on any failure emit
GATE_FAIL and stop. Do not patch an artifact to force a gate to pass.