From 64f7a54be3f68debf97960247378fe88dab8e067 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Mon, 10 Aug 2026 23:34:04 +0900 Subject: [PATCH] docs: type bootstrap record inputs --- docs/build-system.md | 74 ++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/docs/build-system.md b/docs/build-system.md index 6c183b31..27ada257 100644 --- a/docs/build-system.md +++ b/docs/build-system.md @@ -165,7 +165,7 @@ absence of a garbage collector says nothing about version resolution. | **module** | A distributable, versioned source tree rooted by one `ww.mod`, declaring one globally stable module identity and containing zero or more packages. | | **project** | The module or standalone package selected by the user's current command, including its declared products. | | **workspace** | A local, non-published set of module-identity-to-directory overlays described by `ww.work`. It changes location, never identity. | -| **dependency** | A typed directed edge: package import, generated-input edge, tool edge, native-provider edge, runtime edge, ordered link edge, or source-input edge. A source-input edge is content-rooted and has no producer action; it is valid in template/final action inputs but never in `GraphEdgeV1`. The edge kind is never implicit. | +| **dependency** | A typed directed edge: package import, generated-input edge, tool edge, native-provider edge, runtime edge, ordered link edge, source-input edge, or bootstrap-record edge. A source-input edge is content-rooted and has no producer action; it is valid in template/final action inputs but never in `GraphEdgeV1`. A bootstrap-record edge selects the producer action-record or action-result record for `bootstrap.compare`. The edge kind is never implicit. | | **target/platform descriptor** | A canonical architecture/platform/ABI/object/CPU/runtime description. An action labels descriptors by role: execution `B`, product `H`, and optional compiler-output `T`. A target triple is only a short lookup name. | | **artifact** | An immutable byte string or canonical directory tree produced by an action and named by a content digest. Materialized files are copies or links, not the artifact's identity. | | **toolchain** | An immutable descriptor and content closure containing the compiler, action protocol, export/ABI versions, target descriptors, resource files, runtime implementations, and pinned assembler/linker/archive tools. | @@ -603,13 +603,13 @@ For every command, `ww` constructs a typed graph in these deterministic phases: 3. Resolve every import by identity, reject collisions/internal violations, and compute the complete acyclic package graph. 4. Add statically declared generated-input, host-tool, native-provider, - toolchain, runtime, archive, and ordered link edges. Match target clauses and - reject zero or multiple providers. All generated output names and consumers - are known here. + toolchain, runtime, archive, ordered link, and bootstrap-record comparison + edges. Match target clauses and reject zero or multiple providers. All + generated output names and consumers are known here. 5. Lower nodes to the complete **action-template DAG** and report it. A template names every edge/input slot, tool, policy, and output, but its final key remains - unresolved until every predecessor output content digest is known. Only after - this point may a cache be read or a tool execute. + unresolved until every predecessor output or selected record content digest + is known. Only after this point may a cache be read or a tool execute. 6. As verified cache results or completed predecessors resolve input artifacts, finalize ready action records/keys, query the cache, schedule misses, publish successful artifacts atomically, then materialize requested products. @@ -1143,11 +1143,13 @@ unknown values rather than passing them to a tool. `ArtifactRefV1` is permitted in declarative configuration records (including toolchain/native records) and action templates, but never in a final action -record. Its tags are: 1 namespace (`source`, `generated`, `package`, `toolchain`, `sysroot`, -`provider-output`, or `cas`); 2 owner identity (empty only for a root source); +record. Its tags are: 1 `ArtifactNamespace` (`source`, `generated`, `package`, +`toolchain`, `sysroot`, `provider-output`, `cas`, or `graph`); 2 owner identity +(empty only for a root source); 3 normalized logical name/path; 4 semantic artifact kind (`file`, `tree`, `object`, `archive`, `shared`, `import-library`, `script`, `crt`, `loader`, -`native-sidecar`, `native-abi`, `export`, or `package-link`); +`native-sidecar`, `native-abi`, `export`, `package-link`, `action-record`, or +`action-result`); 5 optional expected `TypedDigestV1`; and 6 mode (`data` or `executable`). A local source may omit tag 5 because analysis hashes it. A `cas`, external prebuilt, toolchain, or sysroot reference must include it. A generated/package/provider @@ -1160,8 +1162,26 @@ artifact-kind enum; `GenerateDecl.OutputDecl` remains restricted to `file` or `tree`. In schema 1, `file`, `object`, `archive`, `shared`, `import-library`, `script`, `crt`, and `loader` require a blob digest. `tree` requires record kind 1, `native-sidecar` kind 15, `native-abi` kind 16, `export` kind 18, and -`package-link` kind 19, each at record schema 1. Any other digest domain, record -kind, or schema is invalid kind substitution. +`package-link` kind 19, each at record schema 1. Schema-1 artifact-kind values 14 +`action-record` and 15 `action-result` require record kinds 11 and 12, +respectively, at record schema 1. They are input-only and valid only for +`bootstrap.compare`; they are invalid in built-in, template, or final action +outputs and in `ResultOutputV1`. Any other digest domain, record kind, or schema +is invalid kind substitution. + +The `graph` namespace has one exact form. Its consumer is `bootstrap.compare`, +the `TemplateInputV1` edge kind is `bootstrap-record`, and +`ArtifactRefV1.tag2` is the producer logical node. Tag 3 is the Identifier +selector `action_record` for artifact kind `action-record` or `action_result` +for artifact kind `action-result`; tag 5 is absent. `ArtifactRefV1.tag6` and +`TemplateInputV1.tag5` are `data`, `TemplateInputV1.tag4` repeats the +corresponding artifact kind, and `TemplateInputV1.tag6` is empty. No other +consumer, edge kind, selector, kind, expected digest, or mode is valid for this +namespace. These inputs and edges are bijective: each `graph` template input has +exactly one `bootstrap-record` `GraphEdgeV1`, and each such edge has exactly one +`graph` template input. The edge's consumer node is the enclosing template node, +its consumer input slot equals `TemplateInputV1.tag1`, its producer node equals +`ArtifactRefV1.tag2`, and its selector equals `ArtifactRefV1.tag3`. `InputSlotRefV1` has tag 1 slot name and tag 2 expected semantic artifact type. A final action record contains no `ArtifactRefV1`: every artifact-bearing field is recursively lowered @@ -1269,11 +1289,17 @@ one of those slots. Finalization interns every source, direct export, package/native object, archive, shared library, header/sysroot tree, generated output, tool/resource, CRT, loader, script, and init dispatcher into exactly one named template input. -Predecessor result digests resolve those slots lazily. The producer logical node, -producer output path, producer key, and template digest are graph/provenance -facts only and do not enter the consumer's `ActionRecordV1` or `K`. Two producers -that deliver the same typed bytes to the same semantic slot therefore produce -the same downstream record and key. +For `bootstrap.compare`, it also interns every selected raw action record and +action result as a separate named input. Finalization erases the `graph` +namespace, producer node, and unresolved selector form. The corresponding +tag-10 `ResolvedInputV1` retains edge kind `bootstrap-record`, logical selector +`action_record` or `action_result`, matching artifact kind, `data` mode, and the +resolved typed digest; that digest is the sole authority to read the raw record. +Predecessor output and selected-record digests resolve those slots lazily. The +producer logical node, producer output path, producer key, and template digest +are graph/provenance facts only and do not enter the consumer's `ActionRecordV1` +or `K`. Two producers that deliver the same typed bytes to the same semantic +slot therefore produce the same downstream record and key. `ActionResultV1` tags are: 1 schema, 2 the 32-byte action key, 3 typed action-record digest, and 4 sorted `ResultOutputV1` records. `ResultOutputV1` @@ -1291,9 +1317,14 @@ digest. `GraphSnapshotV1` tags are 1 schema, 2 logical root, 3 sorted 4 optional typed action-record digest, and 5 optional typed action-result digest. `GraphEdgeV1` tags are 1 consumer node ID, 2 consumer input slot, 3 producer node ID, 4 producer output name, and 5 edge kind; edges sort by that five-field tuple. -The `source-input` kind is invalid in `GraphEdgeV1`. Non-action source inputs -live only in the consumer template rather than invented graph nodes. The project -index contains only its typed graph-snapshot digest. +Tag 4 is an ordinary producer output name except that a `bootstrap-record` edge +uses selector `action_record` or `action_result`. That branch resolves the +actual producer `GraphNodeV1.tag4` or tag 5, respectively; it never selects an +`ActionOutputV1` or `ResultOutputV1`. If the selected producer tag is absent, +the input remains unresolved and blocks finalization. The `source-input` kind is +invalid in `GraphEdgeV1`. Non-action source inputs live only in the consumer +template rather than invented graph nodes. The project index contains only its +typed graph-snapshot digest. #### Target, toolchain, native, interface, and handoff records @@ -2387,7 +2418,10 @@ Recovery uses these exact stages: and provenance are excluded because stage 2 was built by stage 1 while stage 3 was built by stage 2. Once those compiler bytes converge, it requires stage-3 and stage-4 semantic outputs **and raw action/result records** to be - byte-identical; their producer compiler digests are then equal. + byte-identical; their producer compiler digests are then equal. Each raw + record is a separately named `action-record` or `action-result` input in + action tag 10; comparison metadata or a digest outside tag 10 is not read + authority. Stage 1 need not equal stage 2: portable-C and production backends may generate different code. Stage 2 MUST equal stage 3 semantically, and stage 3 MUST equal