test: prove long package identity semantics

This commit is contained in:
2026-08-13 05:38:05 +09:00
parent c3df0afeb0
commit 5705c0e3fa
4 changed files with 692 additions and 130 deletions

View File

@@ -3445,6 +3445,182 @@ The pinned official Go 1.26.5 tag (commit
WW adopts those practical ownership and action semantics while retaining its
small direct CLI representation and existing self-contained `.wwi` encoding.
### 11.13 Implemented unbounded semantic package-identity storage slice
Canonical package identity is no longer stored in, derived from, or bounded by
one internal filesystem component. In both drivers every package action now
keeps these values separately:
- `path`: the complete compiler/import identity;
- `import_base`: the complete canonical ordinary directory identity;
- `canon`: the complete canonical directory location;
- `variant` and `role`: the semantic test/action tags; and
- `storage`: an internal scratch basename that is never passed as package
identity.
The first four values, not `storage`, participate in directory-action
interning, source-import edges, module-reset ownership, compiler `--import`
arguments, export ownership, diagnostics, generated-main construction, and
symbol qualification. The reversible outside-root form remains
`__wwlocal.p<escaped-canonical-absolute-directory>.<declared-leaf>` and is
allocated to its exact length. It is neither truncated nor replaced by a
digest, and `__wwlocal` remains unavailable to source imports. Package
declarations continue to validate the selected package kind and leaf; they do
not supply a missing identity and do not alter a command package's canonical
path.
Short actions retain their established `.unit.ww`, `.wwi`, `.s`, `.o`, and
`.a` basenames when the basename plus `.unit.new` fits the 255-byte supported
filesystem component bound and the complete path fits the host pathname API.
An action that does not fit uses this bounded storage locator:
```text
__wwpkg.v<variant>.r<role>.h<lowercase-sha256>
```
The SHA-256 byte input is exactly:
```text
"ww-package-storage-v2:"
|| ASCII(<variant> ":" <role> ":")
|| complete semantic path
|| NUL
|| complete canonical directory
```
WW package paths and host paths cannot contain NUL, so that boundary is
unambiguous. Variant and role are present in both the digest input and the
visible locator tag. The digest is only an action-storage address: units still
begin with `//ww:module-reset <complete-path>`, exports begin with
`//ww:module <complete-path>`, compiler imports carry the complete path, and
qualified declarations use it in generated symbols. A selected executable
entry retains its intentional bare linker spelling. User-selected `-o`
publication paths bypass this derivation completely.
Storage assignment is command-global and finishes before any tool is invoked.
If two actions prefer the same legacy basename, every unhashed member is
readdressed through the complete-action formula instead of rejecting a valid
package graph. If two already-addressed, unequal complete actions ever produce
the same locator, both drivers issue the same full-identity storage-collision
diagnostic before compilation. A persistent workdir also validates every
existing regular `.unit.ww` voucher against the requested complete semantic
owner before stale-tool invalidation or reuse; a missing voucher is cold state,
while a malformed, non-regular, or wrong-owner voucher is a pre-tool error.
Thus ordinary preferred-name collisions are resolved, and a digest collision
cannot silently alias two live or warm package actions. The workdir format is
now build version 10 and test version 11 so an older flat-layout voucher is
never accepted as current state.
The persisted semantic owner is deliberately the complete canonical import
path, not the canonical host directory: host location must not enter compiler
artifacts. Variant and role are encoded in the locator itself. Canonical
directory remains part of command-local action interning and the digest input,
so distinct locations normally receive distinct slots. In the hypothetical
case that two locations with the same import path, variant, and role also
collide in SHA-256, they are still one semantic package identity: the freshly
composed owner unit must byte-equal the committed unit before reuse, so
different sources rebuild and identical sources produce the same deterministic
artifacts. A digest collision between different semantic paths fails the
existing complete-path owner check before tools. This preserves collision
checking without serializing machine-specific canonical directories into units
or exports and without a sidecar, registry, or new metadata protocol.
The package coordinator similarly preserves the reversible existing
`d_<escaped-canonical-request-directory>` component while it fits. A longer
canonical request directory uses:
```text
d_<lowercase-sha256("ww-request-workdir-v1:" || canonical-directory)>
```
This key selects only the driver workdir container; it is never a package
identity or action address. Equivalent logical, relative, absolute, `.` and
explicit root-symlink requests canonicalize before this derivation. Inside the
container the driver independently derives every action locator from its full
semantic tuple and validates the committed semantic owner, so even a
coordinator-key collision cannot silently reuse an unrelated package action or
invoke a tool with a shortened identity. Explicit root symlinks are followed
and canonicalized; source-file symlinks and symlinked recursive children retain
their existing rejection/skipping rules.
The old `SEP_IMPORT_PATH_MAX` and all corresponding 255-byte WWstage import,
variant, local-identity, and generated-main checks are removed. Package names,
canonical identities, reverse-resolved dotted identities, generated-main
identities, compiler import paths, and Cstage assembler symbols now use exact
allocations. Cstage's assembler no longer copies a line, operand, `TEXT`, or
`DATA` symbol through 256-byte arrays, and the C checker no longer resolves a
qualified type through a 128-byte prefix buffer. `PATH_MAX` remains only at
actual host pathname and syscall boundaries; the 255-byte constant remains
only as the conservative internal basename component bound. `SEP_MAXPKG`,
`SEP_MAXPRODUCT`, and `SEP_MAXCONTEXT` remain action-count limits, not byte
limits on semantic identity.
The existing native observers exercise the new boundary with ordinary dotted
identities over 255 bytes and punctuation-heavy reversible local identities
over 255 bytes. They inspect the complete owner in units and exports, exact
direct sorted/deduplicated `.wwi` compiler inputs, long mangled assembler
symbols, complete archive-only link closures, runtime results, and independent
Cstage/WWstage artifact bytes. Two deep outside-root directories declaring
the same leaf coexist under distinct reversible identities. A long command
package and its production, internal, external, and two generated-main actions
remain distinct. Logical and literal roots, dependency-first and root-first
discovery, equivalent and symlink spellings, reordered products, and warm
requests reuse the same production action and persistent slot. The persistent
diamond observer also changes a shared dependency export, proves rebuilding of
its direct importers, and proves propagation stops when the regenerated export
is byte-identical.
This separation follows the pinned official Go 1.26.5 tag at commit
`c19862e5f8415b4f24b189d065ed739517c548ba`, without adopting Go's cache,
build IDs, importcfg, module machinery, or scheduler:
- Source imports are expanded to canonical paths before being recorded
([`pkg.go`, lines 658669](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L658-L669),
[`pkg.go`, lines 11501178](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L1150-L1178)).
Local directories receive a deterministic pseudo-import identity derived
from the full directory while directory and import path stay separate
([`pkg.go`, lines 633647](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L633-L647),
[`pkg.go`, lines 863907](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L863-L907)).
Resolution/package caches retain and reuse those complete values
([`pkg.go`, lines 833842](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L833-L842),
[`pkg.go`, lines 909985](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L909-L985),
[`pkg.go`, lines 10081029](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L1008-L1029)).
- `go/build` reverse-resolves directory ownership through ordered roots and
performs the matching forward lookup while keeping directory, import path,
declared name, and source lists separate
([`build.go`, lines 612665](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L612-L665),
[`build.go`, lines 725767](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L725-L767),
[`build.go`, lines 436493](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L436-L493)).
- Go interns an action by operation and package pointer, returns an existing
action for repeated compilation requests, and attaches only direct package
dependencies
([`action.go`, lines 202206](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L202-L206),
[`action.go`, lines 437447](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L437-L447),
[`action.go`, lines 628658](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L628-L658)).
- Its `Action` keeps `Package`, `Objdir`, and `Target` as independent fields,
then assigns a short `bNNN/` object directory unrelated to import identity
([`action.go`, lines 84109](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L84-L109),
[`action.go`, lines 383394](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L383-L394)).
Direct dependency identities map independently to archive paths, and the
owner is compiled to fixed `_pkg_.a`
([`exec.go`, lines 864884](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L864-L884),
[`exec.go`, lines 928935](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L928-L935),
[`exec.go`, lines 10171033](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L1017-L1033)).
- Linking reuses the compiled root action and separately expands the complete
reachable archive closure
([`action.go`, lines 919957](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L919-L957),
[`action.go`, lines 10341068](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L1034-L1068),
[`exec.go`, lines 15921624](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L1592-L1624),
[`exec.go`, lines 16351647](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L1635-L1647)).
User `-o` separately controls the publication target
([`build.go`, lines 508548](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L508-L548)).
- Go's test loader models ordinary production, internal production-plus-test,
external `_test`, and generated-main packages separately, reusing ordinary
production when possible
([`test.go`, lines 85102](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L85-L102),
[`test.go`, lines 175226](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L175-L226),
[`test.go`, lines 228293](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L228-L293)).
## 12. Candidate architectures and hard-gate decision
Five candidates were developed as coherent systems, not as feature bins.