Development record
The ahoy history registry (~/.abcd/history/index.json and its lock) is created and written through a symlinked ~/.abcd: historyRoot joins the home directory and withHistoryLock and bootstrapHistory call os.MkdirAll, which follows the link, so on a machine whose ~/.abcd is symlinked into a dotfiles checkout the registry of every managed repository, remote URLs included, lands in that repository. Its sibling stores refuse a symlinked level through their create-then-prove seam (transcripts, voyage, lab, inbox, runs use fsutil.EnsureRealDir/EnsureRealDirAll/IsRealDir), and every file abcd trusts in ~/.abcd refuses the link through fsutil.HomeScopeLink (iss-2609281017573862, iss-2609260958587561). The registry is a store, not a trust declaration, and refusing it changes ahoy install's registration on such machines, so it was left for its own ruling: route it through fsutil.EnsureRealDirAll on ".abcd/history" below the home directory and say what the install does when the registry cannot be created.
The ahoy history registry (~/.abcd/history/index.json and its lock) is created and written through a symlinked ~/.abcd: historyRoot joins the home directory and withHistoryLock and bootstrapHistory call os.MkdirAll, which follows the link, so on a machine whose ~/.abcd is symlinked into a dotfiles checkout the registry of every managed repository, remote URLs included, lands in that repository. Its sibling stores refuse a symlinked level through their create-then-prove seam (transcripts, voyage, lab, inbox, runs use fsutil.EnsureRealDir/EnsureRealDirAll/IsRealDir), and every file abcd trusts in ~/.abcd refuses the link through fsutil.HomeScopeLink (iss-2609281017573862, iss-2609260958587561). The registry is a store, not a trust declaration, and refusing it changes ahoy install's registration on such machines, so it was left for its own ruling: route it through fsutil.EnsureRealDirAll on ".abcd/history" below the home directory and say what the install does when the registry cannot be created.
Grounds
- pursued: with ~/.abcd a symlink to an empty directory, ahoy install must leave that directory empty and carry a note naming the skipped registration, the symlinked ~/.abcd and the repair (TestInstallRegistersNothingThroughASymlinkedAbcdHome, which failed before the fix with the target holding history/), and a home that is itself a link must still register (TestInstallRegistersThroughAHomeThatIsItselfALink); what would show it wrong is any file appearing behind the link after an install or a detect, or a linked home losing its registration.
Frontmatter
| id | iss-2609281129171021 |
|---|---|
| type | issue |
| lifecycle | resolved |
| severity | minor |
.abcd/work/issues/resolved/iss-2609281129171021-the-ahoy-history-registry-abcd-history.md
open on GitHub ↗ · commit history ↗
mentions2
- iss-2609260958587561The machine credential store is less strict than its sibling the rules loader about ~/.abcd: credential.SetMachine writes credentials.json and its lock through a ~/.abcd symlinked to an existing directory (a dotfiles checkout), where the rules loader refuses rules.json behind a symlinked ~/.abcd, so a secret can land in a dotfiles repository; and the store's lock files are created 0644 while a pre-existing 0755 ~/.abcd is never tightened, so any local user who can open a lock (a read-only descriptor holds LOCK_EX) can stall every connect for its five-second wait.
- iss-2609281017573862The ~/.abcd/path-entry and cache-attestation readers do not refuse a symlinked ~/.abcd, unlike the rules loader: fsutil.ReadDeclaration lstats the FILE (regular, this uid, not group- or other-writable, O_NOFOLLOW re-open) but follows a symlinked parent directory, and the hook shims' find -maxdepth 0 -type f -user ... ! -perm -0020 ! -perm -0002 check likewise follows the parent. The two readers agree with each other, but AGENTS.md states the rules.json rule as refused behind a symlinked ~/.abcd, so a dotfiles-symlinked ~/.abcd hosts a path-entry record that vouches for which binary the hooks run while the rules loader in the same home would refuse its rules.json. Found by review-drainH (LOW, pre-existing, shared with cache-attestation); related to iss-2609260958587561 (the credential store's copy of the same gap) but not covered by it.