feat(factory): wire the software factory — gate config, Action, issue template - #654
Merged
Merged
Conversation
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
dmarcheck | 1d9b108 | Aug 05 2026, 12:02 PM |
… template Adopts the autonomous issue→fix→merge loop from schmug/shipofclaudius. WIRED, NOT ARMED: `secrets.FACTORY_GH_TOKEN` does not exist, so both write jobs no-op with a clear message rather than half-running. Nothing can auto-merge today. - .factory/gate.json — the deterministic merge gate's config, read from `main` on every run and never from the PR. The denylist mirrors .github/CODEOWNERS and adds the security/money paths that are not currently code-owned: src/auth/**, src/account/**, src/billing/**, src/webhooks/**, src/rate-limit-do.ts, mta-sts-worker/**, scripts/routine-gate/**. `.factory/**`, `.github/workflows/**` and CODEOWNERS are added automatically by the gate and cannot be removed here — a PR must never widen the rules it is judged by. requireFixtureEvidence stays false until a reproduction harness exists. - .github/workflows/factory.yml — killswitch → advance → land. The land job runs NO model at all: it is `gh` plus a zero-dependency Node program, so injected issue text has nothing to act on. It checks out the BASE ref, never the PR head, which is what makes the `pull_request_target` trigger safe. Action SHAs match the existing pins so the action-pin integrity check passes. - .github/ISSUE_TEMPLATE/ — the repo had none. The bug form makes the ```scope block required, which is the gate's single most common escalation cause. Verified end to end against this config with the real gate binary: exit 0 a clean in-scope PR exit 2 real PR #653 (dependabot: unallowlisted author, no fix-verified, no Closes #N, mta-sts-worker/** risk path, 382 lines > 250, no scope block) exit 2 self-editing .factory/**, .github/workflows/**, CODEOWNERS exit 2 touching src/analyzers/**, src/shared/scoring.ts, src/billing/** exit 2 scope drift, oversize, pending required check, BLOCKED merge state Before arming, see .factory/README.md: the write token must be a DISTINCT IDENTITY from @schmug (GitHub forbids self-approval, so a code-owner token can never satisfy require_code_owner_review on main-protection — #299), and this repo still has no rollback path for a bad production deploy. Signed-off-by: schmug <38227427+schmug@users.noreply.github.com>
…y runs
GitHub runs `run:` blocks as `bash -e {0}`, and `set -uo pipefail` does NOT clear
that inherited `-e`. So when the gate exited 2 — the NORMAL escalate path — the
step aborted before the exit code was captured, and the audit-comment and escalate
steps were then skipped by their implicit `success()`.
Net effect: the gate would post no verdict table and apply no `needs-you` label
exactly when it refused a PR, and a gate that genuinely crashed (exit 1) would look
identical to a normal refusal. The merge path was unaffected — it worked when the
gate said yes and silently did nothing when it said no.
`|| code=$?" now captures the code, and the two follow-on steps run under
`always()` so a PR is never left with no explanation of why it did not land.
Found by an adversarial review of the upstream branch; fixed in the shipofclaudius
template in the same pass.
Signed-off-by: schmug <38227427+schmug@users.noreply.github.com>
schmug
force-pushed
the
feat/software-factory
branch
from
August 5, 2026 10:54
37fb211 to
8aad2df
Compare
This was referenced Aug 5, 2026
Open
Two defects that would each have escalated 100% of factory PRs: 1. factory-issue-fix opens a DRAFT, a draft reports mergeStateStatus=DRAFT, and gate condition 8 rejects DRAFT — with nothing converting it. The land job now readies the PR before gating (safe, reversible, and only after a human applied `fix-verified`, which is the approval to land) and converts it back to a draft if the gate refuses. 2. The issue template used `render: text`, which GitHub emits as a \`\`\`text fence, while the gate's extractScopeGlobs matches only \`\`\`scope. Every issue filed through it would have failed condition 7. The template now pre-fills a literal \`\`\`scope fence, and applies `factory`+`needs-repro` so a filed bug actually enters the queue. Also wires the optional --evidence passthrough and documents that condition 9's red/green booleans must come from CI, never from the fix agent's self-report. Found by an independent critical-path review; both confirmed by direct test before fixing. Fixed upstream in the shipofclaudius template in the same pass. Signed-off-by: schmug <38227427+schmug@users.noreply.github.com>
schmug
added a commit
that referenced
this pull request
Aug 6, 2026
Closes the gap between .github/CODEOWNERS and the software factory's risk denylist (.factory/gate.json, wired in #654): src/auth/, src/billing/, src/webhooks/, src/rate-limit-do.ts, mta-sts-worker/, and scripts/routine-gate/ were flagged as security/money-sensitive there but CODEOWNERS hadn't caught up. src/account/ was already covered. Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopts the autonomous issue→fix→merge loop from schmug/shipofclaudius#63.
secrets.FACTORY_GH_TOKENdoes not exist, so theadvanceandlandjobs no-op with a clear notice rather than half-running. Nothing can auto-merge today, and three independent things still gate that — see.factory/README.md:fix-verifiedis human-minted.requireFixtureEvidence: falsebecause this repo has no reproduction harness, so the reproduce phase has no mechanical definition of done.require_code_owner_reviewonmain-protection. That's claude-routines bot-identity split: run overnight routines as a non-admin GitHub identity #299.What's here
.factory/gate.json— the merge gate's config, read frommainon every run and never from the PR. The denylist mirrors.github/CODEOWNERSand adds the security/money paths that aren't currently code-owned:src/auth/**,src/account/**,src/billing/**,src/webhooks/**,src/rate-limit-do.ts,mta-sts-worker/**,scripts/routine-gate/**..factory/**,.github/workflows/**and CODEOWNERS are added automatically by the gate and cannot be removed by this file — a PR must never be able to widen the rules it's judged by..github/workflows/factory.yml—killswitch→advance→land.The
landjob runs no model at all: it'sghplus a zero-dependency Node program, so text injected into a public issue body has nothing to act on — an injected instruction cannot move a<=comparison. It checks out the base ref, never the PR head, which is what makes thepull_request_targettrigger safe; there's nonpm ciand no build step in it.workflow_dispatchinputs are allowlist-validated before they reach the driver's prompt, and all GitHub context flows throughenv:, never interpolated intorun:bodies. Action SHAs match the existing pins so the action-pin integrity check passes..github/ISSUE_TEMPLATE/— the repo had none at all. The bug form makes the```scopeblock required, which is the gate's single most common escalation cause.Verified end to end
Ran the real gate binary against this exact
.factory/gate.json:fix-verified, noCloses #N,mta-sts-worker/**risk path, 382 lines > 250, no scope block.factory/**/.github/workflows/**/ CODEOWNERSno_risk_pathssrc/analyzers/**·src/shared/scoring.ts·src/billing/**no_risk_pathsBLOCKEDmerge stateThat exercise also caught a real bug in the gate package (
gh apitakes no-R, which would have failedci_greenon every PR forever) — fixed upstream in shipofclaudius#63 before this PR was opened.Settled empirically while wiring this
.github/CODEOWNERSis enforcing, not advisory. Themain-protectionruleset isactivewithrequire_code_owner_review: true,required_approving_review_count: 0, one required check (check), and no bypass actors.CLAUDE.mdis correct;MAINTAINERS.md,docs/OSPS-DEVIATIONS.mdand.claude/workflows/pr-triage.jsall say advisory and are wrong. Filed separately rather than mixed into this PR.Not in this PR
The reproduction harness, the coverage floor, the rollback lever, the bot identity, and the
src/index.tsbottleneck are filed as follow-up issues.🤖 Generated with Claude Code