@jnyross/code-factory 1.1.1 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,6 +7,7 @@ This template implements the full pattern:
7
7
  - risk-policy gate before expensive CI fanout
8
8
  - current-head SHA review discipline
9
9
  - canonical rerun comment dedupe
10
+ - optional deterministic remediation agent loop
10
11
  - bot-only thread auto-resolve after clean rerun
11
12
  - browser evidence verification for UI/user-flow changes
12
13
  - incident -> harness-gap loop with weekly metrics
@@ -17,8 +18,10 @@ All control-plane policy lives in `ARCHITECTURE.yaml` under `control_plane`:
17
18
  - `mergePolicy`
18
19
  - `docsDriftRules`
19
20
  - `reviewAgent`
21
+ - `remediationAgent`
20
22
  - `browserEvidence`
21
23
  - `harnessGapLoop`
24
+ - `branchProtection`
22
25
 
23
26
  ## Workflow Order
24
27
  `Control Plane` workflow (`.github/workflows/preflight.yml`) runs jobs in this order:
@@ -30,6 +33,8 @@ For `high` tier changes, the gate auto-applies the PR label `high-risk`.
30
33
 
31
34
  `Code Review Agent` workflow (`.github/workflows/auto-review.yml`) runs in parallel and is enforced by SHA-aware policy checks.
32
35
 
36
+ `remediation-agent` workflow (`.github/workflows/remediation-agent.yml`) can be enabled for in-branch automated fixes after actionable review findings.
37
+
33
38
  ## SHA Discipline and Reruns
34
39
  `scripts/control-plane/risk-policy-gate.mjs` enforces:
35
40
  - review check must be for current PR head SHA
@@ -48,6 +53,8 @@ npm run harness:ui:capture-browser-evidence
48
53
  npm run harness:ui:verify-browser-evidence
49
54
  ```
50
55
 
56
+ In CI, capture + verify are both run in `Browser Evidence` job.
57
+
51
58
  ## Harness Gap Loop
52
59
  `harness-gap-loop` workflow:
53
60
  - creates a `harness-gap` issue when a `production-regression` issue appears
@@ -64,8 +71,35 @@ npm run harness:ui:capture-browser-evidence
64
71
  npm run harness:ui:verify-browser-evidence
65
72
  npm run harness:risk-tier
66
73
  npm run harness:weekly-metrics
74
+ npm run spec:normalize
75
+ npm run spec:validate
76
+ npm run spec:check
77
+ ```
78
+
79
+ ## Branch Protection
80
+ Merge blocking is enforced via GitHub branch protection requiring `risk-policy-finalize`.
81
+
82
+ - `code-factory --github` now applies this automatically.
83
+ - For repos created from GitHub template UI, run:
84
+
85
+ ```bash
86
+ node scripts/control-plane/apply-branch-protection.mjs owner/repo
67
87
  ```
68
88
 
89
+ Note: GitHub may require a paid plan (or public repo) for private-repo branch protection.
90
+
91
+ ## Remediation Agent
92
+ Optional, disabled by default:
93
+ - add a self-hosted runner for the repo
94
+ - set repository variable `ENABLE_REMEDIATION=true`
95
+ - optional variables: `REMEDIATION_ENGINE`, `REMEDIATION_CODEX_MODEL`, `REMEDIATION_VALIDATE_CMD`
96
+
97
+ When enabled, failed review-agent runs can trigger deterministic in-branch remediation:
98
+ 1. read current-head actionable findings
99
+ 2. run local CLI agent (`codex`/`claude`/`opencode`/custom)
100
+ 3. run validation command
101
+ 4. commit + push fix to same PR branch
102
+
69
103
  ## Agent Loop Files
70
104
  - `ARCHITECTURE.yaml`
71
105
  - `AGENTS.md`
@@ -111,6 +145,15 @@ Compatibility alias:
111
145
  - `opencode` (default model `minimax-coding-plan/MiniMax-M2.5`)
112
146
  - `custom`
113
147
 
148
+ Before task execution, `ralph.sh` now runs a spec gate:
149
+ 1. normalize `ARCHITECTURE.yaml` + `prd.json` into canonical format
150
+ 2. validate both files strictly
151
+ 3. if still invalid, auto-repair with your selected local engine and retry (bounded)
152
+
153
+ Defaults:
154
+ - `SPEC_REPAIR_ENABLED=true`
155
+ - `SPEC_REPAIR_MAX_RETRIES=3`
156
+
114
157
  Examples:
