@momentiq/dark-factory-cli 0.1.0-alpha.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.
Files changed (132) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +150 -0
  3. package/dist/adapters/_shared.d.ts +45 -0
  4. package/dist/adapters/_shared.d.ts.map +1 -0
  5. package/dist/adapters/_shared.js +200 -0
  6. package/dist/adapters/_shared.js.map +1 -0
  7. package/dist/adapters/codex-sdk.d.ts +279 -0
  8. package/dist/adapters/codex-sdk.d.ts.map +1 -0
  9. package/dist/adapters/codex-sdk.js +930 -0
  10. package/dist/adapters/codex-sdk.js.map +1 -0
  11. package/dist/adapters/critic-result-schema.d.ts +215 -0
  12. package/dist/adapters/critic-result-schema.d.ts.map +1 -0
  13. package/dist/adapters/critic-result-schema.js +153 -0
  14. package/dist/adapters/critic-result-schema.js.map +1 -0
  15. package/dist/adapters/critic.d.ts +62 -0
  16. package/dist/adapters/critic.d.ts.map +1 -0
  17. package/dist/adapters/critic.js +79 -0
  18. package/dist/adapters/critic.js.map +1 -0
  19. package/dist/adapters/cursor-sdk.d.ts +153 -0
  20. package/dist/adapters/cursor-sdk.d.ts.map +1 -0
  21. package/dist/adapters/cursor-sdk.js +818 -0
  22. package/dist/adapters/cursor-sdk.js.map +1 -0
  23. package/dist/adapters/gemini-sdk.d.ts +113 -0
  24. package/dist/adapters/gemini-sdk.d.ts.map +1 -0
  25. package/dist/adapters/gemini-sdk.js +532 -0
  26. package/dist/adapters/gemini-sdk.js.map +1 -0
  27. package/dist/adapters/grok-direct-sdk.d.ts +148 -0
  28. package/dist/adapters/grok-direct-sdk.d.ts.map +1 -0
  29. package/dist/adapters/grok-direct-sdk.js +694 -0
  30. package/dist/adapters/grok-direct-sdk.js.map +1 -0
  31. package/dist/branch-protection/audit_branch_protection.py +759 -0
  32. package/dist/branch-protection/index.d.ts +25 -0
  33. package/dist/branch-protection/index.d.ts.map +1 -0
  34. package/dist/branch-protection/index.js +70 -0
  35. package/dist/branch-protection/index.js.map +1 -0
  36. package/dist/branch-protection/spec-default.yaml +314 -0
  37. package/dist/cli.d.ts +3 -0
  38. package/dist/cli.d.ts.map +1 -0
  39. package/dist/cli.js +581 -0
  40. package/dist/cli.js.map +1 -0
  41. package/dist/cycle-doc-validator/index.d.ts +43 -0
  42. package/dist/cycle-doc-validator/index.d.ts.map +1 -0
  43. package/dist/cycle-doc-validator/index.js +69 -0
  44. package/dist/cycle-doc-validator/index.js.map +1 -0
  45. package/dist/cycle-doc-validator/validate_cycle_doc.py +1260 -0
  46. package/dist/cycle-tracker-sync/attribute_pr_cycle_ref.py +384 -0
  47. package/dist/cycle-tracker-sync/index.d.ts +20 -0
  48. package/dist/cycle-tracker-sync/index.d.ts.map +1 -0
  49. package/dist/cycle-tracker-sync/index.js +71 -0
  50. package/dist/cycle-tracker-sync/index.js.map +1 -0
  51. package/dist/cycle-tracker-sync/sync_cycle_trackers.py +1093 -0
  52. package/dist/evidence/audit-trail.d.ts +59 -0
  53. package/dist/evidence/audit-trail.d.ts.map +1 -0
  54. package/dist/evidence/audit-trail.js +283 -0
  55. package/dist/evidence/audit-trail.js.map +1 -0
  56. package/dist/evidence/index.d.ts +4 -0
  57. package/dist/evidence/index.d.ts.map +1 -0
  58. package/dist/evidence/index.js +29 -0
  59. package/dist/evidence/index.js.map +1 -0
  60. package/dist/evidence/per-sha.d.ts +13 -0
  61. package/dist/evidence/per-sha.d.ts.map +1 -0
  62. package/dist/evidence/per-sha.js +97 -0
  63. package/dist/evidence/per-sha.js.map +1 -0
  64. package/dist/evidence/quality-gates.d.ts +19 -0
  65. package/dist/evidence/quality-gates.d.ts.map +1 -0
  66. package/dist/evidence/quality-gates.js +212 -0
  67. package/dist/evidence/quality-gates.js.map +1 -0
  68. package/dist/git.d.ts +40 -0
  69. package/dist/git.d.ts.map +1 -0
  70. package/dist/git.js +414 -0
  71. package/dist/git.js.map +1 -0
  72. package/dist/glob.d.ts +4 -0
  73. package/dist/glob.d.ts.map +1 -0
  74. package/dist/glob.js +99 -0
  75. package/dist/glob.js.map +1 -0
  76. package/dist/index.d.ts +17 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +33 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/paths.d.ts +12 -0
  81. package/dist/paths.d.ts.map +1 -0
  82. package/dist/paths.js +42 -0
  83. package/dist/paths.js.map +1 -0
  84. package/dist/policy/baseline.d.ts +15 -0
  85. package/dist/policy/baseline.d.ts.map +1 -0
  86. package/dist/policy/baseline.js +115 -0
  87. package/dist/policy/baseline.js.map +1 -0
  88. package/dist/policy/config.d.ts +64 -0
  89. package/dist/policy/config.d.ts.map +1 -0
  90. package/dist/policy/config.js +363 -0
  91. package/dist/policy/config.js.map +1 -0
  92. package/dist/policy/gate.d.ts +80 -0
  93. package/dist/policy/gate.d.ts.map +1 -0
  94. package/dist/policy/gate.js +1019 -0
  95. package/dist/policy/gate.js.map +1 -0
  96. package/dist/policy/index.d.ts +7 -0
  97. package/dist/policy/index.d.ts.map +1 -0
  98. package/dist/policy/index.js +14 -0
  99. package/dist/policy/index.js.map +1 -0
  100. package/dist/policy/merge-queue.d.ts +183 -0
  101. package/dist/policy/merge-queue.d.ts.map +1 -0
  102. package/dist/policy/merge-queue.js +310 -0
  103. package/dist/policy/merge-queue.js.map +1 -0
  104. package/dist/policy/profile.d.ts +98 -0
  105. package/dist/policy/profile.d.ts.map +1 -0
  106. package/dist/policy/profile.js +156 -0
  107. package/dist/policy/profile.js.map +1 -0
  108. package/dist/policy/tdd-classifier.d.ts +18 -0
  109. package/dist/policy/tdd-classifier.d.ts.map +1 -0
  110. package/dist/policy/tdd-classifier.js +79 -0
  111. package/dist/policy/tdd-classifier.js.map +1 -0
  112. package/dist/prompt.d.ts +13 -0
  113. package/dist/prompt.d.ts.map +1 -0
  114. package/dist/prompt.js +175 -0
  115. package/dist/prompt.js.map +1 -0
  116. package/dist/report.d.ts +88 -0
  117. package/dist/report.d.ts.map +1 -0
  118. package/dist/report.js +376 -0
  119. package/dist/report.js.map +1 -0
  120. package/dist/runner.d.ts +30 -0
  121. package/dist/runner.d.ts.map +1 -0
  122. package/dist/runner.js +456 -0
  123. package/dist/runner.js.map +1 -0
  124. package/dist/security.d.ts +2 -0
  125. package/dist/security.d.ts.map +1 -0
  126. package/dist/security.js +19 -0
  127. package/dist/security.js.map +1 -0
  128. package/dist/trusted-surface/rebind.d.ts +10 -0
  129. package/dist/trusted-surface/rebind.d.ts.map +1 -0
  130. package/dist/trusted-surface/rebind.js +154 -0
  131. package/dist/trusted-surface/rebind.js.map +1 -0
  132. package/package.json +78 -0
