Skip to content

chore(scripts): resolve ten of the twenty-one unreferenced infrastructure scripts (#15127) - #15144

Merged
mrveiss merged 4 commits into
Dev_new_guifrom
issue-15127-unreferenced-scripts
Aug 28, 2026
Merged

mrveiss merged 4 commits into
Dev_new_guifrom
issue-15127-unreferenced-scripts

Conversation

@mrveiss

@mrveiss mrveiss commented Aug 26, 2026 •

Copy link
Copy Markdown
Owner

Targets Dev_new_gui. #15129 has merged (e215065d8), so the baseline this ratchets down
is on the default base; this branch was rebased with
git rebase --onto origin/Dev_new_gui 1bdc67174, which dropped #15129's three commits
cleanly — they were in this branch's own history, not merely in the base.

Thinking Path

21 scripts, and the instruction that matters is that the count is a trap. I resolved ten with
evidence and left eleven explicitly undecided rather than making 21 fast calls, so this is
Refs #15127, not Closes.

The two flagged for special care both contradict the issue's stated premise.

  • git-askpass.sh — the issue says an askpass helper is invoked by assigning GIT_ASKPASS=, which
    a basename grep cannot see. I searched the mechanism, not the name: there is no GIT_ASKPASS
    assignment anywhere in the repo
    , and the only *ASKPASS* occurrences at all are in
    autobot-backend/services/terminal_secrets_service.py, which sets SSH_ASKPASS to a helper it
    writes itself at runtime (_setup_askpass_script, lines 339-355) — never to this file. So it
    is not invoked invisibly; it is not invoked. It is also unusable if it ever were: git reads the
    first line of an askpass helper's stdout as the credential, and lines 10, 15 and 20 print a
    human prompt before the value on lines 12, 17 and 22.
  • utilities/load-env.sh — likewise. No BASH_ENV, no ENV=, no direnv/.envrc, and
    enumerating every source/. target in every shell file in the repo yields six distinct
    targets, none of them this file (the only env file anyone sources is .env.native-vm, directly).
    Two of its four modes select .env.distributed and .env.docker-desktop, neither of which has
    ever been tracked, and ENV_FILE resolves against the caller's cwd while its own help text says
    source ./load-env.sh — so its documented invocation cannot find its own file. Its job is owned
    by detect-environment.sh (same export $(grep -v '^#' … | xargs) idiom, and is referenced)
    plus generate-env-files.py / validate-env-files.py.

Neither was retired on the strength of a grep: each has a named, landed successor doing the same
job.

A defect in the guard itself, found on the way in — now fixed in the base, not here.
repo_tests/unreferenced_shell_script_test.py was red on #15129's original head, on all 21 entries
at once:

FAILED TestBaselineRatchetsDownOnly::test_no_baselined_script_has_gained_a_reference

The baseline module lists every script by path, sits in the tree, and git grep finds it — so each
baselined script had exactly one "reference": the list of things with no reference. My own
additions reintroduced it one level up, because a test that names a script in an assertion becomes
that script's reference; I caught that by mutation rather than by reading, when deleting the README
entry for monitor_testing.sh failed to turn the guard red.

#15129's owner has taken that fix into the base as bd96b8542 (NOT_A_REFERENCE, excluding both
bookkeeping modules), which is the right home for it — a guard that is red the moment it lands is
not a guard. This PR is rebased onto it and carries none of it. What remains here is the
consequence: every kept script is pinned to the document that references it, not merely to "is
referenced", because that weaker assertion is satisfied by this module's own mention of the
filename. That is the same shape as the test_the_wired_in_script_is_referenced_by_the_runbook
correction in the base.

What Changed

Retired — five (proved nothing should call them)

