Skip to content

chore(vehicle): land CI & hooks infra — 6 approved PRs (#16938, #17032, #16952, #16958, #16882, #16959) - #17047

Merged
mrveiss merged 35 commits into
mainfrom
vehicle-v090-2026-09-18-ci-hooks
Sep 19, 2026
Merged

mrveiss merged 35 commits into
mainfrom
vehicle-v090-2026-09-18-ci-hooks

Conversation

@mrveiss

@mrveiss mrveiss commented Sep 18, 2026 •

Copy link
Copy Markdown
Owner

Thinking Path

Six approved PRs (git-hook and CI infra) were each green in isolation and none could land without staling the others on serial merge. This branch is built entirely through the REST API: created from main, then each approved head merged in with POST /repos/.../merges. One CI run covers the union instead of six sequential ones.

Named vehicle-v090-2026-09-18-ci-hooks, flat with no slash.

#16938 and #17032 both touch scripts/install-git-hooks.sh. #16938 was merged into the vehicle first, as instructed; #17032 then merged cleanly on top (201 Created, no conflict).

What Changed

Nothing new. Six already-reviewed heads, each merged cleanly with no conflicts:

PR Head Delivers Ledger verdict
#16938 705a0f8 #16923 — chain formatter dispatch after the branch guard in pre-commit approve@705a0f8fb
#17032 0114377 #17029 — track the commit-msg hook, install it, enforce the subject convention approve@011437730
#16952 c19678e #16601 — prune SKIP dirs during the walk, not after rglob returns approve@c19678eee
#16958 c3d8b47 #16950 — a delegated subagent runs a write its parent is held from approve@c3d8b4782
#16882 9410b8c #15317 — stop binding ChromaDB to every interface by default approve@9410b8c36
#16959 cd87aab #16934 — gate doc-sync to main-at-origin-tip, move it off post-commit approve@cd87aab94

No excluded members — all six passed the ledger gate (approve at current head, no STALE, no failing check, open) and merged without conflict, including the declared #16938/#17032 overlap on scripts/install-git-hooks.sh.

Verification

Each member carries a ledger review verdict pinned to the exact head merged here — the table above, all non-stale at merge time. #16938 was merged before #17032 as instructed to establish the shared file's baseline; the second merge returned 201 Created with no conflict.

What this PR's own CI must establish is that the union holds: no conflict between members, hooks install cleanly together, no ratchet baseline moved.

Model Used

Claude Sonnet 5 (coordinator session, vehicle build only — no new code). Members authored and reviewed by their own PR sessions per the ledger verdicts above.

Closes #16923
Closes #17029
Closes #16934

Lint fix commit

3310ac7 -- lint-only, produced by black/isort/flake8 at the pinned versions, needs non-author review.

Files touched:

  • autobot-backend/auth_rbac_admin_guard_test.py -- black (code-quality black step)
  • repo_tests/doc_index_worktree_contamination_16934_test.py -- black (pre-commit hook scope)
  • repo_tests/chromadb_bind_not_hardcoded_15317_test.py -- isort (pre-commit hook scope)

mrveiss and others added 30 commits September 17, 2026 15:48
…15317)

Both the ai-stack and redis role's systemd unit template used chromadb_host
(the client-facing DIAL address) as the unit's BIND address too, and the
redis role's template hardcoded --host 0.0.0.0 outright -- in front of four
unpatchable ChromaDB advisories, one a pre-auth RCE, with the host firewall
as the only remaining control.

Adds chromadb_bind_host (group_vars/all.yml), a new variable dedicated to
the bind address, defaulting to 127.0.0.1. chromadb_host is left alone as
dial-only rather than repurposed, since its full set of consumers was not
traced and 0.0.0.0 as a dial value pre-dates this issue. A multi-node
install that needs ChromaDB reachable from another host sets
chromadb_bind_host explicitly and adds a subnet-scoped firewall rule
(documented in docs/architecture/NETWORK_TOPOLOGY.md).

Also re-binds the infra repo's decorative reference-copy unit
(autobot-infrastructure/autobot-database/templates/autobot-chromadb.service,
confirmed non-live -- install-bare-metal.sh renders its own inline unit and
never reads this file) so it cannot be copy-pasted forward as a stale,
wide-open example.
#16923)

.pre-commit-config.yaml declares black/isort/flake8/autoflake/mypy and this
repo's own local guards, but nothing ran any of them locally: the local
`pre-commit` hook slot held only the Target Branch Guard -- a self-contained
script with no pre-commit-framework dispatch at all. The first thing that
ever ran black was CI, a full round-trip after every formatting mistake.
`pre-commit.pre-commit-framework`, sitting beside it, turned out to be a
stale copy of the SAME guard from before the Dev_new_gui->main rename, not
the framework's own dispatcher -- confirmed by diff, not assumed.

