driver: implement post-target run argv semantics

This commit is contained in:
2026-08-23 17:33:31 +09:00
parent 0b24b11d65
commit 29122f2a48
6 changed files with 579 additions and 17 deletions

View File

@@ -479,6 +479,82 @@ supervision is unchanged: the known orphan compiler, fixed `.new` staging, and
later persistent-request poisoning remain open and are not credited to this
slice.
The run front has one separate post-target argument contract. The sole
authority is official Go 1.26.5 at commit
`c19862e5f8415b4f24b189d065ed739517c548ba`:
- **behavior directly implemented or asserted by pinned Go** — command flag
parsing supplies only its positional suffix to `runRun`
(`cmd/go/main.go:312322`; `flag/flag.go:10741089,11491176`), and
`runRun` consumes the named-file prefix or one package before attaching the
untouched suffix to the run action
(`cmd/go/internal/run/run.go:96140,170173`).
- **behavior directly implemented or asserted by pinned Go** — official
`cmd/go/testdata/script/mod_run_flags_issue64738.txt:14` proves that
target-following `-p ignored` is program input rather than a Go-command
option. `cmd/go/testdata/script/run_dirs.txt:120` anchors the independent
contiguous named-file prefix, which WW does not claim here.
- **behavior derived from the pinned implementation** — after WW's one
explicit local run target, every remaining operand is runtime argv. The
rule honestly applies without importing Go modules or manifests. WW's
default-dot extension has no explicit target boundary, and leading or
pre-target `--` remains its existing unknown flag rather than gaining
general Go flag-terminator semantics.
Before the repair, **directly measured WW behavior** was stage-equal but
different: both drivers rejected immediately target-following `-p ignored` and
`-- -p ignored` at status 2 with empty stdout and exact unknown-flag stderr,
consumed target-following `-o` and `-I` values as driver configuration, and
passed the ordered suffix only after a second nonflag. Accepted controls loaded
one target and its ordinary import closure and completed the private compiler,
assembler, archiver, linker, and runtime route; rejected rows stopped before
loading, actions, tools, runtime, or scratch.
The focused `run_post_target_arguments_are_program_argv` observer owns the
completed boundary in `test/package/package_test.ww`. Across Cstage and WWstage
it uses both a literal named source and a directory package and requires exact
ordered delivery for separate and joined known-option spellings, unknown
options, would-be values, a singleton value-taking spelling, `--`, later
nonflags and `.ww`, and an empty string. It separately requires pre-target
options and their missing/unknown diagnostics to remain driver-owned, leading
`--` to keep its current rejection, no-operand run to keep default-dot
selection, and target load/producer diagnostics to precede inert suffix bytes.
Valid programs expose the private executable at `os.args()[0]`, receive the
exact suffix at indices 1 onward, and retain WW's existing stdout, stderr, and
exact child-status mapping. Pinned Go's distinct command-level nonzero status
mapping (`cmd/go/internal/run/run.go:56,198210` and
`cmd/go/internal/base/base.go:218246`) remains an open difference.
The observer also treats all four permanent axes as one contract. The build/run
axis changes only the parser-to-child boundary. Build and test controls retain
their status, streams, action inputs, and comparable artifact bytes. Package
membership and command classification still come only from the selected
target, while dotted-import resolution, edges, interfaces, visibility, and
initialization still come only from that target's closure. Direct actions
remain `__root.*`; dotted directories retain dotted identity; argv creates no
package, import, graph, action, symbol, artifact, `.wwi`, publication,
persistence, reuse, or invalidation identity.
Post-target bytes therefore cannot change compiler, assembler, archiver,
linker, initializer, or private executable bytes. Run publishes no public
product or semantic state. Normal success, target/producer failure, runtime
nonzero, and overlapping requests must keep suffixes isolated and remove each
owned private executable, `.sepwork`, stage, transaction, capture, result,
request, descriptor, and child. Cstage and WWstage must agree on stable status,
stdout, stderr, diagnostic order, runtime argv, cleanup, and comparable
artifact bytes. No AST, interface, descriptor, request, transaction, or
persistent schema changes; build workdir format remains 18, test workdir format
remains 19, semantic storage format remains 3, and no test-result cache is
introduced.
The observer makes no claim for regular or missing `_test.ww`, missing `.ww`,
hidden named sources, multiple leading source operands and source-set
boundaries, literal nonregular named sources, shared test-package state,
panic/exit/Fatal/FailNow topology, Go-compatible RE2 `-run`, three-way
no-buildable-source causes, or Go-like run exit-status mapping. External-driver
SIGTERM supervision is also unchanged: the verified orphan compiler, three
fixed `.new` stages, and later persistent-request poisoning remain open.
An existing local directory whose requested build basename ends `.ww`
(including a visible `_test.ww` symlink to a directory) remains a directory
package, not a raw named test source. WWstage `ww build` now uses the same