test: prove long package identity semantics
This commit is contained in:
@@ -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 658–669](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L658-L669),
|
||||
[`pkg.go`, lines 1150–1178](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 633–647](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L633-L647),
|
||||
[`pkg.go`, lines 863–907](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 833–842](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L833-L842),
|
||||
[`pkg.go`, lines 909–985](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/pkg.go#L909-L985),
|
||||
[`pkg.go`, lines 1008–1029](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 612–665](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L612-L665),
|
||||
[`build.go`, lines 725–767](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L725-L767),
|
||||
[`build.go`, lines 436–493](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 202–206](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L202-L206),
|
||||
[`action.go`, lines 437–447](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L437-L447),
|
||||
[`action.go`, lines 628–658](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 84–109](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L84-L109),
|
||||
[`action.go`, lines 383–394](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 864–884](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L864-L884),
|
||||
[`exec.go`, lines 928–935](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L928-L935),
|
||||
[`exec.go`, lines 1017–1033](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 919–957](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L919-L957),
|
||||
[`action.go`, lines 1034–1068](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L1034-L1068),
|
||||
[`exec.go`, lines 1592–1624](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L1592-L1624),
|
||||
[`exec.go`, lines 1635–1647](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 508–548](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 85–102](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L85-L102),
|
||||
[`test.go`, lines 175–226](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L175-L226),
|
||||
[`test.go`, lines 228–293](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.
|
||||
|
||||
Reference in New Issue
Block a user