115
158
  ```bash
116
159
  ./ralph.sh --once
@@ -21,6 +21,8 @@ Options:
21
21
  --owner <owner> GitHub owner/org for --github (defaults to gh auth user)
22
22
  --repo <name|owner/name>
23
23
  GitHub repo name override (default: slugified project name)
24
+ --no-branch-protection
25
+ Skip automatic main branch protection setup for --github
24
26
  --template-url <url> Override template repository URL for this run
25
27
  -h, --help Show help
26
28
 
@@ -61,6 +63,7 @@ function parseArgs(rawArgs) {
61
63
  visibility: "private",
62
64
  owner: null,
63
65
  repo: null,
66
+ branchProtection: true,
64
67
  templateUrl: DEFAULT_TEMPLATE_URL
65
68
  };
66
69
 
@@ -107,6 +110,11 @@ function parseArgs(rawArgs) {
107
110
  continue;
108
111
  }
109
112
 
113
+ if (arg === "--no-branch-protection") {
114
+ options.branchProtection = false;
115
+ continue;
116
+ }
117
+
110
118
  if (arg === "-h" || arg === "--help") {
111
119
  usage(0);
112
120
  }
@@ -149,6 +157,43 @@ function deriveGitHubRepo(projectName, options) {
149
157
  return { owner, repo };
150
158
  }
151
159
 
160
+ function configureBranchProtection({ owner, repo }) {
161
+ const requiredChecks = ["risk-policy-finalize"];
162
+ const payload = {
163
+ required_status_checks: {
164
+ strict: true,
165
+ contexts: requiredChecks
166
+ },
167
+ enforce_admins: false,
168
+ required_pull_request_reviews: {
169
+ dismiss_stale_reviews: true,
170
+ require_code_owner_reviews: false,
171
+ required_approving_review_count: 1
172
+ },
173
+ restrictions: null,
174
+ required_conversation_resolution: true,
175
+ allow_force_pushes: false,
176
+ allow_deletions: false
177
+ };
178
+
179
+ execFileSync(
180
+ "gh",
181
+ [
182
+ "api",
183
+ "--method",
184
+ "PUT",
185
+ `repos/${owner}/${repo}/branches/main/protection`,
186
+ "--input",
187
+ "-"
188
+ ],
189
+ {
190
+ stdio: ["pipe", "inherit", "inherit"],
191
+ input: JSON.stringify(payload),
192
+ encoding: "utf8"
193
+ }
194
+ );
195
+ }
196
+
152
197
  function createProject(projectName, destinationDir, options) {
153
198
  const targetPath = resolve(destinationDir, projectName);
154
199
 
@@ -161,6 +206,7 @@ function createProject(projectName, destinationDir, options) {
161
206
  run("git", ["-C", targetPath, "init", "-q"]);
162
207
  run("git", ["-C", targetPath, "add", "."]);
163
208
  run("git", ["-C", targetPath, "commit", "-q", "-m", "Initial commit from Code Factory template"]);
209
+ run("git", ["-C", targetPath, "branch", "-M", "main"]);
164
210
 
165
211
  if (options.github) {
166
212
  const { owner, repo } = deriveGitHubRepo(projectName, options);
@@ -169,6 +215,18 @@ function createProject(projectName, destinationDir, options) {
169
215
 
170
216
  run("gh", ["repo", "create", fullRepo, visibilityFlag, "--source", targetPath, "--remote", "origin", "--push"]);
171
217
  console.log(`GitHub repo created: https://github.com/${fullRepo}`);
218
+
219
+ if (options.branchProtection) {
220
+ try {
221
+ configureBranchProtection({ owner, repo });
222
+ console.log("Main branch protection applied (required check: risk-policy-finalize).");
223
+ } catch (error) {
224
+ console.warn(
225
+ "Warning: failed to apply branch protection automatically. " +
226
+ "Run scripts/control-plane/apply-branch-protection.mjs in the new repo."
227
+ );
228
+ }
229
+ }
172
230
  }
173
231
 
174
232
  console.log("Your new Code Factory project is ready!");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jnyross/code-factory",
3
- "version": "1.1.1",
3
+ "version": "1.1.4",
4
4
  "description": "Bootstrap new repos from the Code Factory template.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,12 +25,16 @@
25
25
  "new-project": "bin/code-factory.mjs"
26
26
  },
27
27
  "scripts": {
28
+ "control-plane:apply-branch-protection": "node scripts/control-plane/apply-branch-protection.mjs",
28
29
  "harness:risk-tier": "node scripts/control-plane/risk-tier.mjs",
29
30
  "harness:legal-chat:smoke": "node scripts/control-plane/harness-smoke.mjs",
30
31
  "harness:ui:capture-browser-evidence": "node scripts/control-plane/capture-browser-evidence.mjs",
31
32
  "harness:ui:verify-browser-evidence": "node scripts/control-plane/verify-browser-evidence.mjs",
32
33
  "harness:ui:pre-pr": "npm run harness:ui:capture-browser-evidence && npm run harness:ui:verify-browser-evidence",
33
- "harness:weekly-metrics": "node scripts/control-plane/weekly-metrics.mjs"
34
+ "harness:weekly-metrics": "node scripts/control-plane/weekly-metrics.mjs",
35
+ "spec:normalize": "node scripts/control-plane/normalize-specs.mjs --write",
36
+ "spec:validate": "node scripts/control-plane/validate-specs.mjs",
37
+ "spec:check": "npm run spec:normalize && npm run spec:validate"
34
38
  },
35
39
  "files": [
36
40
  "bin",