Skip to content

chore(repo): name the vault repo after what it holds, not the engine - #928

Open
wshallwshall wants to merge 4 commits into
mainfrom
claude/messagefoundry-vault-rename-f3a800
Open

chore(repo): name the vault repo after what it holds, not the engine#928
wshallwshall wants to merge 4 commits into
mainfrom
claude/messagefoundry-vault-rename-f3a800

Conversation

@wshallwshall

@wshallwshall wshallwshall commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

What changed

wshallwshall/MessageFoundry is now wshallwshall/MessageFoundry-vault, and its
GitHub description now names what it holds instead of describing the engine.

It shared a name AND a description with the public engine repo
MEFORORG/MessageFoundry, so two rows in gh repo list read as one project.

before after
name wshallwshall/MessageFoundry wshallwshall/MessageFoundry-vault
description "Lightweight code-first HL7 v2 integration engine (Python)" "Private records vault for MessageFoundry. Holds the ASVS scorecard, role playbooks, and session handoffs. The engine itself is MEFORORG/MessageFoundry."

Three commits, one layer each: the engine-side sweep of the 13 old-slug
references across 8 files, a guard so the tree stays swept, and BACKLOG #1463 for
a gap the work uncovered.

Why the rename disabled nothing

Checked BEFORE renaming. The 9 hardcoded old slugs in the vault sit in cla.yml
and release.yml, both disabled_manually. Every ACTIVE vault workflow either
checks out MEFORORG/MessageFoundry explicitly or reads the github.repository
context, which follows a rename. PyPI Trusted Publishing is bound to
MEFORORG/MessageFoundry, not to the renamed repo.

Two sites are not a plain substitution

  • scripts/hooks/durability_push.sh documents git remote -v output, so its
    remote table had to match the URL the remote now carries. Both local remotes
    were repointed and verified with git ls-remote against the new URL.
  • docs/LEDGER-GATE.md quotes the URL a REFLOG literally recorded. That string
    stays as recorded, with the current name named beside it. Rewriting it would
    make the doc disagree with the artifact the section is reading.

The guard, and why a rename needs one

GitHub keeps a permanent redirect from the old path, and their documentation
names exactly one way to drop it: create a new repository claiming the old name.
That would put the engine's name back in the account listing, so the redirect
stays. The cost is that a stale reference does not fail. It quietly answers,
correctly, about the vault, under a name that is gone.

scripts/quality/stale_repo_slug_check.py greps the tracked tree and fails on the
pre-rename slug, wired as a pre-commit hook with always_run and
pass_filenames: false.

Two design points worth a reviewer's attention:

  • It never writes the old slug as a literal. The needle is assembled from
    parts. Written whole, the guard and its test would each violate the rule they
    enforce, and exempting the guard from itself would make it the one place a real
    stale reference can hide. The accepted cost: grepping the tree for the old slug
    will not find the guard.
  • The one exemption is pinned to a count, not a path. docs/LEDGER-GATE.md
    may hold exactly 1. A path-level exemption would blind the guard to every
    future stale reference in that same file, so drift in either direction fails.

A clean-tree arm proves nothing on its own, so the 12 tests plant violations and
require the guard to see them: a bare slug, a bare slug hiding on a line that also
carries the current one, the pin drifting up, the pin drifting down, an untracked
file staying out of scope, and two git-failure arms, because "no matches" and "the
search never ran" are the same empty output. The missing-root arm found a real
gap and the guard was fixed rather than the test
-- an OSError was reaching the
caller as a traceback instead of exit 2.

End-to-end control run by hand: a planted probe made the WIRED hook exit 1 naming
the site, and removing the probe returned Passed.

The guard then refused this PR's own backlog filing, which quoted the drift
diff verbatim. That is the design working: it cannot tell quoted evidence from a
live reference. docs/BACKLOG.md was deliberately NOT given a count exemption --
23,000 lines growing daily would make the pin a reflex rather than a decision --
so the item describes the diff instead and records why.

BACKLOG #1463, filed here

install-git-hooks.ps1:436 lays scripts/hooks/durability_push.sh down as
.git/hooks/post-commit verbatim, and every instrument that could report it
drifting tests a MARKER rather than content:

  • install-git-hooks.ps1:162 sets $durInstalled by matching a marker the
    installer itself writes in, so it answers "is this ours" and never "is this
    current". :164 prints the presence string off it, with no hash.
  • The parity test tests/test_installed_coord_hooks.py:353 is parametrized at
    :352 over PAYLOADS, parsed at :231 from the installer's own
    $payloads = @("claim_check.py", "push_guard.py"). The test's scope IS the
    installer's scope by construction, and it inherits the gap.
  • tests/test_durability_hook_provenance.py does drive a post-commit hook. Its
    docstring at :32 says the fixtures never touch the real one -- correct for a
    provenance test, and it means the file whose name most suggests coverage here
    provides none.

