parallax#1 was the real-world evidence: infra#179's branch-writability stall (>40s observed) blew past the tool's 5s budget, substitution ran zero files, and the repo shipped genuinely broken (go.mod still read `module __MODULE_PATH__`) — recoverable only via a manual clone/sed/git-mv/push. Adds `resume: bool`. When true, skips template lookup and repo generation entirely — the destination must already exist — and jumps straight to the tree-walk substitution. This is safe to re-invoke repeatedly because substituteEntry already compares against the branch's CURRENT state on every call (GetTree is re-fetched fresh each time): a file already fixed in a prior partial pass shows up already-correct or already-renamed and is a no-op. So the actual blocker to resumability was purely the "destination must NOT exist" guard on the create path — flipped it for resume, no change needed to the substitution logic itself. Consequences of resume existing: - infra179FinalizeMessage (#46) now points at the concrete recovery — "call this tool again with resume=true" — instead of manual clone/sed guidance. - "no placeholders substituted" only loud-fails on a FRESH create; on resume, finding nothing left to do is the expected steady state (success). - dispatch_allow injection (#43) is now idempotent (read-before-write, update with sha if present-but-different, skip if already correct) so a resumed call with dispatch_allow=true doesn't error re-creating a path that already exists (#51's root cause). - #51's other ask: dispatch_allow failures now land in their own dispatch_allow_failure field, never conflated with substitution's partial_failure — the two can independently succeed/fail. Tests: resume with no destination (error, names "nothing to resume"), resume continuing a partial substitution (asserts /generate is never re-called, only the still-wrong file is rewritten), resume when already fully done (success, not the fresh-create loud-fail), dispatch_allow idempotent re-injection (two-phase test capturing the real written content, no test-visible knowledge of the internal constant), and dispatch_allow_failure as a distinct field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,12 +6,13 @@ import (
|
||||
)
|
||||
|
||||
// #46: the infra#179 finalize guidance must not point at a non-existent command
|
||||
// (`hyperguild new-project` was never built). It should name the real remaining
|
||||
// work — substituting the placeholders — so the caller isn't sent to a dead end.
|
||||
// (`hyperguild new-project` was never built). #50 superseded the original
|
||||
// manual-editing guidance with a concrete, real recovery: re-invoke this same
|
||||
// tool with resume=true.
|
||||
func TestInfra179FinalizeMessage(t *testing.T) {
|
||||
msg := infra179FinalizeMessage("main", 5, 2, "branch does not exist")
|
||||
|
||||
for _, want := range []string{"infra#179", "__PROJECT_NAME__", "__MODULE_PATH__", "branch does not exist"} {
|
||||
for _, want := range []string{"infra#179", "resume=true", "branch does not exist"} {
|
||||
if !strings.Contains(msg, want) {
|
||||
t.Errorf("message missing %q\ngot: %s", want, msg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user