3aa1a74b ยท zzmq.dev@gmail.com/zz
Commit
3aa1a74b000cacd82071c41fb7bad7e216c8ef4c
Add `zz ladder sync`; fix directory-rung anchoring bugs it exposed zz ladder sync <local-repo> <owner/repo>: the ongoing half of onboarding a real GitHub repo, where zz ladder build + zz ladder push was the one-time half. Fetches the latest commits, re-summarizes only the files that actually changed since the last sync (describeOneFile, extracted out of walkFileTree's own per-file loop rather than a full re-walk), and re-runs the issue/PR/release/contributor/dependency onboarding functions directly -- they already skip anything already present, so calling them again is naturally incremental with no extra bookkeeping needed for any of those five. Known limitation: a brand-new file still gets registered under the repo root rather than nested under its real parent directory (documented in the file's own header) -- content is still correctly stored and findable, just not as cleanly placed in the Ladder tree view until a full rebuild. Writing this surfaced three real, pre-existing bugs in the LOCAL Ladder's own directory-rung handling, all in engine/ladderNotes.ts, none introduced by this change but never exercised until something re-touched an already-onboarded repo's files: 1. A directory anchored to its own tree sha, which changes whenever ANY file anywhere under it changes -- confirmed live, the first real sync run orphaned every directory note with a changed file underneath, same failure mode "_repo" itself already avoids by anchoring to the root commit instead. Fixed the same way. 2. That fix alone collided every directory (and "_repo" itself) onto the exact same git-notes (ref, oid) slot, since they'd now share both the oid (root commit) AND the ref ("code") -- confirmed live, every directory read back as "_repo"'s own content, each write clobbering whichever was there before. Fixed by giving directories their own ref, same shape ask/contributor/dependency paths already get. 3. A directory's real path is hierarchical (app, app/agent, ...), and git's loose-ref storage is a real filesystem tree where one ref can't be a path-prefix of another -- confirmed live ("ENOTDIR") the moment a repo had any directory with a subdirectory of its own. Fixed by flattening "/" before it reaches the ref name. Also fixed in ladder-build.ts: a --force rebuild of an already-onboarded repo rewrote "_repo"'s own note with a fresh, empty children array in the same batch as the file-tree's top-level items, silently dropping every ask/release/contributor/dependency path already appended to it since the first build (their own notes were untouched -- just unreachable from the root). Only the very first build writes "_repo" itself now; every later rebuild appends the fresh file-tree items without touching what's already there. And a real correctness bug in engine/ingest.ts, unrelated to any of the above but found while in this code: every file rung's own commit source recorded the literal string "HEAD" as its ref instead of a real commit sha (fileCommitSummary now returns the actual oid). Also fixes sanitizeRefSegment (shared by ask/contributor/dependency paths too) to handle a path component starting with "." -- a real top-level ".zz" directory hit this live ("would be an invalid git reference"), and dotfiles/dotdirs are completely ordinary in a real repo. Verified end to end against the real zzmq-dev/zz repo after all of the above: a clean build reaches 239 real anchors (was silently dropping to 11-93 under each successive bug), app and _repo read back as genuinely distinct content, and a full rebuild no longer loses anything already onboarded.
Troy Howard <thoward37@gmail.com> -- 2026-10-14T01:28:37.000Z