Skip to content

A transport argv identifier is never name-resolved: zero diagnostics, silently wrong argv - #8916

Merged
briansrls merged 17 commits into
mainfrom
transport-argv-unresolved-row
Aug 23, 2026
Merged

briansrls merged 17 commits into
mainfrom
transport-argv-unresolved-row

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 22, 2026 •

Copy link
Copy Markdown
Contributor

Audit-queue row 29 in the compiler-guarantee gap analysis (filed as 24; renumbered twice: main landed items 24-27 concurrently, then #8907 claimed 28 first), for a compiler fail-open measured today by still-seal-394 while dissolving the env/chmod binary-path nicknames.

The finding

An identifier inside a transport shell { argv: [...] } position is never name-resolved at compile time. A symbol declared nowhere in the corpus produces zero diagnostics.

The discriminating control is what makes this a finding rather than an observation — same file, same run:

where result
undefined variable in an ordinary fn body reds undefined variable
the identical undefined name in a transport argv no diagnostic at all

Read off the emitted AST rather than the diagnostic count, three arms in one 0-diagnostic run:

argv: [probe_bin, "0700", "{path}"]        -> ExprVar,  binding_kind null, no inferred node
argv: ["chmod", probe_tail(path: path)]    -> ExprCall, unresolved
argv: [nowhere_declared_symbol, "{path}"]  -> ExprVar,  unresolved, ZERO diagnostics

The position parses expressions — consistent with clever-crab-309's independent finding that a service argv can splice a function returning List<String> — and simply never resolves them.

The claim is filed in its weaker form, deliberately

The first version of this finding said the transport layer cannot be dissolved by citation. That was stronger than what was measured, and the measuring session retracted it unprompted, in the direction that weakened its own result. I filed the corrected version at their request.

The corrected version is worse, not better. "Impossible" would at least fail loudly. What was actually measured is that a citation written here emits as a literal token with nothing refusing — so the failure mode is a silently wrong argv, not a refusal. That is below floor (§5), not a rung on the ladder: the deficit's frequency is zero by construction because no instrument counts it.

Rung and trigger

  • Rung: outside the ladder — silent wrongness. Not mitigatable; nothing contains the harm because nothing observes it.
  • Ceiling: structurally guaranteed. Resolving an argv expression is the same decidable Node-tree read the namespace authority already performs everywhere else. Missing wiring, not an undecidable property.
  • Next-rung trigger: resolve identifiers in transport argv positions through the ordinary name-resolution path and refuse an unresolved one with a typed, located diagnostic.

Why this blocks a live program

It puts roughly 15 of 46 bare-env sites out of scope for citation-based dissolution — extdeps/{shell,python,gunbc,rust/cargo_build,tools/npm} and cli_services. Those sites are out of scope for want of per-site live execution, not out of reach in principle; the corrected claim is precisely what makes that distinction available.

Not claimed

That any argv in the corpus is currently wrong. No instrument in the repository can answer that today — which is the row's point. It records a population and a blindness, not a defect count.

Docs-only; no code paths touched.

Brian Searls and others added 3 commits August 22, 2026 17:04
… silently wrong argv

Audit-queue row 24, filed from the CORRECTED (weaker) form of the finding at
the measuring session's request.

The discriminating control is what makes this a finding: an undefined variable
in an ordinary fn body reds `undefined variable`; the identical name in a
transport argv produces no diagnostic at all, same file, same run. Reading the
emitted AST rather than the diagnostic count shows the position parses
expressions (ExprVar / ExprCall) and never resolves them.

The first version claimed the transport layer CANNOT be dissolved by citation.
That was stronger than measured and was retracted unprompted. The corrected
claim is worse, not better: "impossible" would fail loudly, whereas an
unresolved citation emits as a literal token with nothing refusing -- a
silently wrong argv. Below floor, not a rung.

Ceiling is structurally guaranteed: this is missing wiring over the same
decidable Node-tree read the namespace authority already performs, not an
undecidable property.

Not claimed: that any argv in the corpus is currently wrong. No instrument can
answer that today, which is the row's point.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lved-row

# Conflicts:
#	docs/plans/compiler-guarantee-recovery-gap-analysis.md
Main tops out at 27, leaving 28 and 29 free, and two concurrent PRs both took
28. #8907's row was filed first (as item 23, before main landed 23-27), so it
keeps 28 and this one moves rather than making the older PR move.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brian Searls and others added 13 commits August 22, 2026 18:49
…lved

Two additions, both from still-seal-394's measurement of the emitted AST rather
than the diagnostic count.

First, the failure is not only that an undeclared identifier is accepted. It is
accepted as ExprVar with binding_kind null and no inferred node, so what flows
onward is indistinguishable from a name that resolved. A narrow "refuse unknown
identifiers in argv" patch closes the loud half and leaves the silent half
intact -- retiring the row's visible symptom without retiring the row. Recorded
because the cheap patch is the tempting one.

Second, the fix must not collapse a compile-time cited declaration with a
runtime caller-selected executable. The existing literal-only requirement exists
because an operation INPUT choosing the executable is unsafe; that argument does
not reach a resolved module declaration. Preserving the refusal uniformly would
leave env_path_resolved_program and chmod_binary_path -- authored to be cited --
permanently uncitable where they are needed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…to this diff

This PR is docs-only -- one row in the gap analysis. It cannot produce a
witness failure or a typecheck diagnostic. The prior run's logs have expired,
but main itself is intermittently red on an infrastructure race in the regen
phase (spawn rustfmt: Text file busy, os error 26) when several witnesses runs
execute concurrently, and that failure is content-independent.

Re-running rather than editing, because there is nothing in a markdown row to
fix and editing it to chase a red would be changing the artifact to satisfy an
instrument that was not measuring it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…lved-row

# Conflicts:
#	docs/plans/compiler-guarantee-recovery-gap-analysis.md
…lved-row

# Conflicts:
#	docs/plans/compiler-guarantee-recovery-gap-analysis.md
… identity, never re-run lookup at emit grain
@gunbai-bot

gunbai-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

CI red here was an INFRASTRUCTURE FLAKE, not a defect in this PR, and I am recording the diagnosis rather than silently re-running.

The diff on this branch is 118 added lines in one markdown file and nothing else. It cannot produce a runtime failure, so any red on it is inherited or environmental by construction — that is worth stating first, because it is the cheapest discriminator available and it settles the question before anyone reads a log.

WHAT ACTUALLY FAILED, from run 32644076746:

required-ci: phase regen (first generation vs committed)
required-ci: regen refused: normalize committed v1_compiler_parse.rs: spawn rustfmt: Text file busy (os error 26)
required-ci: FAILED PHASE regen

ETXTBSY on spawn means the rustfmt binary was open for writing at the moment the regen phase tried to execute it — a concurrent toolchain install or update on the same host, not anything about this branch's content.

THE FLOOR PHASE ON THIS SAME RUN WAS CLEAN, which is the other half of the diagnosis and easy to miss because the log carries 57 loud lines that are not failures:

planned=10679 executed=10679 terminal=10679 passed=10378 known_red_held=36 failed=0
stale_quarantine=0 interrupted_before_verdict=0 completed_over_cost_requirement=0
host_tool_unresolved=0 route_gap_unenrolled=0 stale_route_gap=0
known_red_runtime_errored=164

Every one of the seven gating causes is zero. known_red_runtime_errored=164 is REPORTED AND DELIBERATELY NOT GATING — claim_executor required_floor_outcome_is_clean enumerates seven causes and that arm is not among them, with the reason stated at the definition: making it block reds lanes with no connection to the defect, and needs an approved design and a shadow phase rather than an author's judgement. A reader who greps the log for alarming lines finds 57 of them and concludes the floor failed; it did not.

ONE THING WORTH ESCALATING RATHER THAN JUST RETRYING. ETXTBSY is a contention signature, and the fleet's committed runner width moved from 6 to 21 slots per host on 2026-08-23. More concurrent jobs per host means more concurrent toolchain access, and this class gets more likely rather than less as the width setting beds in. If it recurs, the repair is to stop racing on a shared toolchain binary — not to raise a retry count, which would be the absorbing fallback in its usual disguise.

Re-running the failed job. Nothing to fix on this branch.

— sent from eager-crane-282

@briansrls
briansrls merged commit 5cf7fa7 into main Aug 23, 2026
2 checks passed
@briansrls
briansrls deleted the transport-argv-unresolved-row branch August 23, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant