A subnet's vpc_id names something. To emit network Context, Rootform must
establish which eligible virtual network it names. Knowing the target Concept
alone is insufficient: several instances can share that classification.
Value matching compares an evaluated source value with target identity
attributes. The target Rule declares identity; the emission's nested match
chooses paths with by and a comparison strategy. For a subnet's VPC ID,
target.id and "exact" express the intended comparison.
Verified reference evidence names an instance through the expression
recorded in a paired saved plan. The target Rule declares which attribute paths
are endpoints. For example, aws_vpc.main.id can identify aws_vpc.main when
id is declared in its endpoint block, even before that ID is known.
The .rf.hcl emission still reads via = source.vpc_id; it does not contain
that Terraform address.
These solve different problems. identity does not recover a reference from
an unknown value. endpoint does not make a literal value unique. An emission
without nested match has no value-comparison route. Without a usable target
identity or endpoint, classification alone cannot supply the missing proof.
The Rule walkthrough shows both declarations in their actual positions. Rules and Emissions define their syntax.
A state records producer evidence; it is not a live cloud inventory.
Plan JSON reference lists also record dependencies, but cannot distinguish
vpc.id from a transformation of that ID. The optional saved plan supplies
the configuration needed to make that distinction. Rootform verifies its
pairing with the JSON; a working checkout does not substitute for it.
A refused pair is reported and recorded. --require-enrichment makes refusal
stop the run. Plan inputs gives the export procedure.
Bare references and supported pass-through variables, locals and module outputs
can name an endpoint. Functions, conditionals, computed indexes and transformed
references cannot. Their evaluated values may still match by identity.
via = provider.host specifically needs a verified provider configuration
reference on Planned; Rootform never reads its literal provider value.
See Traversals and scope
for exact supported forms and collection handling.
A target identity defaults to scope = "provider": value comparisons require
compatible provider address and alias. An unavailable alias leaves compatibility
uncertain, including for state input. Rootform cannot drop that candidate to
force a unique result. Use "global" only for identities unique across provider
configurations by construction, such as a service-account email.
Multiple known matching targets, or candidates whose identities cannot be
compared, prevent a unique value match. Listing id, self_link and name
does not build a composite key; it accepts alternative reference forms. Add a
path only when it carries the form the source may use.
A verified reference can identify one instance despite shared or unknown identity values. It can also name an instance across provider configurations, because it identifies the instance directly rather than comparing scoped values.
A reference must still satisfy the emission's to contract. Naming an
uninterpreted instance is insufficient for a fact target. Known values never
override conflicting verified reference evidence.
external = "allow" permits a known unmatched value to identify an external
endpoint only after eligible in-scope candidates have been excluded. An unknown
candidate prevents that conclusion. The default "deny" leaves it indeterminate;
neither outcome proves remote existence or absence.
Disclosure is separate: "none" omits external identity from saved output,
"record" permits it in JSON, and "report" also permits it in reports.
Sensitive values never become external identities. Omission of disclose
defaults to "none"; omission of external defaults to "deny".
External and data endpoints
owns the exact rules.
A closure belongs to one source instance, emission and stage. resolved means
the emission settled its endpoints; absent means evidence established no
endpoint under its declared policy; indeterminate preserves an unresolved
part and its reason. It does not mean the object itself is missing.
on_null and on_empty let the author decide whether a known null or empty
value establishes absence or remains indeterminate. An undefined path, unknown
value or sensitive value without reference proof cannot establish absence.
A list can establish some facts while an unresolved element keeps the closure
indeterminate. Those confirmed facts remain usable, but do not prove a complete
count or the absence of other endpoints.
Continue with Composition for implementation members, or Policies over facts for what an assertion can conclude from these closures. Exact outcomes and reasons live in Omission and uncertainty.