Repository navigation
One binary, two spellings: 'env'/'/usr/bin/env' and 'chmod'/'/bin/chmod' are section-3 nicknames at the transport layer - #8918
Merged
Conversation
…one of the spellings disagreed
extdeps.tools.env is new: env(1) had no upstream authority at all, so a product
module (gunbc.roadmap_dashboard_instance) held the only declaration of its path
in the repository -- a layer inversion sitting underneath the nickname. It now
derives from the tool authority instead of declaring it.
The sharp finding is chmod. gunbc.roadmap_dashboard_instance_apply spelled
"/usr/bin/chmod" twice -- once as the program its install step execs, once in
the required-executable roster its preflight tests for existence -- while
extdeps.tools.chmod, the tool's authority, records "/bin/chmod" for the same
fleet. Two absolute paths for one binary in two modules, neither able to see
the other, agreeing today only because these hosts are usrmerged. The preflight
was gating a path no sanctioned caller runs. Both sites now read the authority.
The two forms are two FACTS, not a right and a wrong spelling. An absolute path
is a claim about an observed filesystem; asserting one for a remote target this
repository has not observed would fabricate a host fact (DESIGN 5). So each
authority declares both, with its reason, and every reachable call site cites
one rather than inventing a literal.
Out of reach and named rather than missed: ~15 sites sit inside
`transport shell { argv: [...] }`, where an identifier is not name-resolved at
compile time -- measured with a same-file same-run control, an undefined
variable in a fn body reds while an undeclared identifier in a transport argv
produces zero diagnostics.
devboot's twelve env sites are deliberately untouched: gunbc#8912 removes ten
of them outright by making GIT_INDEX_FILE an operation-owned transport prefix.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…he two-facts rows on them quick-newt-661's ArgvCommand-seal lane declares a hard dependency on env_prefixed_args, so cutting the argv producers would have blocked their PR to keep this diff tidy. Taken wholesale from origin/env-execution-authority (witnesses green by execution there; re-run here rather than carried), with env_path_resolved_program added beside env_binary_path and the annotation rewritten: the bare name is not a decline to say which binary, it is the correct form for a host this repository has not observed. Adds the two assertions that would red if a later editor decided one row of each pair was a stale duplicate and pointed it at the other -- the repair that looks like tidying and is a fabricated host fact. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 22, 2026
… imports Resolutions: - extdeps/tools/env.dag takes main's wholesale. My branch had accidentally committed the throwaway stub I was typechecking against (a git add -A picked up the untracked file); it is gone, and the authority is still-seal-394's. - The two env call sites take my builder form. main converted the 'env' program WORD at both; env_prefixed_command carries the whole invocation, so the binding is a modeled EnvSet rather than a joined string and the word comes from the same row either way. - chmod_set_mode_command now takes its program as a parameter, because main landed chmod's second spelling and the two are two facts: the observed /bin/chmod a sudoers rule names, and the PATH-resolved name for a host we have not read. fleet_converge_plan_cli keeps the resolved row main gave it, so this merge changes no emitted word there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhAfyPkuxnjZaTzPn5PyE1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The defect this leads with
gunbc.roadmap_dashboard_instance_applyspelled"/usr/bin/chmod"twice — once as theprogramits serve-binary install step execs, once insidedashboard_required_target_executables, the roster whose entire job is to assert the required binaries exist before apply proceeds. Meanwhileextdeps.tools.chmod, the tool's authority, records"/bin/chmod"for the same fleet, andtools.build_step_transportruns that one.Two absolute paths for one binary, in two modules, neither able to see the other. The preflight was gating a path no sanctioned caller execs. It passed only because these hosts are usrmerged — a host fact nobody declared, quietly holding both claims up, and the first non-usrmerged target turns it into a mystery. Both sites now read
chmod_binary_path.Underneath the chmod pair sits the same class one layer worse.
env(1)had no upstream authority at all:gunbc.roadmap_dashboard_instance'sdashboard_environment_binding_executablewas the only declaration of env's path anywhere in the repository. A product module standing as the upstream authority for a coreutils binary is the §3 layer inversion that the nickname was sitting on.dag/extdeps/tools/env.dagnow owns it and the product row derives from it.The design decision that changed the answer
The tempting rule is the bare name is a decline to say which binary, so the absolute path is correct everywhere. That is half right and the wrong half is load-bearing. The two forms answer different questions:
chmod.dagcarries one at all), what a preflight can test for existence, and what refuses loudly where the claim is false.So each authority declares both rows, each with its cited reason, and every reachable call site cites one. The nickname dies — no site invents a spelling — without erasing the distinction, because a caller now has to declare which question it is asking. This correction propagated: it caused
quick-newt-661to revert nine tool rows that had been written to absolute paths on the older rule.Populations (git grep over HEAD,
dag/**/*.dag)"env""/usr/bin/env"pijul_upstream_model_execution_testfixtures"chmod""/usr/bin/chmod"Two of the
"env"hits (extdeps/languages/yaml/gha_workflow) are a YAML mapping key, not the binary — counted and excluded, recorded here so a later reader does not re-derive it.What is out of reach, named rather than missed
~15 sites sit inside
transport shell { argv: [...] }(extdeps/{shell,python,gunbc,rust/cargo_build,tools/npm},gunbc.cli_services). An identifier in that position is not name-resolved at compile time. Measured with three arms in one 0-diagnostic run, reading the emitted AST rather than the diagnostic count:Same-file same-run control: an undefined variable in an ordinary
fnbody redsundefined variable.The honest claim is "citing a symbol there is UNGUARDED", not "impossible" — the position parses expressions and may well resolve at realization; if it does not, it emits as a literal token and nothing refuses. That is worse than impossible, because impossible fails loudly. I first reported this as "cannot be dissolved by citation" and retracted it in the weakening direction. Filed as its own substrate row in gunbc#8916.
These ~15 are BLOCKED BY gunbc#8916, not residue of this lane and not a safety boundary (per the ruling on that row, which post-dates the first draft of this section and corrects it). The standing operation-argv note says the executable position must be a literal because letting an operation input choose the executable is unsafe. That argument is sound and it does not reach this case: a compile-time citation of a resolved declaration and a runtime caller-selected executable are different facts, and the ruling states they must not be collapsed —
env_binary_path,env_path_resolved_programandchmod_binary_pathare exactly the first case. So the blocker is a missing compiler path that today refuses the safe and unsafe cases alike because it cannot tell them apart — the obligation sits in the name-resolution layer, which the ruling assigns by name and says deserves a cut of its own. Nothing in this PR's design is what those sites are waiting on.dag/gunbc/devboot/{build,produce}.dagare deliberately untouched: gunbc#8912 deletes ten of their twelve env sites by makingGIT_INDEX_FILEan operation-owned transport prefix inextdeps.git.plumbing, which is a better answer than an env prefix.Evidence
Nine witnesses run by execution on a binary built from this tree, remote (
ctrl-build --remote, one dispatch, build and run together):dag/test/claim/env_execution_authority_witness_test.dag— the arity of an assignment vs an unset,NAME=not collapsing into-u NAME, tail-producer/whole-vector agreement, the binary being absolute, and the newthe_path_resolved_name_is_a_second_fact_not_the_binary_paththe_path_resolved_chmod_is_a_second_fact_not_the_binary_path(new) beside the existingchmod_argv_adds_the_execute_bit_rather_than_replacing_the_modeas a controldashboard_target_preflight_derives_dispatch_platform_dependencies, whose/usr/bin/chmodliteral moved to/bin/chmod— that literal is now the one independent statement of the value, so it reds if the authority moves without anyone looking thereThe discriminating RED
Ten greens show the witnesses pass, not that they can fail. Mutation probe, one remote dispatch, ephemeral checkout,
chmod_path_resolved_program"chmod"->"chmodX":the_mode_is_set_on_staging_before_the_renametruefalsethe_path_resolved_chmod_is_a_second_fact_not_the_binary_pathtruefalsechmod_argv_adds_the_execute_bit_rather_than_replacing_the_mode(control)truetrueThe control is the load-bearing row. It pins the ABSOLUTE path, which the mutation does not touch, so its staying green is what establishes the mutation was targeted rather than broadly breaking the module -- two reds beside a red control would have measured nothing.
The two "second fact" witnesses are the ones that matter for durability: they red if a later editor decides one row of each pair is a stale duplicate and helpfully points it at the other. Both state their expected values as literals, so they are independent oracles rather than the module agreeing with itself.
Attribution
extdeps/tools/env.dag'sEnvBinding-grounded producers and its witness file areeager-crane-282's, taken fromorigin/env-execution-authorityrather than reinvented; their green is re-run here, not carried.#8915is closed. The two-facts rows and annotation are mine.env_prefixed_argsships becausequick-newt-661's ArgvCommand-seal lane declares a hard dependency on it — I had cut the producers as unconsumed, and that was the caller.