From 66e4a6f83d7baa8d6a8b0a39e8078b1e13eaf23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Z=20Sink=C3=B3?= Date: Sun, 8 Nov 2026 15:37:48 +0100 Subject: [PATCH] docs: D5-2, the realization context: what exists, where the chain breaks, and a proposal D5 asked where host, base_path, key_id, resource_id and revision should come from. This surveys what is written and what is in code about the realization context they should be derived from, marking every item implemented, scaffold, concept or not read, with every claim re-read from a live file (the knowledge base was used for orientation only). Found: the logical identity (the CIC uid) and its separation from the provider identity, the state object's provenance and revision, the host-side correlation and conformance code in the Relay (wired only to drift, not to the execution path), the plan-then-execute-signed-plan decision, the OIS seam and the signing identity exist or are written. The realization context itself does not: no document defines it and no Relay Go type carries it, the state object's binding has only provider and provider_id, and the target values reach the module as free request fields. The model exists, but the implementation bridge breaks there. Proposes (concept) a versioned, authenticated realization context per object and provider, the derivation of each target field from it, and a realization digest that makes target_digest a function of the context inside the chain that execution_digest commits to. Lists the open questions that the sources cannot decide, and the sources that were not read (the Forms engine, the schema registry, OIS). Documentation only; nothing is implemented. --- [signing-metadata] key = cic-my-sign-key signature = vault:v1:MEUCIQDKvOw6AJ3B/ctltkjTjJs6RT2+j2tOKzTkCBlHLm23EgIgYcgcipYw+ss/y+pljJbkcEcFSiidLxaoOFkffmOWrOQ= hash-algorithm = sha256 digest = COf9/9ApopusYKgaBw4Xwi28Rixm1w0L30YFH8Ip4No= [certificate] -----BEGIN CERTIFICATE----- MIICBjCCAaygAwIBAgIUSnRMR6RPnEbg296XWPOqq/u5PCwwCgYIKoZIzj0EAwIw QzELMAkGA1UEBhMCSFUxGTAXBgNVBAoMEENlbnRyYWxJbmZyYUNvcmUxGTAXBgNV BAMMEENJQyBEZXZlbG9wZXIgQ0EwHhcNMjYwMzIwMTMyMjU5WhcNMjYxMjMxMTMy MjU5WjBFMQswCQYDVQQGEwJIVTEZMBcGA1UECgwQQ2VudHJhbEluZnJhQ29yZTEb MBkGA1UEAwwSR2Fib3IgWm9sdGFuIFNpbmtvMFkwEwYHKoZIzj0CAQYIKoZIzj0D AQcDQgAEIG2CVmTfmLB9pLLclj7YmP2eedAjklpy4LGrU2ijoiy6Xqpuybv7OgJe i+ez31s65NEV8+X/ByeX1cstR988z6N8MHowCQYDVR0TBAIwADAdBgNVHQ4EFgQU yZN6AIX/TNnIJ9GwAa/NRN3ujHAwHwYDVR0jBBgwFoAUXn6CHYzPUqU4JVP8g+OS WeDYjhcwDgYDVR0PAQH/BAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF BQcDBDAKBggqhkjOPQQDAgNIADBFAiEA+bFzXRoJ4PCQbhAAtpkcMjt0vNj5rEW0 lOMBGDNyaWkCIB1vmM7PcZzv/c9bIrxF5kqv6QXomouhByUfeNUTbpKW -----END CERTIFICATE----- --- MANIFEST.sha256 | 3 +- docs/design/README.md | 3 + docs/design/specs/realization-context.md | 158 +++++++++++++++++++++++ 3 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 docs/design/specs/realization-context.md diff --git a/MANIFEST.sha256 b/MANIFEST.sha256 index 6b1159f..319bcb6 100644 --- a/MANIFEST.sha256 +++ b/MANIFEST.sha256 @@ -156,6 +156,7 @@ a4c522ffc80fc87ff4244ba3da8f19591d8206ed9acb4d1d7896ced9f75714a3 docs/design/sp a6728222647cd2d265b28a522ecd3f8d779e01bb8bea5367912f4cd7fb8c72d2 module/execute_create_id_test.go a6c2baaaf307c0718ecaa43f654742269c3830fd9ff899a000af5e56713e5082 tools/__init__.py a85fe8169218b1abe90093cc5d7f8bccc0cb1eb98a4670881b31d37834e54893 tools/oci-extract/client_test.go +a8976b81a8096be5dd2b1404be36b4b295a1f92a3cae6be6fe9630a61855c6ec docs/design/README.md a8ecf9c2551505fd5a4c477c735c88fff9c4627136dade955cdcbfc16d8ca131 docs/en/makefile-cheatsheet.md aedb718131b5633d08f58ac67b23d3940b4fbffd98e93c9f75db3cf80903f1f8 module/schemas/core/instance.json b1609aa1ad37f8f682e3025d866eaebe9719802b34aac580387d3bce65935f30 module/observed.go @@ -171,9 +172,9 @@ b73da39348121a3ae5bf42915a4ab3c35653b7c9fb5a4c575a9ce0d89da66c7a docs/en/wasm-m b8107f8b819135d4ba3d56804ecca545c24bde54a381f5ddde7ac19815253734 docs/design/forms-integration-direction.md b8e7c23cfe46a0daf7d3441b15657e9d4b35c4bf50f9421c2841dfbf19cacc82 docs/en/architecture.yaml b9325f58a95216b240f3715a773e34fe8cdfa4d5fe48a5e7b32002a40be5cc2e tests/test_tools/test_finalize_release.py -b96d9bec819c23a253271f3f26ab999e27179cbf6381a4403f090a04bc9195f2 docs/design/README.md bb8a1743ab9f77a309bd851b4a1660f6f2420900455a5a0dfb83f4e6905968ff module/abi_manifest_test.go bbe93c718d90a03de5aab2999031c7097bd63a8e40ec14589c8dbe4364a4ec52 renovate.json +bdcc6a3130f3522ce94c9c200247fd6925a47f22cab85eb0a799d17b83c203ed docs/design/specs/realization-context.md bdea227cb29b579b2daaa7fa398102adc096ff9073c78bd9ec1f0dde44b89824 docs/design/relay-requirements.md bef22a55d1559676a57b4a05b48efc7cd226d3d733a1c932e183666679046b53 module/testdata/vcn-v1/cases/drift/expected/evidence.claims.json bfccbd3cd778ac6f0458b7d45d7b25e2cbdc0a789f40e81c1de476f8aab44363 tools/schemalib/loader.py diff --git a/docs/design/README.md b/docs/design/README.md index dc67e64..2d5bb20 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -31,6 +31,9 @@ namespace it opens. Written 2026-07-18 from the design session recorded in computed over. - [specs/plan-digest.md](specs/plan-digest.md) — `plan_digest`, `target_digest`, `execution_digest` and the gate `execute` applies before it signs anything. +- [specs/realization-context.md](specs/realization-context.md) — D5-2: a survey of what is written + and what is in code about the realization context that target data should be derived from, + where the chain breaks, and a proposal (concept). - [specs/target-origin-and-path-safety.md](specs/target-origin-and-path-safety.md) — D5: a measurement of what the module does with a caller-given `host` and `base_path`, and a proposal (concept) for where target data should come from; probes and output in diff --git a/docs/design/specs/realization-context.md b/docs/design/specs/realization-context.md new file mode 100644 index 0000000..8885d25 --- /dev/null +++ b/docs/design/specs/realization-context.md @@ -0,0 +1,158 @@ +# Realization context (D5-2): what exists, where the chain breaks, and a contract proposal + +Status: sections 1 to 3 are a **survey** of what is written and what is in code, every item marked +`implemented`, `scaffold`, `concept` or `not read`. Section 4 is a **proposal (concept)**: nothing in it +is implemented in the module or the Relay. + +The question: how does a general, provider-independent intent become a realization context bound +to a provider, an environment and a CIC object, so that the `host`, `base_path`, `key_id`, +`resource_id` and `revision` of an execution are **derived and provable**, not supplied (D5, +`target-origin-and-path-safety.md`, section 3)? Without that, an exactly extracted API version would +only be one more well-formed parameter. + +The premise is the project owner's statement of the CIC model: the target data belong to the +realization context, the provider contract and the observed state. This survey tests it against what +is written down and what is in the code; where the sources are silent it says so. + +## 1. Method and sources + +- The `cic-graph` knowledge base was consulted for orientation only. It is a snapshot (built + 2026-10-16, one source dirty at build, some sources behind upstream); **every claim below was + re-read from a live file** and is cited by file. +- Read live: this repository's `docs/design/` (`state-model.md`, `forms-integration-direction.md`, + `architecture.md`, `relay-requirements.md`, the D5 and M4 documents); CIC-Relay at `55a899f` + (`features/feature-011-oci-provider/design.md`, `core/nexus/iac`, `core/nexus/drift`, + `core/nexus/ois`, `core/cabinet`, `cmd/relay/cic_flow_*`). +- **Not read in this pass:** the Forms engine and its docs (`cic-primitive-forms`, + `cic-primitive-engine`), the schema registry (`cic-schema-registry`), `primitives`, + `CIC-basic-knowledge`, and the OIS repository. Statements about them are second-hand and marked. + +## 2. What exists + +| Element | Where | State | What it carries | +|---|---|---|---| +| Intent and state are two representations of one logical object; **correlation by the stable CIC `uid`, never by `provider_id`**; correspondence checked object-level | `docs/design/specs/state-model.md` (status: spec), Relay `features/feature-011-oci-provider/design.md` | spec, `concept` as a whole; `observe` (implemented) returns the applied-config projection and the provider metadata | `metadata.uid`; the state object's `binding: {provider, provider_id}`, `revision` (etag), `provenance: {intent_commit, observer_module_hash, observed_at}` | +| Logical references resolved against the provider (`route_table: production-private` to a `route_table_id`) | the same two files | `concept` | a correspondence rule per resource kind | +| Host-side comparison and object-level conformance (intent against state, with an observation-coverage envelope) | Relay `core/nexus/iac` (`compare.go`, `conformance.go`, `observation.go`) | `implemented` as Go code with tests; imported (non-test) by `core/nexus/drift`, which uses it for a scalar drift check; the IaC loader of `cmd/relay/main.go` uses the same package. **Not** imported by the cabinet or the `cic-flow` execution path | comparison and verdicts; `provider_id` is treated as a state-only field | +| The data path: user intent, Relay decomposition and routing, Forms (pinned schema binding, validation, expansion, defaults with origin, policy resolution, normalization), expanded object with digests, module, Relay execution boundary, provider, observe | `docs/design/forms-integration-direction.md`, section 3 | `concept` on the module side (the document says so); the Forms engine exists in Go and Rust (second-hand: **not read**) | the schema and object digests of the expanded object | +| "The module does not attest its own work and holds no custody"; **plan, then execute the exact signed plan; observe and verify are host-side** | Relay `features/feature-011-oci-provider/design.md` ("Boundary") | recorded design decision; the `cic-flow` host module (`sign`, `actuate`) is `implemented`; the approval and signed-plan step is `concept` (`relay-requirements.md` R7) | the host seals evidence, grants scoped capabilities | +| Intent authorization seam (OIS gate: `Intent{Actor, Action, TargetRef, Reason}`, `Policy.Authorize`) | Relay `core/nexus/ois`, `features/feature-010/ois-gate.md` | `implemented` as a seam; its non-test importers are the rollback recorder and the demo, not the module's execution path | an authorization decision on a declared intent | +| Signing identity and reach | the module's `project.yaml` `capability_manifest` (egress `*.oraclecloud.com`, secret handle `oci/*`), Relay `cmd/relay/cic_flow_*` | `implemented` | the module **declares** its own reach in its signed manifest; the key stays in the Relay's Vault signer | +| State commit model: a state is committed only with verifiable provenance, confirmed physical realization (PoSE) and no unresolved drift | `CIC-basic-knowledge` `docs/en/reality/state_commit_model.md` | second-hand from the knowledge base, **not read live** | the conditions for a final state | + +## 3. Where the chain breaks + +``` +concept -> code -> runtime -> audit +``` + +| Link | State | Evidence | +|---|---|---| +| intent to the expanded object (Forms) | code exists elsewhere, **not read** here | `forms-integration-direction.md` section 3 | +| **realization context: which provider account, environment, contract version and execution identity this object is realized in** | **does not exist** | no document in this repository defines it; no Go type for a realization, deployment context, environment or binding in the Relay's `cmd`, `core`, `pkg` at `55a899f` (searched by type name); in the spec's example the state object's `binding` has only `provider` and `provider_id` | +| derivation of `host`, `base_path`, `key_id` from it | does not exist | measured: all five target values are caller-supplied to every entry point (`destroy-invoke-binding.md`, `target-origin-and-path-safety.md`); the registry records no API version, base path or host | +| routing an object to a module and an environment | `concept` | `forms-integration-direction.md` section 3 ("module routing") | +| an authenticated execution context for the guest | `concept` | `relay-requirements.md` R6; the Relay passes only the component id | +| approval and single use | `concept` | R7, R8 | +| execution of an operation | `implemented` and measured against real OCI for several operations; M1 to M4a gates in the module | `manual-verification.md`, the module tests | +| observed state, correlation, correspondence | `observe` `implemented`; `core/nexus/iac` `implemented` but wired only to drift | section 2 | +| evidence | partial: a post-hoc, best-effort trace in the cabinet | `relay-requirements.md` R9 | + +**The model exists, but the implementation bridge breaks at the realization context**: between the +expanded intent object and the execution target. Everything on either side has a written form or code; +the object that says *in which provider environment, under which provider contract and with which +execution identity this logical object is realized* has neither, and the values that should come from +it enter the module as free request fields today. + +What the existing material already gives, and the proposal below reuses: the logical identity +(`uid`) and its separation from the provider identity (`provider_id`); the state object's +`provenance` and `revision`; the schema digests and the `contract_digest` already inside +`plan_digest`; the plan-then-execute-signed-plan decision; and the host-side correlation and +conformance code. + +## 4. Proposal: a realization context (concept) + +### 4.1 What it is + +A versioned, authenticated record that says, for one logical object (its CIC `uid`) and one provider, +where and under what contract that object is realized. It is **not** part of the domain intent and +**not** a request parameter of a provider call. It is produced by the layer that realizes the object +(not the provider module) and reaches an execution through the authenticated execution context the +Relay provides (R6). + +Content (concept; names open): + +| Member | Meaning | Becomes | +|---|---|---| +| `object` | the CIC `uid` (and kind) | the correlation key | +| `provider` | which provider and provider module | module routing | +| `environment` | provider account scope and region/realm | `host`, by the provider contract's host rule | +| `provider_contract` | the registry digest the object is realized under | `base_path` (the API version) and the operation set | +| `execution_identity` | a reference to the signing identity (a handle such as `oci/prod`), never key material | `key_id` and the scoped capability | +| `binding` | the provider identity of the current realization, if any (`provider_id`) | `resource_id` | +| `observation` | the observation the revision comes from (source, time, digest) | `revision` | +| `issued_by`, `policy_decision`, `valid` | who derived and issued it, under which decision, for how long | authority and validity | + +### 4.2 How the target is derived + +| Target field | Derived from | By | +|---|---|---| +| `host` | `environment` and the provider contract's host rule (the rule recorded in the provider contract, not hard-coded in a harness) | the realization layer; the manifest allowlist stays an upper bound | +| `base_path` | `provider_contract` (the API version recorded per service in the registry: D5-1) | the module, from the registry digest | +| `key_id` | `execution_identity` resolved by the Relay | the Relay | +| `resource_id` | `binding.provider_id`, found by `uid` correlation | the state model | +| `revision` | `observation` | the observer | + +### 4.3 How it ties to what already exists + +`target_digest` becomes a function of the derived target and of a **realization digest** over the +context, with its own domain tag and the same `cic-canonical-json/1` framing; the plan then rests on +a chain the approval transitively commits to through `execution_digest`: + +``` +intent digest, schema digests -> plan_digest (with contract_digest) +realization digest -> target_digest +observation digest -> revision +plan_digest + target_digest -> execution_digest (what an approval names) +``` + +The module, given the context through the authenticated execution context, recomputes the target from +it and compares; the Relay verifies the context's authenticity and policy (R6, R7); the host-side +correlation and conformance code (`core/nexus/iac`) and the observation are the verification after +the execution; the trace records the context and the digests (R9). A signed observation is +evidence of what was read, not proof of the physical state: the state commit model's physical- +realization condition is not claimed to be met by it. + +Until such a context exists, the module's `target` input stays what the M4a gate proves consistent +and nothing more: a caller-supplied value. + +### 4.4 Relation to OIS + +OIS (the intent authorization seam) decides whether a consequence may be applied. The realization +context says which provider environment, contract and identity the consequence applies to. They are +separate: an approval of a consequence is not an identification of its target, and an identified +target is not an approval. + +## 5. Open questions (for the owner; the sources cannot decide them) + +1. **Where a realization context is authored and stored**: a deployment repository, the Relay's + configuration, a schema kind in the schema registry, or elsewhere. +2. **Granularity**: one context per environment shared by many objects (with the object binding kept + in the state), or one per object. +3. **Who issues and signs it**, and what the authenticator is. +4. **The provider contract's record of the host rule and the API version** (D5-1: extend the registry + and the extractor), and whether the host rule is a pattern or a list. +5. **Routing and decomposition**: how one intent that spans providers or regions becomes several + realizations (the data path calls this "object decomposition" and "module routing": `concept`). +6. **Lifecycle**: rotation and revocation of the execution identity binding; what happens to an + approved but unexecuted plan when its context changes. +7. **The Forms side**: where in "defaults with origin" and "policy resolution" a context-derived value + would enter; this needs the Forms engine and its documents read, which this pass did not do. + +## What this does not claim + +The realization context is not implemented anywhere and no document in this repository defined it +before this one. Nothing here is verified against the Forms engine, the schema registry or the OIS +repository, which were not read in this pass. The Relay facts are from `55a899f`, read, not run. +Section 4 is a proposal: the premise it rests on is the owner's statement of the model, and the +open questions above are the points where that statement has to be completed before anything is built.