docs: record persistent builder identity

This commit is contained in:
2026-08-12 15:51:55 +09:00
parent badde25fa9
commit c4bdc5dc4f
2 changed files with 71 additions and 22 deletions

View File

@@ -2606,11 +2606,11 @@ commit and are implementation evidence, not requirements for the replacement.
`-L` and `-l` values, losing their original interleaving (C driver, lines `-L` and `-l` values, losing their original interleaving (C driver, lines
10951249 and 13681460). 10951249 and 13681460).
- `-w DIR` is a caller-owned mutable reuse directory, not a cache. Freshness is - `-w DIR` is a caller-owned mutable reuse directory, not a cache. Freshness is
exact composed-unit bytes, copied compiler/assembler bytes, a text mode stamp, exact composed-unit bytes, copied driver/compiler/assembler bytes, a text mode
and artifact existence/nonzero size. The graph and units are rebuilt in stamp, and artifact existence/nonzero size. The graph and units are rebuilt
memory and the final executable is relinked on every invocation. Publication in memory and the final executable is relinked on every invocation.
through `.new` files with the unit committed last is usefully atomic (C driver, Publication through `.new` files with the unit committed last is usefully
lines 867952, 10161059, and 11101213). atomic (C driver, lines 867952, 10161059, and 11101213).
- Without `-w`, a build creates and deliberately retains - Without `-w`, a build creates and deliberately retains
`<output-stem>.sepwork`; repeating while it exists fails. With `-w`, the caller `<output-stem>.sepwork`; repeating while it exists fails. With `-w`, the caller
must create and serialize the directory. Normal driver products are always must create and serialize the directory. Normal driver products are always
@@ -2696,10 +2696,11 @@ flags, compiler built-ins, assembler/linker defaults,
inferred `argv[0]` library locations, current working directory, file mode, runtime inferred `argv[0]` library locations, current working directory, file mode, runtime
archive, linker binary, native-library resolution, host libc/CRT/loader, SDK, archive, linker binary, native-library resolution, host libc/CRT/loader, SDK,
CPU, target, and environment. Make does not invalidate existing C objects when CPU, target, and environment. Make does not invalidate existing C objects when
the host compiler or C flags change. Workdir reuse also omits the driver binary/ the host compiler or C flags change. Persistent package workdirs now bind the
graph and archive semantics, relying on a manually bumped text format stamp; a exact driver executable, conservatively covering its graph, unit, archive, and
driver change can therefore reuse stale outputs. WW has no target triple, sysroot, conditional commit semantics; the remaining ambient inputs are not thereby promoted into a
source, generator, manifest, lock, source digest, or frozen/offline concept. cache protocol. WW has no target triple, sysroot, conditional source, generator,
manifest, lock, source digest, or frozen/offline concept.
### 11.4 Measurements and disposable experiments ### 11.4 Measurements and disposable experiments
@@ -2965,7 +2966,7 @@ declares helpers and contains no `@test`, so its package clause and imports are
still checked by the shared loader. Every built variant is run, and a successful still checked by the shared loader. Every built variant is run, and a successful
compiler-owned dispatcher with empty output is reported as `[no tests]`. compiler-owned dispatcher with empty output is reported as `[no tests]`.
Persistent workdirs keep a global compiler/assembler/stamp identity and Persistent workdirs keep a global driver/compiler/assembler/stamp identity and
per-action committed units. When that global identity is stale, the command per-action committed units. When that global identity is stale, the command
first removes every old `.unit.ww` voucher while leaving artifacts recoverable. first removes every old `.unit.ww` voucher while leaving artifacts recoverable.
It can then commit the new identity even if one root fails: successful actions It can then commit the new identity even if one root fails: successful actions
@@ -3076,6 +3077,52 @@ tests remain real package variants in
and direct compile dependencies are expanded separately for linking in and direct compile dependencies are expanded separately for linking in
[`cmd/go/internal/work/action.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#628). [`cmd/go/internal/work/action.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go#628).
### 11.10 Implemented persistent-workdir driver identity slice
The package driver is now an explicit content input to every persistent
`-w DIR` package action. Both stages copy the exact invoking executable to
`.wwtool.ww`, alongside `.wwtool.w6c`, `.wwtool.w6a`, and the mode/format
stamp. A warm invocation byte-compares all applicable live executables before
considering any committed unit reusable. A missing or changed driver copy
invalidates every `.unit.ww` voucher before compilation; old artifacts may
remain recoverable, but none can be reused without a freshly committed unit.
The workdir format revisions are 5 for ordinary builds and 6 for tests.
This closes a real hidden-input boundary. The driver, rather than `w6c`, owns
canonical directory interning, source-derived graph construction, direct-export
unit composition, deterministic dependency ordering, single-member package
archive serialization, and the artifact commit sequence. Unit equality alone
cannot identify changes to those algorithms, and a manually maintained format
number can be forgotten. Exact driver bytes conservatively cover them during
the transitional plain-file reuse scheme. This may rebuild after an unrelated
driver change, but it cannot falsely reuse a package after a relevant one.
The linker remains outside the recorded package identity because persistent
reuse never skips a final link: each invocation reconstructs the complete
reachable `.a` closure, selects current runtime inputs and link flags, and runs
the selected linker. Thus a linker or runtime change affects the requested
binary immediately without forcing unrelated package compilation.
Repository-native coverage runs a three-directory import graph through copied,
independently mutable Cstage and WWstage drivers. Exact compiler, assembler,
and linker wrappers prove a cold dependency-first build, an unchanged warm
compile/assemble skip with a deliberate relink, and full package invalidation
after only the invoking driver's bytes change. The test inspects direct
`.unit.ww` inputs, `.wwi`, `.a`, identity files, exact tool arguments,
transitive link order, diagnostics before tool execution, published binary
bytes, runtime exit, and stage equivalence.
Go 1.26.5 draws the same semantic line with a richer cache: its build action ID
binds compiler/assembler tool identities, configuration, selected source
content, and direct dependency content IDs in
[`cmd/go/internal/work/exec.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#261),
while its link action ID separately binds linker configuration and the package
closure in
[`cmd/go/internal/work/exec.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go#1504).
WW adopts only the correctness boundary in its existing inspectable `cmp`-based
workdir. It does not add build IDs, hashes, a CAS, an action graph, a scheduler,
or a manifest.
## 12. Candidate architectures and hard-gate decision ## 12. Candidate architectures and hard-gate decision
Five candidates were developed as coherent systems, not as feature bins. Five candidates were developed as coherent systems, not as feature bins.

View File

@@ -236,18 +236,20 @@ tools in invocation-owned directories and apply the same exact cleanup rule.
`ww build -w DIR` and single-file `ww test -w DIR` replace that scratch with a `ww build -w DIR` and single-file `ww test -w DIR` replace that scratch with a
caller-owned persistent package-artifact workdir: the directory must already caller-owned persistent package-artifact workdir: the directory must already
exist, is never cleaned by the driver, and holds one committed unit, `.wwi`, exist, is never cleaned by the driver, and holds one committed unit, `.wwi`,
`.s`, `.o`, and dep `.a` per package plus byte copies of the compiler and `.s`, `.o`, and dep `.a` per package plus byte copies of the invoking driver,
assembler and a small mode stamp. A package is reused only when its freshly compiler, and assembler and a small mode stamp. A package is reused only when
composed unit byte-equals the committed unit and the recorded tool copies its freshly composed unit byte-equals the committed unit and every applicable
byte-equal the live tools — content identity only, no mtimes, no hashes, every recorded executable byte-equals the live executable — content identity only,
decision reproducible with `cmp` against plain files. Recompiled artifacts no mtimes, no hashes, every decision reproducible with `cmp` against plain
land at staged `.new` names and commit by rename with the unit renamed last, files. The driver identity covers the graph, unit-composition, archive, and
so an interrupted build forces a recompile rather than a false reuse; the commit algorithms that neither unit bytes nor compiler identity can name.
link always reruns. One workdir serves one invocation at a time and one Recompiled artifacts land at staged `.new` names and commit by rename with the
(root, mode) shape; both driver stages implement the identical contract. unit renamed last, so an interrupted build forces a recompile rather than a
This is build staleness in the Make/mk/Go sense, not a result cache: tests false reuse; the link always reruns. One workdir serves one invocation at a
always run, and the byte-identity and bootstrap gates keep building on fresh time and one (root, mode) shape; both driver stages implement the identical
scratch. `make clean` reclaims every workdir under `out/`. contract. This is build staleness in the Make/mk/Go sense, not a result cache:
tests always run, and the byte-identity and bootstrap gates keep building on
fresh scratch. `make clean` reclaims every workdir under `out/`.
On a package or tree target, `ww test -w DIR` forwards to the coordinator, On a package or tree target, `ww test -w DIR` forwards to the coordinator,
which keys one persistent driver workdir per package group under `DIR` which keys one persistent driver workdir per package group under `DIR`