tools/git-hooks/pre-commit: the branch-guard section is untouched (still the
sync source for autobot-infrastructure's twin); its `*)` arm now falls
through instead of exiting, into a new section that dispatches staged files
to the `pre-commit` framework binary (`pre-commit run --hook-stage pre-commit
--files <staged>`) when it's on PATH, skipping gracefully otherwise so the
hook stays a self-contained file with no hard dependency. Verified end-to-end
against a real checkout of this repo (not just the unit tests below): an
unformatted file gets reformatted and the commit refused, a protected-branch
commit still blocks before the dispatch ever runs, and scripts/hooks/post-
checkout's separate flock-wrapper injection (#1684) targets the same `set
-uo pipefail` anchor this change preserves, so it keeps working unmodified.

repo_tests/git_hooks_formatter_dispatch_16923_test.py (new): uses a
hand-rolled local hook in the fixture's own .pre-commit-config.yaml instead
of the real black/isort, so the dispatch mechanism itself is proven without
depending on network access to a formatter's own pre-commit environment a
fresh CI runner may not have cached. Covers: an unformatted file (created via
plain file write, never touched by an editor tool) is corrected and the
commit refused, then succeeds once re-added; an already-clean commit is not
blocked; the branch guard still blocks release/master with the file left
untouched (proving the dispatch never ran); the same property holds when
installed from a worktree; a negative control reconstructing the pre-#16923
hook (guard only) confirms the identical scenario would NOT have been caught
by it; and github-actions[bot]'s auto-fix-generated-types.yml is confirmed to
never call scripts/install-git-hooks.sh, so it stays hook-less by
construction rather than by an assumption nothing checks.

Refs #16923
…from (#16950)

A parent whose work item gates "writing files" on human approval can call
the delegate tool, and the child it gets is built from the child profile
alone: build_governed_identity({"agent_id": agent_type}) drops the
parent's approval categories and work item. The child's write_file then
runs unapproved -- the refusal is laundered through the delegation.

The failing half is a strict xfail with raises=AssertionError: it reports
XFAIL on main as the proof, and the fix's XPASS fails the suite, so the
marker must come out in the commit that closes the hole. The preconditions
(the parent is held; the delegation ran) are asserted in a separate,
ordinary test, so broken setup can never pass as proof.
…mit (#16934)

The doc-sync git hook ran on every commit in every worktree, with no branch
or origin check, indexing that worktree's own tree into the shared, live
autobot_docs ChromaDB collection. A fresh worktree has no per-checkout hash
cache, so its first commit read as every file changed and wrote unmerged
branch docs into production.

- Moved doc-sync from post-commit to post-merge (fires only after a local
  git merge/pull), with an explicit gate: branch must be main AND HEAD must
  equal origin/main's own tip. A branch merging into a locally-named "main"
  that never tracked origin's tip still does not index.
- Hash cache (doc_indexer.py and tools/index_documentation.py's own
  autobot-infrastructure/shared copy is unused dead code -- see #16956) now
  resolves to the checkout's shared git-common-dir via new
  autobot_shared.paths.git_common_dir()/shared_cache_path(), not a
  per-worktree data/ path, fixing the cache-miss root cause.
- DocIndexerService.rebuild_from_scratch() and `index_documentation.py
  --rebuild` deliver the one-time remedy for branch docs already in
  production (ordinary --force re-indexing never removes a chunk whose file
  no longer exists in the tree being scanned). Documented, not run here --
  see docs/operations/DOC_INDEX_REBUILD.md.
- Added install-post-merge to .pre-commit-config.yaml so the new
  scripts/hooks/post-merge dispatcher is actually bootstrapped, mirroring
  install-post-commit/install-post-checkout.
- repo_tests/doc_index_worktree_contamination_16934_test.py: drives the real
  hook via actual git commit/merge against a throwaway repo (plus a bare
  remote for the positive control), covering both gates, the plain-commit
  case, and a negative control proving the pre-fix wiring would have
  indexed the same scenario.

Refs #16934
…, not after (#16601)

test_modules() now watches which directories os.walk is fed to next, using a
spying wrapper plus a synthetic SKIP-named directory holding a sentinel file.
Every existing test here passes equally against rglob()-and-filter and
os.walk()-with-pruning, because both strategies land on the identical final
file list -- that identity is exactly why nothing caught the regression class
#16601 fixed. The new test fails when the dirnames[:] = [...] pruning line is
reverted to a post-hoc filter, confirmed locally by temporarily reverting it,
running the test, and restoring the fix.
scripts/hooks/post-checkout decided whether .git/hooks/pre-commit was
"already wrapped" by grepping it for the literal string "Issue #1689",
a marker that only ever identified pre-commit-branch-guard-wrapper.
tools/git-hooks/pre-commit (branch guard chained into formatter
dispatch, #16923) never contained that string either, so the very
next checkout after installing it silently swapped it back for the
older wrapper, discarding the formatter dispatch and only coincidentally
keeping the branch guard (the wrapper carries its own). AC2 held only
inside #16923's own test fixture, which has no post-checkout hook
present, never in a real checkout with both hooks installed.

Recognition is now content-based instead of marker-based: post-checkout
diffs the installed hook against tools/git-hooks/pre-commit's own
tracked content (mod the flock block injected separately), the same
self-sync pattern it already uses to keep itself current. A fresh
clone, a genuinely stale hook, and a stale copy of an older version of
the template all converge on the current template through that one
comparison, so a future edit to tools/git-hooks/pre-commit needs
nothing kept in sync here. The legacy wrapper-based install/update path
is preserved unchanged for a checkout that predates #16923 (no
tools/git-hooks/pre-commit present at all), and a hook `pre-commit
install` genuinely generated itself is still never clobbered, matching
scripts/install-git-hooks.sh's own exception.

Adds repo_tests/git_hooks_post_checkout_precommit_sync_16923_test.py,
which drives the real post-checkout hook end-to-end against a real
throwaway git repository (never a mock), including a negative control
that reconstructs the pre-fix detection and proves it reproduces the
swap.
…uring the walk, not after (#16601)

auth_rbac_admin_guard_test.py's _python_files() was changed by the same
original PR to the identical os.walk()-with-pruning pattern as
collected_test_model.py's test_modules(), and had the same gap: no
existing test could distinguish in-walk pruning from a post-hoc filter,
since both produce the same final file list. Add the equivalent
negative-control test, spying on os.walk to assert a SKIP_DIR_PARTS
directory is never visited at all.
…16923)

Review on PR #16938 found the branch that upgrades .git/hooks/pre-commit to
the #16923 template did a bare overwrite with no backup, unlike the sibling
wrapper-swap branch (which backs up to pre-commit.pre-commit-framework).
Move the pre-existing hook aside to pre-commit.pre-formatter-dispatch before
overwriting, so a developer's hand-customized hook or the old #1689 wrapper
is never silently destroyed.

Adds the two tests review called out as missing: upgrading a real installed
old wrapper to the template, and backing up a hand-customized hook while
still replacing it.
…bare rev-parse; document finishing a pick of an old subject (#17029)
…e, and a blocking hook is a defect to fix or file (#17029)
@mrveiss
mrveiss merged commit 0e14efe into main Sep 19, 2026
69 of 77 checks passed
@mrveiss
mrveiss deleted the vehicle-v090-2026-09-18-ci-hooks branch September 19, 2026 10:13
@mrveiss mrveiss removed the land-next Landing set: CI capacity goes to these PRs first (owner direction 2026-09-18, #15397) label Sep 19, 2026
mrveiss added a commit that referenced this pull request Sep 19, 2026
…globs (#17124)

chromadb_bind_not_hardcoded_15317_test.py (landed via #17047) declares
*.service, *.service.j2 and docker/*.yml root-relative globs that
GLOB_DECLARED_UNCOVERED never recorded, flipping
glob_declared_reads_15900_test.py red on main -- a second, independent
combination red alongside #17124's own KB-visibility guard, folded into
this base-fix PR per the current queue rather than opened separately.

Same fix c0 wrote for #17116's vehicle (verified via
`git diff 2acfb8b^1 2acfb8b -- repo_tests/glob_declared_reads_15900_test.py`
against a fresh check that the test fails on current main without it);
applied here as an identical diff, confirmed via `git diff` against
that reference before committing.
mrveiss added a commit that referenced this pull request Sep 19, 2026
…globs (#17124)

chromadb_bind_not_hardcoded_15317_test.py (landed via #17047) declares
*.service, *.service.j2 and docker/*.yml root-relative globs that
GLOB_DECLARED_UNCOVERED never recorded, flipping
glob_declared_reads_15900_test.py red on main -- a second, independent
combination red alongside #17124's own KB-visibility guard, folded into
this base-fix PR per the current queue rather than opened separately.

Same fix c0 wrote for #17116's vehicle (verified via
`git diff 2acfb8b^1 2acfb8b -- repo_tests/glob_declared_reads_15900_test.py`
against a fresh check that the test fails on current main without it);
applied here as an identical diff, confirmed via `git diff` against
that reference before committing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant