run: reject .ww directories as named sources
This commit is contained in:
@@ -10376,6 +10376,141 @@ test/run command boundaries. No serialized representation changes: build
|
||||
workdir format remains `18`, test workdir format remains `19`, semantic storage
|
||||
format remains `3`, and no cache or result record is added.
|
||||
|
||||
### 11.53 Implemented `.ww`-spelled directory run rejection
|
||||
|
||||
An existing target selected by `ww run` whose exact requested spelling ends
|
||||
`.ww` is a named-source request when ordinary symlink-following `stat` reports
|
||||
a directory. Run rejects that directory before package resolution or private
|
||||
work creation. This is deliberately different from section 11.52's build/test
|
||||
directory route: the command-specific front door, not the shared resolver,
|
||||
owns the distinction.
|
||||
|
||||
#### Pinned authority and applicability
|
||||
|
||||
- **behavior directly implemented or asserted by pinned Go** — official Go
|
||||
1.26.5 commit `c19862e5f8415b4f24b189d065ed739517c548ba`
|
||||
scans leading `.go` operands at
|
||||
`cmd/go/internal/run/run.go:73–112`, rejecting an `_test.go` spelling at
|
||||
103–109 before passing the named set to `GoFilesPackage`.
|
||||
`cmd/go/internal/load/pkg.go:3244–3289`, especially 3274–3281, follows
|
||||
`Stat` and fatals when a named operand is a directory. Later checking,
|
||||
action construction, linking, and execution at `run.go:141–173` are not
|
||||
reached.
|
||||
- **behavior directly implemented or asserted by pinned Go** — the exact Go
|
||||
status, header-free diagnostic, and terminating newline follow
|
||||
`cmd/go/internal/base/base.go:137–145,175–183`,
|
||||
`cmd/go/main.go:98–100`, and `log/log.go:200–245`. Official
|
||||
`cmd/go/testdata/script/run_hello.txt:1–10`, `run_dirs.txt:1–20`, and
|
||||
`run_set_executable_name.txt:4–17` anchor the named-file run front and its
|
||||
distinction from package-form run. Indirect official directory-kind anchors
|
||||
are `list_ambiguous_path.txt:4–15,29–36`,
|
||||
`mod_get_go_file.txt:47–58`, and `mod_symlink_dotgo.txt:4–9`. No official
|
||||
end-to-end `go run` test asserts this directory diagnostic; the result is
|
||||
implemented directly by the cited source.
|
||||
- **behavior derived from the pinned implementation** — WW's `.ww`
|
||||
named-source spelling and existing directory-package form meet at the same
|
||||
practical boundary. The applicable adaptation uses `WW file` and
|
||||
`*_test.ww` while preserving requested operand bytes. It requires no module,
|
||||
manifest, registry, network lookup, generalized import grammar, cache,
|
||||
database, CAS, or build expression.
|
||||
|
||||
#### Ownership, selection, and diagnostics
|
||||
|
||||
- **directly measured WW behavior** — before this change, Cstage followed a
|
||||
direct `.ww` directory or visible `.ww`/`_test.ww` symlink into the ordinary
|
||||
directory graph, invoked compiler, assemblers, linker, and user program, and
|
||||
returned that program's status. WWstage instead entered raw-source loading,
|
||||
returned status 1 with exact `ww: cannot read source\n`, and ran no producer
|
||||
or program. Both removed the private work they had unnecessarily created.
|
||||
- **behavior derived from the pinned implementation** — the true WW owners
|
||||
are only `cmd/ww/main.c::do_run` and
|
||||
`selfhost/cmd/ww/main.ww::dorun`, after their existing option/target parse
|
||||
and requested `stat`, but before `resolve_module`/`resolvemodule` and run
|
||||
scratch creation. Changing the shared resolver would wrongly change the
|
||||
distinct build, test, logical, and dotted-package fronts.
|
||||
- **directly measured WW behavior** — after the run-local classification,
|
||||
both stages return status 1 with empty stdout. A requested spelling ending
|
||||
`_test.ww` emits exactly
|
||||
`ww: cannot run *_test.ww files (OPERAND)\n`; every other selected directory
|
||||
ending `.ww` emits exactly
|
||||
`OPERAND is a directory, should be a WW file\n`. The requested operand is
|
||||
reproduced unchanged. `_test.ww` precedence applies before ordinary
|
||||
directory rejection, including through a symlink.
|
||||
- **directly measured WW behavior** — the rule includes direct and symlinked
|
||||
`.ww` directories and hidden directory spellings `.hidden.ww` and
|
||||
`_hidden.ww`. It also precedes malformed package clauses and missing imports
|
||||
inside the directory because no member is selected or opened. Existing run
|
||||
option errors and target determination retain their earlier precedence.
|
||||
A trailing separator does not end `.ww`; non-`.ww` directories and dotted
|
||||
logical requests retain the established package route.
|
||||
|
||||
#### Build, test, package, and import effects
|
||||
|
||||
- **directly measured WW behavior** — package/source selection is the primary
|
||||
axis. The rejected request creates no raw or directory package, canonical
|
||||
identity, declared-name instance, test variant, initializer, graph node, or
|
||||
action. Requested spelling and followed target are diagnostic observations
|
||||
only, never canonical package, action, symbol, artifact, `.wwi`,
|
||||
publication, or persistence identity.
|
||||
- **directly measured WW behavior** — build retains section 11.52's stat-first
|
||||
rule for the same direct and symlink spellings. It still enumerates the
|
||||
directory, discovers its dotted dependencies, constructs ordinary package
|
||||
actions, and applies the established default, explicit, directory,
|
||||
`/dev/null`, `-S`, publication, persistence, invalidation, and rollback
|
||||
policies. Unaffected build controls retain stage-byte-identical public and
|
||||
semantic artifacts.
|
||||
- **directly measured WW behavior** — raw `ww test`, `ww test -c`, and
|
||||
directory `ww test -S` retain their stat-first directory selection and
|
||||
established diagnostics/artifact bytes. Test package variants, generated
|
||||
main, process topology, filtering, capture, result ordering, retention, and
|
||||
result non-caching are unchanged.
|
||||
- **directly measured WW behavior** — imports are not scanned on the selected
|
||||
run rejection and create no qualifier or edge. Dotted and non-`.ww` package
|
||||
controls retain exact canonical import identity, dependency discovery, and
|
||||
runtime behavior. No physical directory becomes canonical identity through
|
||||
this rule.
|
||||
|
||||
#### Actions, lifecycle, parity, and scope
|
||||
|
||||
- **directly measured WW behavior** — selected rejection invokes no compiler,
|
||||
assembler, archiver, linker, initializer, runtime, or owned child/process
|
||||
group. A fixture-preoccupied exact `/tmp/ww_run_<pid>` plus sentinel remains
|
||||
untouched, proving that the driver does not acquire or mutate its run-scratch
|
||||
path; final cleanup leaves that path absent. It also creates no output,
|
||||
`.sepwork`, unit, `.wwi`, assembly, object, archive, executable, capture,
|
||||
result, transaction, stage, backup, or persistent record. Thus
|
||||
producer/runtime failure, publication, reuse, invalidation, and rollback are
|
||||
inapplicable on this preflight route; all prior caller and committed bytes
|
||||
remain untouched.
|
||||
- **directly measured WW behavior** — classification is request-local,
|
||||
read-only, and isolated under concurrency. An interruption in this preflight
|
||||
owns no child or filesystem resource. The general direct-driver interruption
|
||||
gap from section 11.52 remains open: a different request interrupted after
|
||||
transaction staging can still leave fixed-name `.new` files and poison
|
||||
later persistent reuse. This slice neither reaches nor fixes that machinery.
|
||||
- **directly measured WW behavior** — Cstage and WWstage match exactly on
|
||||
status, stdout, stderr, diagnostic bytes, empty producer traces, artifact
|
||||
absence, exact PID-path non-acquisition and final absence, concurrent
|
||||
isolation, and cleanup for every selected row. Unaffected controls retain
|
||||
diagnostic and public or semantic artifact-byte parity.
|
||||
- **behavior derived from the pinned implementation** — this narrow
|
||||
file-kind slice does not implement the complete suffix-first run front.
|
||||
Regular or missing `_test.ww`, missing or logical `.ww`, multiple named
|
||||
sources, finite FIFOs, and hidden regular sources retain their prior routes
|
||||
and remain separately open where different. Recursive requests, ordinary
|
||||
directory requests, and generalized imports are not changed.
|
||||
|
||||
The focused WW-native observer covers direct, symlinked, hidden, ordinary, and
|
||||
`_test.ww` directory spellings; malformed-package and missing-import
|
||||
precedence; exact requested diagnostics; empty tool/runtime traces; exact
|
||||
PID-path non-acquisition and final absence; concurrency and cleanup;
|
||||
trailing-separator,
|
||||
non-`.ww`, regular-source, and dotted logical run controls; and unchanged
|
||||
same-spelling build and raw/compile-only/assembly-only test boundaries. No
|
||||
serialized representation changes: build workdir format remains `18`, test
|
||||
workdir format remains `19`, semantic storage format remains `3`, and no cache
|
||||
or result record is added.
|
||||
|
||||
## 12. Candidate architectures and hard-gate decision
|
||||
|
||||
Five candidates were developed as coherent systems, not as feature bins.
|
||||
|
||||
29
docs/spec.md
29
docs/spec.md
@@ -370,10 +370,31 @@ ImportPath = ident { "." ident } .
|
||||
no new package, dotted-import, graph, action, symbol, artifact, `.wwi`,
|
||||
publication, or persistence identity. Raw `ww test`, `ww test -c`, and
|
||||
`ww test -S` already use the same directory classification and are unchanged.
|
||||
`ww run` retains its separate named-operand front door. Multiple operands,
|
||||
recursive and logical requests, regular and non-regular source targets, and
|
||||
dangling symlinks are not changed. Build workdir format remains 18, test
|
||||
workdir format remains 19, and semantic storage format remains 3.
|
||||
`ww run` retains its separate named-operand front door, with its
|
||||
`.ww`-spelled directory rule specified next. Multiple operands, recursive
|
||||
and logical requests, regular and non-regular source targets, and dangling
|
||||
symlinks are not changed. Build workdir format remains 18, test workdir
|
||||
format remains 19, and semantic storage format remains 3.
|
||||
- For `ww run`, an existing selected target whose exact requested spelling
|
||||
ends `.ww` is a named-source request when symlink-following `stat` reports a
|
||||
directory. The command rejects it before shared resolution, directory
|
||||
enumeration, source/import loading, graph/action construction, private run
|
||||
scratch, producers, or runtime. A requested suffix `_test.ww` has the earlier
|
||||
exact diagnostic
|
||||
`ww: cannot run *_test.ww files (OPERAND)\n`; every other such directory has
|
||||
exact diagnostic `OPERAND is a directory, should be a WW file\n`. Both forms
|
||||
return status 1 with empty stdout and reproduce the requested operand bytes
|
||||
unchanged. The rule follows a terminal symlink, includes `.hidden.ww` and
|
||||
`_hidden.ww` directory spellings, and precedes any malformed package or
|
||||
missing import inside the directory. A trailing separator does not end
|
||||
`.ww`; ordinary non-`.ww` directories, dotted logical requests, regular and
|
||||
missing operands, multiple named operands, and non-directory non-regular
|
||||
targets retain their established routes. The rejected spelling and followed
|
||||
target are diagnostic metadata only and create no package/import identity,
|
||||
graph/action, symbol, artifact, `.wwi`, publication, transaction,
|
||||
persistence, process, or filesystem owner. Build and all test forms retain
|
||||
their distinct stat-first directory behavior. Build workdir format remains
|
||||
18, test workdir format remains 19, and semantic storage format remains 3.
|
||||
- `import acme.codec;` loads the canonical package `acme.codec`. If that
|
||||
package declares `package wire;`, the importing file sees its exported names
|
||||
as `wire.Name`; `codec.Name` is not an additional binding. An explicit alias
|
||||
|
||||
@@ -278,12 +278,29 @@ parity, direct and symlinked `.ww` directories, a dotted dependency, output
|
||||
modes, cold/warm transaction behavior, compiler and signaled-linker failure
|
||||
preservation, selected-route concurrency, cleanup, and the exact test-command
|
||||
behavior. Direct driver interruption remains owned by the unchanged directory
|
||||
machinery and is not claimed fixed here. The shared resolver and `ww run` are
|
||||
deliberately unchanged—and the observer
|
||||
retains their pre-existing stage difference—because pinned Go's run command
|
||||
has a distinct named-file front door.
|
||||
No test product, result, package/import identity, or serialized format changes;
|
||||
build remains 18, test remains 19, and semantic storage remains 3.
|
||||
machinery and is not claimed fixed here.
|
||||
|
||||
Pinned Go's run command has a distinct suffix-first named-file front door.
|
||||
Accordingly, an existing `ww run` target whose exact requested spelling ends
|
||||
`.ww` and whose symlink-following `stat` result is a directory is rejected in
|
||||
the twin run fronts before the shared resolver and private run scratch. An
|
||||
`_test.ww` spelling emits exactly
|
||||
`ww: cannot run *_test.ww files (OPERAND)\n`; every other selected `.ww`
|
||||
directory emits exactly `OPERAND is a directory, should be a WW file\n`.
|
||||
Both stages return status 1 with empty stdout, open no directory member, scan
|
||||
no import, construct no package/graph/action, invoke no producer or runtime,
|
||||
and create no run scratch or artifact. This includes direct and symlinked
|
||||
directories and hidden directory spellings; directory contents cannot displace
|
||||
the classifier diagnostic. A trailing separator and non-`.ww` or dotted
|
||||
package requests retain the directory package route. The same-spelling build,
|
||||
raw test, `test -c`, and directory `test -S` routes remain stat-first and keep
|
||||
their existing diagnostics and artifact bytes. Thus this run change creates no
|
||||
test product, result, package/import identity, test-process/filter change, or
|
||||
serialized-format change; build remains 18, test remains 19, and semantic
|
||||
storage remains 3. Regular or missing `_test.ww`, missing/logical `.ww`,
|
||||
multiple named sources, finite FIFOs, and hidden regular sources are not
|
||||
claimed by this existing-directory slice. The general direct-driver `.new`
|
||||
interruption residue also remains open.
|
||||
|
||||
List mode uses that same product process and initialization boundary but starts
|
||||
no per-test child. The shared language harness emits only selected qualified
|
||||
|
||||
Reference in New Issue
Block a user