package/dist/runner.js ADDED
@@ -0,0 +1,456 @@
1
+ import { buildReviewPacket } from "./trusted-surface/rebind.js";
2
+ import { collectChangedPaths } from "./evidence/index.js";
3
+ import { buildRubricContext, enforceVerificationRoutes, evaluateCommitGate, runTddClassifier, } from "./policy/gate.js";
4
+ import { changedFiles, commitParent, resolveCommit } from "./git.js";
5
+ import { diagnosticsDir, resolveArtifactDir } from "./paths.js";
6
+ import { resolvePolicyBaseline } from "./policy/baseline.js";
7
+ import { applyProfileAuth, applyProfileParamOverrides, resolveProfileWithConfig, } from "./policy/profile.js";
8
+ import { runQualityGates } from "./evidence/index.js";
9
+ import { acquireCommitLock, buildAggregate, quorumAggregateVerdict, releaseCommitLock, writeArtifacts, writePending, } from "./report.js";
10
+ export async function runReview(options) {
11
+ const { registry } = options;
12
+ const cwd = options.cwd ?? options.loaded.repoRoot;
13
+ const ref = options.ref ?? "HEAD";
14
+ const sha = await resolveCommit(ref, cwd);
15
+ // Self-modification guard across the whole trusted policy surface
16
+ // (config + guidance files + prompt fragments). See `policy-baseline.ts`.
17
+ const baseline = await resolvePolicyBaseline({ loaded: options.loaded, sha, cwd });
18
+ const loaded = baseline.loaded;
19
+ const lock = await acquireCommitLock(loaded, sha);
20
+ if (!lock.acquired) {
21
+ throw new Error(`another agent-review is already in progress for commit ${sha} (lock at ${lock.lockPath}). Wait for it to finish or remove the lock if stale.`);
22
+ }
23
+ // Wrap EVERYTHING after lock acquisition in try/finally so the lock is
24
+ // always released — even on early failures from runQualityGates,
25
+ // buildReviewPacket, writePending, or any critic promise rejection.
26
+ // Without this, an exception during preparation leaves a stale `.lock`
27
+ // file that permanently blocks future reviews of the same SHA. (Cycle 3 #6)
28
+ const startedAt = new Date().toISOString();
29
+ const startMs = Date.now();
30
+ let packet;
31
+ let paths;
32
+ let artifact;
33
+ try {
34
+ // Honor `runBeforeReview`: when true, run the configured required quality
35
+ // gates synchronously before invoking the critic. The result file is
36
+ // picked up by `buildReviewPacket` → `readValidationEvidence`, so the
37
+ // packet carries fresh deterministic evidence. Without this, the flag was
38
+ // dead and operators always had to attach evidence by hand.
39
+ if (loaded.config.validation.runBeforeReview) {
40
+ await runQualityGates({
41
+ loaded,
42
+ commit: sha,
43
+ cwd,
44
+ ...(options.signal !== undefined ? { signal: options.signal } : {}),
45
+ });
46
+ }
47
+ packet = await buildReviewPacket(loaded, {
48
+ ref: sha,
49
+ cwd,
50
+ ...(baseline.baselineRef !== undefined ? { trustedSurfaceRef: baseline.baselineRef } : {}),
51
+ });
52
+ await writePending(loaded, {
53
+ loaded,
54
+ commit: sha,
55
+ parent: packet.commit.parent,
56
+ range: packet.range,
57
+ diffHash: packet.diffHash,
58
+ createdAt: startedAt,
59
+ });
60
+ const sink = options.telemetry;
61
+ // Cycle 322.7 Phase C — Emergency revert audit trail. When the
62
+ // config-load path applied `AGENT_REVIEW_AGGREGATION_POLICY`, it
63
+ // populated `loaded.policyOverride` with the audit record. Emit
64
+ // the matching `aggregation_policy_overridden` event so the
65
+ // run's NDJSON timeline captures the override + any auto-promoted
66
+ // critics. Fires BEFORE profile_selected so the audit ordering is
67
+ // "policy override → profile selection → review_started → critic
68
+ // runs → review_finished".
69
+ if (loaded.policyOverride) {
70
+ emit(sink, {
71
+ ts: new Date().toISOString(),
72
+ event: "aggregation_policy_overridden",
73
+ commit: sha,
74
+ configured: loaded.policyOverride.configured,
75
+ overridden: loaded.policyOverride.overridden,
76
+ autoPromotedCritics: loaded.policyOverride.autoPromotedCritics,
77
+ });
78
+ }
79
+ // Cycle 322.7 — Profile resolution. The caller has already
80
+ // applied --profile / AGENT_REVIEW_PROFILE precedence and passed
81
+ // the resolved name. Look it up against the loaded config:
82
+ // - If config has no `profiles` map → back-compat: profile is
83
+ // undefined, full critic list, root aggregation.quorum.
84
+ // - If config HAS `profiles` and name matches → filter critics
85
+ // to profile.criticIds, override aggregation quorum, emit
86
+ // profile_selected telemetry.
87
+ // - If config HAS `profiles` and name doesn't match → throw a
88
+ // clear error (resolveProfileWithConfig handles this).
89
+ //
90
+ // profile_selected fires BEFORE review_started so the timeline
91
+ // operators see in telemetry has "selection happens before run".
92
+ const resolvedProfile = options.profileName
93
+ ? resolveProfileWithConfig(loaded.config, options.profileName)
94
+ : undefined;
95
+ const activeCritics = resolvedProfile?.criticIds
96
+ ? loaded.config.critics.filter((c) => resolvedProfile.criticIds.includes(c.id))
97
+ : loaded.config.critics;
98
+ if (resolvedProfile?.profile) {
99
+ emit(sink, {
100
+ ts: new Date().toISOString(),
101
+ event: "profile_selected",
102
+ commit: sha,
103
+ profile: resolvedProfile.profileName,
104
+ criticIds: resolvedProfile.profile.criticIds,
105
+ quorum: resolvedProfile.profile.quorum,
106
+ });
107
+ }
108
+ emit(sink, {
109
+ ts: startedAt,
110
+ event: "review_started",
111
+ commit: sha,
112
+ });
113
+ const adapterDiagnosticsDir = diagnosticsDir(await resolveArtifactDir(loaded));
114
+ const reviewOptions = {
115
+ blockingSeverities: loaded.config.aggregation.blockingSeverities,
116
+ diagnosticsDir: adapterDiagnosticsDir,
117
+ ...(options.signal !== undefined ? { signal: options.signal } : {}),
118
+ ...(sink !== undefined ? { emit: (e) => sink.emit(e) } : {}),
119
+ };
120
+ // Cycle 322.8 — apply profile-scoped modelParamOverrides BEFORE
121
+ // dispatching to adapters. Identity (same reference) when no
122
+ // override applies to a critic; otherwise a clone with the
123
+ // overridden params. Adapters see the resolved critic via their
124
+ // existing `critic.model.params` surface — no adapter-side change.
125
+ //
126
+ // Issue #2103 — chain `applyProfileAuth` AFTER `applyProfileParamOverrides`.
127
+ // Both are pure and commute (no field overlap), so order is only a
128
+ // convention; documenting it makes the pipeline reviewable.
129
+ const requiredCritics = activeCritics.map((c) => applyProfileAuth(applyProfileParamOverrides(c, resolvedProfile?.profile), resolvedProfile?.profile));
130
+ const results = await Promise.all(requiredCritics.map(async (critic) => {
131
+ if (!registry.has(critic.adapter)) {
132
+ return {
133
+ criticId: critic.id,
134
+ status: "error",
135
+ requiresHumanJudgment: false,
136
+ reviewer: {
137
+ name: critic.name,
138
+ adapter: critic.adapter,
139
+ model: critic.model,
140
+ runtime: critic.runtime,
141
+ },
142
+ summary: `no adapter registered for "${critic.adapter}"`,
143
+ findings: [],
144
+ validation: { qualityGateResults: [], qualityGatesMissing: [] },
145
+ confidence: "unknown",
146
+ error: { message: `no adapter registered for "${critic.adapter}"`, retryable: false },
147
+ };
148
+ }
149
+ const adapter = registry.resolve(critic.adapter);
150
+ return adapter.review(packet, critic, reviewOptions);
151
+ }));
152
+ const finishedAt = new Date().toISOString();
153
+ artifact = buildAggregate({
154
+ loaded,
155
+ commit: sha,
156
+ parent: packet.commit.parent,
157
+ range: packet.range,
158
+ diffHash: packet.diffHash,
159
+ criticResults: results,
160
+ status: "complete",
161
+ createdAt: startedAt,
162
+ // Cycle 322.7 — thread profile quorum so the persisted artifact's
163
+ // gateVerdict uses the same effective quorum as the runtime gate
164
+ // evaluator (Codex P2 on PR #1468).
165
+ ...(resolvedProfile?.quorum !== undefined
166
+ ? { quorumOverride: resolvedProfile.quorum }
167
+ : {}),
168
+ });
169
+ artifact.updatedAt = finishedAt;
170
+ paths = await writeArtifacts(loaded, artifact);
171
+ // Cycle 322.3 — populate quorum-aware telemetry on review_finished
172
+ // even when the live config policy is still `block-if-any`. This
173
+ // lets operators inspect the calibration-window data: how would
174
+ // the gate behave under quorum, today? The artifact's actual
175
+ // gateVerdict still reflects the live policy; `aggregateReason`
176
+ // is always the quorum interpretation (one of "majority", "veto",
177
+ // "quorum_unmet").
178
+ //
179
+ // The reason that the field is ALWAYS the quorum interpretation
180
+ // (instead of "block-if-any" sometimes) addresses Cursor critic
181
+ // 367476d3 finding #2 (observability, §5): under the live
182
+ // block-if-any policy, operators need to count would-be
183
+ // `majority` / `veto` outcomes across the calibration window —
184
+ // not just `quorum_unmet`. The active policy is encoded in the
185
+ // artifact's `aggregationPolicy` field; operators correlate
186
+ // `aggregateReason` against that to interpret the value (live
187
+ // gate-decision path vs. hypothetical 322.3.1 outcome).
188
+ const criticVerdicts = {};
189
+ const criticCompletionStates = {};
190
+ for (const r of results) {
191
+ if (r.verdict !== undefined) {
192
+ criticVerdicts[r.criticId] = r.verdict;
193
+ }
194
+ criticCompletionStates[r.criticId] =
195
+ r.status === "complete"
196
+ ? "completed"
197
+ : r.status === "error"
198
+ ? "errored"
199
+ : "pending";
200
+ }
201
+ // Cycle 322.7 — when a profile is active, profile.quorum
202
+ // overrides root aggregation.quorum for the aggregateReason
203
+ // computation. Under back-compat (no profile), fall back to the
204
+ // 322.3 logic: root quorum on min-complete-quorum, hypothetical
205
+ // quorum=2 on block-if-any (so calibration metrics still surface).
206
+ const quorum = resolvedProfile?.quorum ??
207
+ (loaded.config.aggregation.policy === "min-complete-quorum"
208
+ ? (loaded.config.aggregation.quorum ?? 2)
209
+ : 2);
210
+ const aggregateReason = quorumAggregateVerdict(results, loaded.config.aggregation.blockingSeverities, quorum).reason;
211
+ emit(sink, {
212
+ ts: finishedAt,
213
+ event: "review_finished",
214
+ commit: sha,
215
+ durationMs: Date.now() - startMs,
216
+ ...(artifact.gateVerdict !== undefined ? { verdict: artifact.gateVerdict } : {}),
217
+ findingCount: results.reduce((acc, r) => acc + r.findings.length, 0),
218
+ aggregateReason,
219
+ criticVerdicts,
220
+ criticCompletionStates,
221
+ });
222
+ }
223
+ catch (err) {
224
+ // Convert the pending artifact to a terminal error artifact so the gate
225
+ // sees a real failure instead of perpetually-pending. Without this, a
226
+ // throw here leaves `<sha>.json` at status=pending and `gate-push`
227
+ // blocks forever with `review_in_progress`. (Cycle 3 #9)
228
+ //
229
+ // Recovery runs whenever `packet` is built, NOT only when writePending
230
+ // returned successfully — `writePending` -> `writeArtifacts` writes JSON
231
+ // first; if any subsequent step throws, the JSON is already on disk and
232
+ // would otherwise stay at status=pending forever. `writeArtifacts` is
233
+ // now JSON-authoritative (markdown best-effort), so a hostile markdown
234
+ // path cannot block recovery.
235
+ if (packet) {
236
+ try {
237
+ const errArtifact = buildAggregate({
238
+ loaded,
239
+ commit: sha,
240
+ parent: packet.commit.parent,
241
+ range: packet.range,
242
+ diffHash: packet.diffHash,
243
+ criticResults: [],
244
+ status: "error",
245
+ createdAt: startedAt,
246
+ });
247
+ errArtifact.updatedAt = new Date().toISOString();
248
+ await writeArtifacts(loaded, errArtifact);
249
+ }
250
+ catch {
251
+ // Best-effort. If the error-artifact write itself fails, the lock
252
+ // release in the finally block still happens; the operator can
253
+ // re-run agent-review-commit to recover.
254
+ }
255
+ }
256
+ emit(options.telemetry, {
257
+ ts: new Date().toISOString(),
258
+ event: "review_error",
259
+ commit: sha,
260
+ durationMs: Date.now() - startMs,
261
+ error: err.message,
262
+ });
263
+ throw err;
264
+ }
265
+ finally {
266
+ releaseCommitLock(lock.lockPath);
267
+ }
268
+ // Re-narrow after try/finally — a successful path guarantees these are set.
269
+ if (!artifact || !paths || !packet) {
270
+ throw new Error("internal: artifact/paths/packet not set after successful runReview");
271
+ }
272
+ return {
273
+ artifact,
274
+ paths,
275
+ packet,
276
+ acquired: true,
277
+ };
278
+ }
279
+ export async function runCommitGate(options) {
280
+ const cwd = options.cwd ?? options.loaded.repoRoot;
281
+ // Apply the same self-modification guard as `runReview`: a commit that
282
+ // touches the trusted policy surface (config + guidance + fragments) is
283
+ // not allowed to weaken its OWN gate evaluation. Without this, a commit
284
+ // could set `blockOnMissingReview=false` or empty `requiredQualityGates`
285
+ // and have pre-push respect the weakened HEAD policy.
286
+ const sha = await resolveCommit(options.commit, cwd);
287
+ const baseline = await resolvePolicyBaseline({ loaded: options.loaded, sha, cwd });
288
+ const loaded = baseline.loaded;
289
+ // Cycle 322.7 Phase C — Emergency revert audit trail (gate path).
290
+ // The documented operator flow is `AGENT_REVIEW_AGGREGATION_POLICY=
291
+ // block-if-any git push`, which goes through gate-push → runCommitGate.
292
+ // If we only emitted the event in runReview, that primary operator
293
+ // surface would lose the audit record. Emit here too so every override
294
+ // application — whether through the local critic subprocess or the
295
+ // pre-push gate evaluator — appears in `_runs.ndjson`. The Cursor critic
296
+ // finding on dce8fd9e flagged the gap (HIGH, observability §5).
297
+ if (loaded.policyOverride) {
298
+ emit(options.telemetry, {
299
+ ts: new Date().toISOString(),
300
+ event: "aggregation_policy_overridden",
301
+ commit: sha,
302
+ configured: loaded.policyOverride.configured,
303
+ overridden: loaded.policyOverride.overridden,
304
+ autoPromotedCritics: loaded.policyOverride.autoPromotedCritics,
305
+ });
306
+ }
307
+ // Cycle 318.2 wiring: gate-push composes four gates in sequence; first
308
+ // failure does NOT short-circuit — collect all blockers so a developer
309
+ // sees the full picture in one pre-push output instead of stair-stepping
310
+ // through the gate one fix at a time.
311
+ //
312
+ // 1. TDD classifier (Component 1)
313
+ // 2. Verification routes (Component 2)
314
+ // 3. Bypass / artifact / rubric-aware critic gate (Component 5)
315
+ //
316
+ // Bypass is handled inside `evaluateCommitGate` and still short-circuits
317
+ // — the deterministic gates only run when no bypass is in effect.
318
+ const allBlocks = [];
319
+ const allWarnings = [];
320
+ const bypassReason = (process.env["AGENT_REVIEW_BYPASS"] ?? "").trim();
321
+ const bypassActive = loaded.config.policy.allowEmergencyBypass && bypassReason.length > 0;
322
+ if (!bypassActive && loaded.config.version === 2) {
323
+ // TDD classifier — fail-closed per manifesto §8 (AI-Generated Code
324
+ // with Safety Nets). A classifier exception (missing commit metadata,
325
+ // shallow clone, IO failure) is a deterministic-gate failure: we
326
+ // can't confirm whether tests accompany the production change, so
327
+ // the gate must block. Operators with a genuinely broken local
328
+ // environment can opt out via AGENT_REVIEW_BYPASS=<reason>.
329
+ try {
330
+ const tdd = await runTddClassifier({ loaded, sha, cwd });
331
+ if (tdd && tdd.verdict === "block") {
332
+ allBlocks.push({
333
+ reason: "tdd_no_test",
334
+ detail: `${tdd.reason}; production paths: ${tdd.productionPaths
335
+ .slice(0, 5)
336
+ .join(", ")}${tdd.productionPaths.length > 5 ? ", ..." : ""}`,
337
+ });
338
+ }
339
+ else if (tdd && tdd.verdict === "justified") {
340
+ allWarnings.push({
341
+ reason: "tdd_justified",
342
+ detail: tdd.reason,
343
+ });
344
+ }
345
+ }
346
+ catch (err) {
347
+ allBlocks.push({
348
+ reason: "tdd_classifier_error",
349
+ detail: `TDD classifier failed: ${err.message}`,
350
+ });
351
+ }
352
+ // Verification routes — also fail-closed. A route evaluation that
353
+ // throws (corrupted JSON, fs error, etc.) means we can't read the
354
+ // per-SHA evidence file safely; block by default so a stale or
355
+ // unreadable artifact cannot let a push through. AGENT_REVIEW_BYPASS
356
+ // remains the documented escape hatch for tool-broken emergencies.
357
+ try {
358
+ const parent = await safeParent(sha, cwd);
359
+ const files = await changedFiles(parent, sha, cwd, { readContent: false });
360
+ // Include `oldPath` from rename/copy entries so a rename out of a
361
+ // routed glob (e.g., `backend/app/foo.py` → `web/generated/foo.ts`)
362
+ // still triggers the source's route. Without this, the only path
363
+ // checked was the new path, and the moved-from glob would silently
364
+ // fall off the gate. (Codex P2 follow-up on PR #1349.)
365
+ const routeEval = await enforceVerificationRoutes({
366
+ loaded,
367
+ sha,
368
+ changedPaths: collectChangedPaths(files),
369
+ });
370
+ for (const r of routeEval.perRoute) {
371
+ if (r.status === "missing") {
372
+ allBlocks.push({
373
+ reason: "verification_route_missing",
374
+ detail: r.detail,
375
+ });
376
+ }
377
+ else if (r.status === "failed") {
378
+ allBlocks.push({
379
+ reason: "verification_route_failed",
380
+ detail: r.detail,
381
+ });
382
+ }
383
+ }
384
+ if (routeEval.suppressedBy) {
385
+ allWarnings.push({
386
+ reason: "routes_suppressed",
387
+ detail: `exclusive route "${routeEval.suppressedBy.id}" suppressed all production routes`,
388
+ });
389
+ }
390
+ }
391
+ catch (err) {
392
+ allBlocks.push({
393
+ reason: "verification_routes_error",
394
+ detail: `verification-routes evaluation failed: ${err.message}`,
395
+ });
396
+ }
397
+ }
398
+ // Build the rubric context once (commit trailers + per-SHA evidence)
399
+ // so the critic-gate finding filter has it without reparsing. Only
400
+ // build for v2 configs; v1 keeps the legacy behavior.
401
+ const rubricContext = loaded.config.version === 2 && !bypassActive
402
+ ? await buildRubricContext({ loaded, sha, cwd })
403
+ : undefined;
404
+ // Cycle 322.7 — when a profile is active, override the quorum used
405
+ // by the gate evaluator AND scope the artifact's critic results to
406
+ // the profile's allowlist. The profile resolver throws on unknown
407
+ // profile names so a mistyped --profile fails loudly here too.
408
+ const resolvedProfile = options.profileName
409
+ ? resolveProfileWithConfig(loaded.config, options.profileName)
410
+ : undefined;
411
+ const quorumOverride = resolvedProfile?.quorum;
412
+ const profileCriticIds = resolvedProfile?.criticIds;
413
+ const result = await evaluateCommitGate({
414
+ loaded,
415
+ commit: options.commit,
416
+ cwd,
417
+ ...(rubricContext !== undefined ? { rubricContext } : {}),
418
+ ...(quorumOverride !== undefined ? { quorumOverride } : {}),
419
+ ...(profileCriticIds !== undefined ? { profileCriticIds } : {}),
420
+ });
421
+ // Merge deterministic gate results with the artifact-driven gate result.
422
+ // Bypass on the artifact gate replaces our collected blocks entirely —
423
+ // a bypass invocation is a full ceasefire on this push.
424
+ const merged = result.bypass
425
+ ? result
426
+ : {
427
+ blocked: result.blocked || allBlocks.length > 0,
428
+ blocks: [...allBlocks, ...result.blocks],
429
+ warnings: [...allWarnings, ...result.warnings],
430
+ ...(result.bypass !== undefined ? { bypass: result.bypass } : {}),
431
+ };
432
+ emit(options.telemetry, {
433
+ ts: new Date().toISOString(),
434
+ event: merged.bypass
435
+ ? "gate_bypassed"
436
+ : merged.blocked
437
+ ? "gate_blocked"
438
+ : "gate_passed",
439
+ commit: options.commit,
440
+ ...(merged.bypass ? { bypassReason: merged.bypass.reason } : {}),
441
+ });
442
+ return merged;
443
+ }
444
+ async function safeParent(sha, cwd) {
445
+ try {
446
+ return await commitParent(sha, cwd);
447
+ }
448
+ catch {
449
+ return "";
450
+ }
451
+ }
452
+ function emit(sink, event) {
453
+ if (sink)
454
+ sink.emit(event);
455
+ }
456
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function redactSecrets(input: string): string;
2
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAYA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD"}
@@ -0,0 +1,19 @@
1
+ const SECRET_PATTERNS = [
2
+ { name: "openai", re: /sk-[A-Za-z0-9]{20,}/g },
3
+ { name: "anthropic", re: /sk-ant-[A-Za-z0-9-_]{20,}/g },
4
+ { name: "cursor", re: /cursor_[A-Za-z0-9-_]{20,}/g },
5
+ { name: "github_pat", re: /gh[pousr]_[A-Za-z0-9]{20,}/g },
6
+ { name: "aws_access_key", re: /AKIA[0-9A-Z]{16}/g },
7
+ { name: "private_key", re: /-----BEGIN [A-Z ]+PRIVATE KEY-----[\s\S]*?-----END [A-Z ]+PRIVATE KEY-----/g },
8
+ { name: "generic_long_token", re: /(?<![A-Za-z0-9])([A-Za-z0-9_-]{40,})(?![A-Za-z0-9])/g },
9
+ ];
10
+ const SECRET_KEY_HINT = /\b(api[_-]?key|secret|token|password|passphrase|auth[_-]?token)\b\s*[:=]\s*["']?(?!\[REDACTED)([^"'\s]{8,})/gi;
11
+ export function redactSecrets(input) {
12
+ let out = input;
13
+ for (const { name, re } of SECRET_PATTERNS) {
14
+ out = out.replace(re, `[REDACTED:${name}]`);
15
+ }
16
+ out = out.replace(SECRET_KEY_HINT, (_match, key) => `${key}=[REDACTED]`);
17
+ return out;
18
+ }
19
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAmC;IACtD,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,sBAAsB,EAAE;IAC9C,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,4BAA4B,EAAE;IACvD,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,4BAA4B,EAAE;IACpD,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,6BAA6B,EAAE;IACzD,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,mBAAmB,EAAE;IACnD,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,6EAA6E,EAAE;IAC1G,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,sDAAsD,EAAE;CAC3F,CAAC;AAEF,MAAM,eAAe,GAAG,+GAA+G,CAAC;AAExI,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,eAAe,EAAE,CAAC;QAC3C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,aAAa,IAAI,GAAG,CAAC,CAAC;IAC9C,CAAC;IACD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,GAAW,EAAE,EAAE,CAAC,GAAG,GAAG,aAAa,CAAC,CAAC;IACjF,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { LoadedConfig } from "../policy/config.js";
2
+ import type { GuidanceFile, ReviewPacket } from "@momentiq/dark-factory-schemas";
3
+ export interface BuildPacketOptions {
4
+ ref?: string;
5
+ cwd?: string;
6
+ trustedSurfaceRef?: string;
7
+ }
8
+ export declare function buildReviewPacket(loaded: LoadedConfig, options?: BuildPacketOptions): Promise<ReviewPacket>;
9
+ export declare function readContainedFiles(repoRoot: string, paths: string[]): GuidanceFile[];
10
+ //# sourceMappingURL=rebind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rebind.d.ts","sourceRoot":"","sources":["../../src/trusted-surface/rebind.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAaxD,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EAEb,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IAOb,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAID,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,YAAY,CAAC,CA+CvB;AAoBD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAoBpF"}