commit-msg and pre-push are thin shims that locate a hashed .py payload, so
a marker is enough for them. post-commit has no payload: the body IS the
implementation, and nothing hashes it.

This was found the hard way -- a direct diff was the only thing that reported it,
while -Status printed IN SYNC hash pairs for both payloads and, for the
drifted file, the word INSTALLED.

Checks run

check result
ruff check + ruff format --check clean
mypy strict on messagefoundry 268 files, no issues
mypy --strict on both new files no issues
bandit passed, after the repo's usual nosec for a fixed-argv read-only git call
scripts/docs/backlog_status_check.py 671 items, each declaring exactly one status
parse_items on the new item #1463 parses as open
pytest guard suite 12 passed
pytest test_tooling_partition (pins the new manifest entry) passed
pytest test_required_workflow_state, test_durability_hook_provenance, test_coord_alloc_strand_sweep 40 passed
all pre-commit hooks, all three commits passed

Full pytest was not run. Hosted-runner legs (for example
windows-service-smoke) must be read from CI after this process exits.

Two things this PR does not do

The installed hook still needs a manual reinstall. .git/hooks/post-commit
carries the pre-rename remote table. Fixing it means writing into the shared
.git of the primary checkout, which 38 worktrees share, so it is the owner's
hand:

pwsh -NoProfile -File scripts/coord/install-git-hooks.ps1

Both payloads already report IN SYNC and this branch is 0 commits behind
origin/main, so the reinstall cannot downgrade anything -- the only content
change is the two comment lines.

A stale measurement was left as recorded. docs/adr/0160-*.md line 455 says
the vault reports "every workflow except ASVS scorecard" as
disabled_manually. Measured today: 6 are active (ASVS scorecard, ASVS verifier
drift, Branch leak scan, SDS citations, SDS standard freshness, threat-model
drift) plus Dependabot Updates and Dependency Graph. It is a dated 2026-08-06
measurement inside a "measurements that produced that decision" block, so
correcting it is its own change, not a side effect of this one.

Five live peer sessions were mailed before the shared private remote URL
changed under them.

🤖 Generated with Claude Code

wshallwshall and others added 4 commits September 5, 2026 18:59
wshallwshall/MessageFoundry shared a name AND a description with the public
engine repo MEFORORG/MessageFoundry, so two rows in `gh repo list` read as one
project and sessions kept confusing them. Renamed it to
wshallwshall/MessageFoundry-vault, and rewrote its description to name the ASVS
scorecard, role playbooks and handoffs it actually holds.

Checked BEFORE renaming that no ACTIVE vault workflow gates on the old slug: the
9 hardcoded occurrences sit in cla.yml and release.yml, both disabled_manually.
Every active workflow either checks out MEFORORG/MessageFoundry explicitly or
reads the github.repository context, which follows a rename.

This commit carries the engine side, the 13 old-slug references across 8 files.
Two sites are not a plain substitution:

  * scripts/hooks/durability_push.sh documents `git remote -v` output, so its
    remote table had to match the URL the remote now carries. Both local remotes
    were repointed and verified with `git ls-remote`.
  * docs/LEDGER-GATE.md quotes the URL a REFLOG literally recorded. That string
    stays as recorded, with the current name named beside it. Rewriting it would
    make the doc disagree with the artifact it is reading.

Checks: ruff check and ruff format --check on the two touched Python files,
clean. mypy strict on messagefoundry, 268 files, no issues.
scripts/docs/backlog_status_check.py, 670 items OK. pytest on
test_required_workflow_state, test_durability_hook_provenance and
test_coord_alloc_strand_sweep, 40 passed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The vault rename left a PERMANENT GitHub redirect, and GitHub's documentation
names exactly one way to drop one: create a new repository claiming the old
name. That would put the engine's name back in the account listing, so the
redirect stays. The cost of keeping it is that a stale reference does not fail.
It quietly answers, correctly, about the vault, under a name that is gone, and
nothing anywhere reports it.

scripts/quality/stale_repo_slug_check.py greps the TRACKED tree and fails on the
pre-rename slug. Wired as a pre-commit hook with always_run and pass_filenames
false, so a changed-file list cannot narrow what it looked at while still
reporting clean.

