feat(onboarding): auto-scaffold agent-authorable gaps into a PR (igor#304) #311
No reviewers
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
2 participants
Notifications
Total time spent: 1 minute 45 seconds
Due date
igor
1 minute 45 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor!311
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/304-auto-scaffold"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What this does
When a repo fails onboarding on scaffolding the agent can author, open a scaffold PR instead of (only) filing a human ticket. Worked example, done by hand: scenekids #12 — that PR is the literal target output (minus the CI file).
How
New functions in
lib/repo-checks.sh, called fromhandle_onboarding_failurebefore the ticket step:bin/test-scaffold.sh):scaffold_parse_gaps(which of CLAUDE.md / test / lint are open, from the- [ ]checklist lines),scaffold_detect_stack(v1: Node + Eleventy), and the generators (scaffold_claude_md,scaffold_markdownlint,scaffold_test_script,scaffold_pr_body).scaffold_try_open_pr— idempotency (reuse an open scaffold PR; skip a leftover branch), createagent-scaffoldoff the default branch, PUT the files via the contents API (no clone;package.jsonis a read-jq-write), open the PR.On success the onboarding ticket is narrowed to "scaffolded in PR #N — only CI is left for you."
Safety
.forgejo/workflows/) stays a human residual — off-limits to the agent.Test plan
bin/test-scaffold.sh— 18 checks on the pure functions (gap parse, stack detect, test-script, generated content)bin/check-sync.shgreen (picks up the new test)bash -n lib/repo-checks.shRefs igor#304.
🤖 Review —
COMMENT(automated)CI for
84adba06: successAdds an auto-scaffold path to onboarding: when a repo fails onboarding on agent-authorable gaps (CLAUDE.md / test script / lint config), the agent opens a guarded, unassigned scaffold PR and narrows the onboarding ticket to the human residual (CI). Well-scoped (~250 lines), additive, CI green, and the pure functions are unit-tested. My reservations are minor but enough to keep a human in the loop rather than rubber-stamp — this feature autonomously opens PRs on external repos and its risky part is untested.
Findings
Checklist count is off by one (honesty). The description says
bin/test-scaffold.sh — 18 checks, but I count 17eq/has/noassertions in the file (3 gap-flag + 1 empty + 1 no-false + 4 stack + 2 test-script + 1 markdownlint + 3 claude_md + 2 pr-body). The test file is real and substantive, so this is a miscount rather than fabricated work — but the human trusts the checklist, so fix the number to 17.The impure orchestrator
scaffold_try_open_pris untested and validated only in production. The test plan's last (unchecked) item is essentially "watch it run against parsley/certifiedtradejobs after merge." This is the highest-risk code in the PR (branch creation, contents-API PUTs, PR open) and it depends on several helpers not in the diff (forgejo_repo_get_file,forgejo_find_pr_by_head,forgejo_open_pr,_fj,log).bash -nwon't catch a wrong helper name/signature. Worth a human confirming those helpers exist and are called correctly. Not a contract violation (unit-testing live API calls isn't feasible without mocks), but a reason not to auto-approve.A leftover scaffold branch permanently blocks retry. If the branch is created (
POST /branches) but every subsequent PUT fails (wrote=0), the function returns 0 leaving an orphanagent-scaffoldbranch and no PR. On the next tick the leftover-branch guard (_fj GET /branches/agent-scaffold→ return 0) makes it skip scaffolding forever until a human deletes the branch. Falls back to ticket-only (pre-#304 behavior), so not fatal, but a transient PUT failure is sticky. Consider deleting the branch whenwrote=0.PR body can claim files that weren't actually written.
scaffold_pr_bodyis generated fromgaps, not from which PUTs succeeded. On a partial failure (e.g. CLAUDE.md PUT fails but lint succeeds), the opened PR still listsCLAUDE.mdas added. Cosmetic — the human reviews the PR — but the body could mislead.base64 -w0is GNU-specific. Fine on a Linux agent (the test skips ifbase64is absent), just noting it would break on BSD/macOSbase64.Nits / non-blocking
printf '# %s\n\n%s\n\n' "$name" "$desc"is safe against%/\in the description since both are%sargs, not format strings — good. The escaped backticks in the unquotedhandle_onboarding_failureheredoc are also correct..forgejo/workflows//.github/workflows/changes; those are only referenced as text. Good — CI stays operator-managed.jq --arg, content is base64-encoded, and interpolated URL segments (repo, hardcoded paths) aren't user-controlled.Net: correct-looking and safely guarded, but fix the 17-vs-18 count and let a human weigh the untested live-API orchestrator and the sticky-leftover-branch behavior before this lands.
Independent review by the harness on
claude-opus-4-8. The human reviewer is requested once Igor has reviewed; a human still merges.