Script Evidence
git-askpass.sh No GIT_ASKPASS/ASKPASS assignment repo-wide; terminal_secrets_service.py:339-355 generates its own helper; and it prints the prompt where git expects the secret
start_vnc.sh Superseded in the commit that introduced it (fa55a78bde), which added api/vnc_manager.py alongside it invoking /usr/bin/vncserver directly and never referencing the script; infrastructure/browser-vnc.service:16-19 runs the identical -geometry 1920x1080 -depth 24 on display :1
utilities/sync-grafana-dashboards.sh ansible/roles/monitoring/tasks/grafana.yml:131-134 performs the same dashboards→/var/lib/grafana/dashboards/ copy; the script's own header already concedes Ansible owns it; and its source path (config/grafana/dashboards) has not existed since #781
utilities/create_github_issues.sh A one-shot backlog seeder for a Redis consolidation completed in 2025; its seven issue bodies enumerate ~30 files under src/ and backend/, roots removed at #926
utilities/load-env.sh See above — no invocation by any mechanism, two modes selecting files that never existed, a superseding referenced sibling

Wired in — two (each was unrunnable from any directory)

  • install-doc-sync-hook.sh — HOOK_SOURCE pointed at $PROJECT_ROOT/scripts/hooks/, removed at
    refactor: Reorganize repository folders by deployment role #781, so the installer could only print "Hook source not found" and exit 1. The hook it installs
    still exists at autobot-infrastructure/shared/scripts/hooks/post-commit-doc-sync; the installer
    and the hook were added as a designed pair in 3b95ecf466 (Documentation Indexing - Enable Chat Agent Self-Awareness #250). Repointed and documented.
  • utilities/start-seq-forwarder.sh — line 7 cds into utilities/, after which
    python3 scripts/seq_log_forwarder.py resolves to utilities/scripts/seq_log_forwarder.py,
    which has never existed. Anchored to ${SCRIPT_DIR}/../seq_log_forwarder.py, which does, with a
    fail-closed check. It also ran pip install aiohttp into whatever interpreter was first on
    PATH; it now reports the missing dependency and exits instead of mutating the caller's
    environment.

Recorded as genuine manual tools — three

All three already run correctly against the current tree (each resolves its root through
scripts/lib/project_root.sh, hardened at #13149) and had no inbound reference of any kind.

  • network/fix-wsl-networking.sh → a new Repair script section in
    docs/developer/WSL2_NETWORKING.md, which described exactly this failure mode and named no
    script at all.
  • monitor_testing.sh and cleanup-disk-space.sh → a new Manual operator tools section in
    autobot-infrastructure/shared/scripts/README.md, alongside the two wired-in scripts.

The guard

  • TestTheBatchThisIssueResolved asserts, per script, that the five retired ones are gone from both
    tree and baseline; that each of the five kept ones is named by the specific document that
    justifies keeping it
    (KEPT maps script → document); and that both wired-in scripts name paths
    that exist and that neither runs pip install.
  • The NOT_A_REFERENCE exclusion this depends on lives in the base (bd96b8542), not here.
  • Baseline: 21 → 11 entries, down-only. The eleven that remain are listed there unchanged.

Zero-headroom floors — six, across three files

Retiring utilities/sync-grafana-dashboards.sh removes one source .../lib/... site, and
repo_tests/shell_lib_sources_resolve_test.py carries five non-vacuity floors pinned to the tree's
exact current size. All five had to move by exactly one:

line assertion before after
281 len(_SITES) 78 77
293 len(rels) distinct scripts 71 70
355 checked (resolved) 73 72
391 checked (shape) 73 72
458 len(decisive) 73 72

Only the first is visible on a first run: len(rels) sits after it in the same test function, so
the earlier assertion ends the function before it is reached. A single red line in a multi-assert
test is a floor, not a census of what broke — measured by evaluating the module's internals
directly rather than by reading the failure list.

Attribution measured, not assumed. Of the five files this PR deletes, exactly one carries a lib
source site:

files deleted by THIS PR: 5
deleted files that carried a lib source: ['.../utilities/sync-grafana-dashboards.sh']

So the delta is exactly −1 on every counter, and each floor is decremented by that and no more.

Recomputed after #15129's squash and the four merges that followed (#15142, #15125, #15131,
#15148), rather than assumed to have survived. Every floor still sits exactly at the count, with
no slack — which is the property the contract below depends on:

counter recomputed floor
len(_SITES) 77 77
len(rels) 70 70
len(decisive) 72 72
checked (shape) 72 72
extensionless 16 16 (untouched)
_SCANNED 174 derived from git ls-files (#15079)

Why decrement rather than loosen. The file already answers this, at the len(rels) floor:

The floor is left AT the current count rather than lowered for headroom, so it still catches a
regressed matcher; a future legitimate retirement has to come here and say so, which is the point.

That is a deliberate acknowledge-on-change tripwire, and #14371 set the precedent by decrementing
56 → 55 with a comment naming the retired script. Replacing it with a loose floor plus "this is not
a census" would weaken a guard a prior issue deliberately tightened, and would remove exactly the
step that forces a human to state which script went and why. These decrements follow the existing
precedent's shape: measured delta, named script, named issue.

The floors keep their teeth — see mutation D below.

The sixth floor: the AUTOBOT_ reach self-check

autobot-infrastructure/shared/tests/test_ssot_config_lib.sh:458 (run by the ssot-config-lib-guard
pre-commit hook, gated in CI by verify-precommit-config step 8) carries the same shape again:

FAIL: reach self-check found only 59 distinct AUTOBOT_ names -- expected >= 61 (#14173 baseline)

Measured, and the arithmetic is −3, not −2. The floor was not sitting at the count: the base
tree held 62 distinct names against a floor of 61, so one name of slack was already there.

distinct AUTOBOT_* names in tracked *.sh
origin/Dev_new_gui 62 (floor was 61 — one of slack)
this branch 59

All three lost names trace to one retired script, utilities/load-env.sh, which was the only
tracked .sh file naming any of them:

name sole .sh holder at base still live?
AUTOBOT_DEPLOYMENT_MODE utilities/load-env.sh yes — env_registry.py:214, four .env* files, read by autobot-backend/user_management/config.py
AUTOBOT_PLAYWRIGHT_API_PORT utilities/load-env.sh no consumer anywhere — filed as #15151
AUTOBOT_PLAYWRIGHT_HOST utilities/load-env.sh no consumer anywhere — filed as #15151

The other four retirements contributed no AUTOBOT_ name uniquely, so nothing else in this diff
reduced the reach.

Acknowledge-on-change, not derivable. The check counts the very names its own regex finds, so an
expectation computed the same way would confirm itself — the _SITES argument unchanged. (#15079's
reach floor was derivable, from git ls-files, and was correctly derived; these are not the same
problem.) Lowered to 59, the exact current count, which also absorbs the stale slack, with a
comment naming the script, the three names and this issue. It keeps its teeth — see mutation E.

The file's own comment states the purpose this preserves: the var-count floor "catches a regex that
stops matching a variable shape"
.

The pattern

Six zero-headroom floors, in three files, tripped by one batch of retirements:
repo_tests/shell_lib_sources_resolve_test.py (five),
autobot-infrastructure/shared/tests/test_ssot_config_lib.sh (one). They are deliberate
acknowledge-on-change tripwires and this PR treats them as such — but they are invisible until a
deletion trips them, they live in unrelated files, and each fails independently. The next person
retiring a script will hit whichever one this PR did not touch.
Worth a follow-up that inventories
them in one place; not folded in here, because retuning six guards' sensitivity is a change of a
different kind from resolving ten scripts.

Not resolved — eleven, deliberately

backup_ollama_models.sh, build_secure_sandbox.sh, cleanup-legacy-python.sh,
debug_chat_system.sh, fix-frontend-dependencies.sh, start_containers.sh, start_seq.sh,
utilities/batch-configure-vms.sh, utilities/enable-phase4-enterprise.sh,
utilities/ollama_thread_utility.sh, utilities/security-audit.sh.

Three are genuinely ambiguous rather than merely unexamined, and the choice is an owner's, not
mine: batch-configure-vms.sh is live and was maintained as recently as #14172, but Ansible is the
declarative owner of the sudoers and package state it sets imperatively;
ollama_thread_utility.sh needs a one-line path fix but roles/llm/templates/ollama.service.j2
may already make it redundant; start_seq.sh reaches for a forwarder that is gone entirely rather
than mis-pathed, so wiring it in means merging it into start-seq-forwarder.sh.

Verification

Criterion Evidence Kind
git-askpass.sh invoked by no mechanism git grep -i askpass → one hit, its own comment; no GIT_ASKPASS anywhere; successor at terminal_secrets_service.py:339-355 forensic
load-env.sh invoked by no mechanism every source/. target in every shell file enumerated → 6 distinct, none matching; no BASH_ENV/.envrc/direnv; .env.distributed and .env.docker-desktop untracked forensic
start_vnc.sh superseded at birth git show fa55a78bde adds vnc_manager.py in the same commit, calling vncserver directly forensic
Wired-in targets exist hooks/post-commit-doc-sync and seq_log_forwarder.py both tracked; asserted in the test static
Retired scripts had no references per-script git grep -lI -F <basename> excluding the file itself → NONE for all five static
Kept scripts are now referenced guard's own unreferenced() no longer lists them unit
Guard was red before the base's fix pytest repo_tests/unreferenced_shell_script_test.py on 129eff2d2 → 1 failed, 8 passed unit
Orphan guard green on this head 24 passed unit
Shell-sweep guard green on this head 78 passed; both together 102 passed in 15.50s unit
AUTOBOT_ reach delta is exactly three, all from one script base 62 → head 59; each name's sole .sh holder was load-env.sh forensic
ssot-config-lib-guard clean bash autobot-infrastructure/shared/tests/test_ssot_config_lib.sh → 38 passed, 0 failed unit
Lib-source delta is exactly one of the 5 deleted files, only sync-grafana-dashboards.sh carries a source .../lib/ site static
Lint / size black --check clean, flake8 → 0, scripts/check_python_file_size.py → exit 0 static
Shell syntax bash -n on both modified scripts → clean static

Shards: repo_tests/unreferenced_shell_script_test.py → shard 8 of 12;
repo_tests/shell_lib_sources_resolve_test.py → shard 10 of 12
(stable_shard.shard_of, --shard-splits 12). No new module added, so no shard membership moves.

Not proven: shellcheck is unavailable on this runner, so the two modified shell scripts are
verified by bash -n and by reading, not by a linter. Neither script was executed — one installs a
git hook, the other starts a forwarder against a live Seq.

Contrast mutations (re-run against this branch's final head, 48455c821)

A. Delete the README entry documenting monitor_testing.sh — the "record as a manual tool"
resolution is only real if removing the documentation puts the script back on the pile:

FAILED TestNoNewUnreferencedScript::test_every_script_is_referenced_or_baselined
E   AssertionError: these scripts have no inbound reference from any other tracked file:
E       autobot-infrastructure/shared/scripts/monitor_testing.sh
FAILED TestTheBatchThisIssueResolved::test_kept_script_is_referenced_by_its_document[monitor_testing.sh-...README.md]
E   AssertionError: autobot-infrastructure/shared/scripts/README.md no longer names
E   monitor_testing.sh. That entry is the whole reason the script is not debris -- restore it or
E   retire the script (#15127).

Before the base's NOT_A_REFERENCE fix this mutation passed, which is how the self-reference
defect surfaced.

B. Empty KNOWN_UNREFERENCED — the enumeration must fail when emptied, not report a clean tree:

FAILED TestBaselineRatchetsDownOnly::test_baseline_is_not_empty_while_it_is_still_being_worked_through
E   AssertionError: baseline emptied; remove the file and this test together
FAILED TestOwnBookkeepingIsNotAReference::test_a_baselined_script_is_named_only_by_the_bookkeeping
FAILED TestNoNewUnreferencedScript::test_every_script_is_referenced_or_baselined

C. Restore one retired script to the tree — retirement must be asserted, not assumed:

FAILED TestTheBatchThisIssueResolved::test_retired_script_is_gone_from_tree_and_baseline[git-askpass.sh]
E   AssertionError: git-askpass.sh was retired but is tracked again
FAILED TestNoNewUnreferencedScript::test_every_script_is_referenced_or_baselined

D. Regress the source matcher — proves a floor lowered by one still catches a broken matcher
rather than having been tuned into uselessness. Narrowing _SOURCE to only ${SCRIPT_DIR}-prefixed
quoted paths drops the sweep from 77 sites to 39:

FAILED test_the_sweep_actually_reached_the_tree
E   AssertionError: only found 39 lib source sites — expected >= 77 (#14041 enumerated 56 scripts;
E   #14891 added 17 sites in 16 extensionless hooks; #15127 retired one); the matcher has regressed
FAILED test_every_lib_source_resolves_to_a_real_file
E   AssertionError: only resolved 39 source sites — the expander has regressed and this test would
E   pass having checked almost nothing
FAILED test_a_missing_lib_is_never_swallowed
E   AssertionError: only checked 39 sites — this would pass vacuously
E   AssertionError: only 39 decisive sites — vacuous

A first attempt at this mutation — dropping the unquoted-path alternative — left all 78 green,
because every real site is double-quoted. Recorded because a mutation that does not move the
number proves nothing, and reporting it as a pass would have been the vacuity this PR is about.

E. Regress the AUTOBOT_ matcher — narrowing the reach scan's pattern to $AUTOBOT_VNC…
drops it from 59 names to 6:

FAIL: reach self-check found only 6 distinct AUTOBOT_ names -- expected >= 59 (#14173 baseline, #15127 retired 3)
FAIL: reach self-check's scan did not find AUTOBOT_SSH_KEY -- matcher regressed
FAIL: reach self-check's scan did not find AUTOBOT_SSH_USER -- matcher regressed
FAIL: reach self-check's scan did not find AUTOBOT_SLM_NODE_ID -- matcher regressed
=== 34 passed, 4 failed ===

So a floor lowered by three still catches a regressed regex. Clean run: 38 passed, 0 failed,
which is the ssot-config-lib-guard hook CI gates on.

Tree restored after each; working tree clean. 24 passed on the orphan guard, 78 passed on
the shell-sweep guard, 102 passed together on the rebased head.

Filed, not fixed here

#15151 — AUTOBOT_PLAYWRIGHT_HOST / AUTOBOT_PLAYWRIGHT_API_PORT are documented but read by nothing. Pre-existing, not caused by the retirement: load-env.sh had no caller, so they had no live consumer before it went either.

#15143 — detect-environment.sh selects three .env files that do not exist. Different scope: it
is referenced, so the unreferenced-script guard never looked at it, and it needs correcting
rather than retiring.

Model Used

Claude Opus 5 (1M context)

Refs #15127 — ten of twenty-one resolved; eleven remain in the baseline, named above.

@mrveiss
mrveiss force-pushed the issue-15127-unreferenced-scripts branch from aca59e8 to 167db9d Compare August 26, 2026 16:32
@mrveiss mrveiss changed the title chore(scripts): resolve ten unreferenced infrastructure scripts and stop the guard citing itself (#15127) chore(scripts): resolve ten of the twenty-one unreferenced infrastructure scripts (#15127) Aug 26, 2026
@mrveiss
mrveiss force-pushed the issue-15127-unreferenced-scripts branch from 167db9d to 2da1340 Compare August 26, 2026 17:54
Base automatically changed from issue-15079-orphan-scripts to Dev_new_gui August 26, 2026 19:03
@mrveiss
mrveiss force-pushed the issue-15127-unreferenced-scripts branch from 2da1340 to f5861ee Compare August 26, 2026 19:09
@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No new hardcoded values of either class — ssot and other both block.

Known backlog in pipeline-scripts/hardcoded_values_baseline.txt is suppressed and tracked in #14371.

@mrveiss
mrveiss merged commit ae232fb into Dev_new_gui Aug 28, 2026
59 checks passed
@mrveiss
mrveiss deleted the issue-15127-unreferenced-scripts branch August 28, 2026 04:14
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