Two design points worth a reviewer's attention:

  * IT NEVER WRITES THE OLD SLUG AS A LITERAL. The needle is assembled from
    parts. Written whole, the guard and its test would each violate the rule
    they enforce, and exempting the guard from itself would make it the one
    place a real stale reference can hide.
  * THE ONE EXEMPTION IS PINNED TO A COUNT, NOT A PATH. docs/LEDGER-GATE.md
    quotes a URL a reflog literally recorded. A path-level exemption would blind
    the guard to every FUTURE stale reference in that same file, so the pin is
    exact and drift in either direction fails.

A clean-tree arm proves nothing on its own, so the tests plant violations and
require the guard to see them: a bare slug, a bare slug hiding on a line that
also carries the current one, the pin drifting up, the pin drifting down, an
untracked file staying out of scope, and two git-failure arms, because "no
matches" and "the search never ran" are the same empty output. The missing-root
arm found a real gap and the GUARD was fixed rather than the test: an OSError
was reaching the caller as a traceback instead of exit 2.

End-to-end control run by hand: a planted probe made the WIRED hook exit 1 with
the site named, and removing the probe returned Passed.

Checks: ruff check and ruff format, clean. mypy --strict on both new files, no
issues. bandit, passed after the repo's usual nosec for a fixed-argv read-only
git call. pytest on tests/test_stale_repo_slug_check.py, 12 passed, and
tests/test_tooling_partition.py, which pins the new manifest entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…check

Found while landing the vault rename. install-git-hooks.ps1 lays
scripts/hooks/durability_push.sh down as .git/hooks/post-commit VERBATIM, and
every instrument that could report it drifting tests a MARKER instead of the
content. The two .py payloads installed beside it are content-hashed in both
directions. This one IS the implementation, and nothing hashes it.

Measured 2026-09-05: the source was updated with the rename, the installed copy
was not, and a direct diff was the only thing that said so. -Status printed a
hash pair for both payloads and, for the drifted file, the word INSTALLED plus a
correct armed-remote line read from live git config. The only green-looking row
on the screen was the wrong one.

The drift found was comment-only, and that is not the point. A body change would
have hidden identically, and in this file the comment IS the safety work: it is
what a human reads before choosing a remote, and git push with no remote named
resolves to the PUBLIC one.

Scope was drawn deliberately and the test inherits it by construction.
install-git-hooks.ps1:82 describes $payloads as the .py payloads for -Status to
audit, and tests/test_installed_coord_hooks.py:231 parses that same declaration,
so the test's scope IS the installer's scope. tests/test_durability_hook_
provenance.py does drive a post-commit hook, and its docstring at :32 says the
fixtures never touch the real one -- correct for a provenance test, and it means
the file whose name most suggests coverage here provides none.

The drift diff is DESCRIBED in the item rather than pasted, and the item records
why: the stale-slug guard in this same PR refuses a verbatim quotation and cannot
tell quoted evidence from a live reference. docs/BACKLOG.md was deliberately NOT
given a count exemption -- 23,000 lines growing daily would make that pin a
reflex rather than a decision, which is the one property it exists to buy.

The number was allocated with scripts/coord/alloc.ps1, not grepped.

Checks: scripts/docs/backlog_status_check.py, 671 items each declaring exactly
one status. parse_items confirms #1463 parses as open. The new stale-slug guard
exits 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ne session

The item cited "38 worktrees share these hooks" as a bare fact. It was true when
read and is now 18, measured after the owner reinstalled the hooks. A decaying
figure recorded without its as-of time is unusable rather than current, and this
one sat in a durable ledger entry.

The instruments are not in disagreement, which was the first thing checked:
install-git-hooks.ps1:490 and :300 both count `git worktree list` with the
identical expression, and a direct `git worktree list` agrees with them. The
population itself moved as sibling sessions pruned worktrees -- 43 at session
start, 38 an hour later, 18 after the reinstall.

The argument the figure supported needs only "more than one", so it is now stated
without a number and the readings are recorded beside it with their date.

Verified in passing, and it is the reason this session read the count at all: the
reinstall cleared the drift #1463 was filed about. The installed post-commit hook
is now byte-identical to the committed source, checked by direct diff, because
the installer prints no hash for that file -- which is the item.

Checks: scripts/docs/backlog_status_check.py, 671 items each declaring exactly
one status. The stale-slug guard exits 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the ci-red A required check went red. Attribute it before retrying. label Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci-red A required check went red. Attribute it before retrying.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant