Agent self-bootstrap: auto-open a scaffold PR instead of dumping onboarding on the human #304
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
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor#304
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Goal
When a repo fails validation on agent-authorable scaffolding, open a scaffold PR instead of (only) dumping an onboarding ticket on the human. Turns "repo not ready, you set it up" into "merge this one PR." The worked example, done by hand, is scenekids.com #12 — that PR is the literal target output.
Why
validate_repo_via_api(lib/repo-checks.sh) checks: CLAUDE.md, README, test signal, lint config, CI workflow, labels. Of these, CLAUDE.md + test script + lint config are agent-authorable — none is operator-only. Buthandle_onboarding_failureassumes "scaffolding only the operator can add" (its own comment) and files a human ticket. That assumption is wrong, and it's why ~8 repos sit with "repo not ready" tickets on the human's plate (scenekids was 5 tickets that collapsed to 1 PR once scaffolded).Design
In/around
handle_onboarding_failure(lib/repo-checks.sh:233), after parsing the gap report:- [ ] ...report lines: missing CLAUDE.md, test signal, lint config.package.jsonpresent, eleventy in deps/scripts). Bail to ticket-only on anything unrecognized.CLAUDE.md— conventions frompackage.json(name/description/scripts) + README + root listing. (v1 can template this deterministically; a model-written version is a nice v2.)package.jsontest—eleventy --dryrunfor 11ty (a clean build is the gate); generalize per build tool..markdownlint.json— lenient lint config.feat/agent-scaffold, marker-titled), assigned toFORGEJO_REVIEWER. Idempotent: skip if that branch/PR already exists (don't re-open every tick)..forgejo/workflows/is off-limits to the autonomous agent, so the scaffold PR can't include CI. (Repos that already have a CI workflow — like scenekids'deploy.yml— validate fully on the scaffold PR alone; repos with none keep a one-line "add CI" residual.)Acceptance
Notes
Implementation plan (locked after reading
lib/repo-checks.sh)Giving this its own focused pass — it edits the live onboarding path (
handle_onboarding_failure, repo-checks.sh:233) which self-deploys in ~1 min, so it gets the same careful/tested treatment the P0 (#307) got, not a wedge between other work.Shape: a new
lib/scaffold.sh(pure + impure split for testability), called fromhandle_onboarding_failurebefore the ticket step. Additive and fully guarded: any failure or unrecognized stack falls through to today's ticket-filing unchanged (blast radius = worst case, behaves exactly as now).Pure functions (unit-tested in
bin/test-scaffold.sh):scaffold_parse_gaps <report>— from the- [ ] <name> -- <hint>lines, return which agent-authorable gaps are open: CLAUDE.md, test signal, lint config. (README/labels/CI are NOT auto-scaffolded — CI is off-limits.forgejo/workflows/.)scaffold_detect_stack— Node + Eleventy (package.json present +eleventyin deps/scripts). Bail (empty) on anything else → ticket-only.scaffold_gen_claude_md/scaffold_gen_markdownlint/scaffold_add_test_script— deterministic content frompackage.json(name/scripts) + README. Test signal for 11ty = a\"test\": \"eleventy --dryrun\"-style script (clean build is the gate).Impure (guarded, integration):
feat/agent-scaffoldbranch or its PR already exists (don't re-open every tick).feat/agent-scaffoldvia the contents API (no clone), one PUT each;package.jsonis a read-jq-write update with its blob sha.FORGEJO_REVIEWER; narrow the onboarding ticket to "agent scaffolded CLAUDE.md/test/lint in PR #N — only the CI workflow is left for you."Acceptance: a new unvalidated 11ty repo gets an auto scaffold PR matching scenekids #12 (minus CI); merging it validates the repo (if CI already exists) or leaves only "add CI"; idempotent; never auto-lands (human merge gate). Main live beneficiary: parsley (certifiedtradejobs is a slow-burn, not urgent).
PR next.
Done — implemented and merged in #311 (auto-scaffold: CLAUDE.md / test / lint on an idempotent, guarded, human-gated scaffold PR; onboarding ticket narrowed to the CI residual). Closing. I'll watch the next ticks for the scaffold PR to actually open on parsley and confirm the live behavior; if it doesn't fire, that resurfaces as its own signal.