@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.
- package/LICENSE +201 -0
- package/README.md +150 -0
- package/dist/adapters/_shared.d.ts +45 -0
- package/dist/adapters/_shared.d.ts.map +1 -0
- package/dist/adapters/_shared.js +200 -0
- package/dist/adapters/_shared.js.map +1 -0
- package/dist/adapters/codex-sdk.d.ts +279 -0
- package/dist/adapters/codex-sdk.d.ts.map +1 -0
- package/dist/adapters/codex-sdk.js +930 -0
- package/dist/adapters/codex-sdk.js.map +1 -0
- package/dist/adapters/critic-result-schema.d.ts +215 -0
- package/dist/adapters/critic-result-schema.d.ts.map +1 -0
- package/dist/adapters/critic-result-schema.js +153 -0
- package/dist/adapters/critic-result-schema.js.map +1 -0
- package/dist/adapters/critic.d.ts +62 -0
- package/dist/adapters/critic.d.ts.map +1 -0
- package/dist/adapters/critic.js +79 -0
- package/dist/adapters/critic.js.map +1 -0
- package/dist/adapters/cursor-sdk.d.ts +153 -0
- package/dist/adapters/cursor-sdk.d.ts.map +1 -0
- package/dist/adapters/cursor-sdk.js +818 -0
- package/dist/adapters/cursor-sdk.js.map +1 -0
- package/dist/adapters/gemini-sdk.d.ts +113 -0
- package/dist/adapters/gemini-sdk.d.ts.map +1 -0
- package/dist/adapters/gemini-sdk.js +532 -0
- package/dist/adapters/gemini-sdk.js.map +1 -0
- package/dist/adapters/grok-direct-sdk.d.ts +148 -0
- package/dist/adapters/grok-direct-sdk.d.ts.map +1 -0
- package/dist/adapters/grok-direct-sdk.js +694 -0
- package/dist/adapters/grok-direct-sdk.js.map +1 -0
- package/dist/branch-protection/audit_branch_protection.py +759 -0
- package/dist/branch-protection/index.d.ts +25 -0
- package/dist/branch-protection/index.d.ts.map +1 -0
- package/dist/branch-protection/index.js +70 -0
- package/dist/branch-protection/index.js.map +1 -0
- package/dist/branch-protection/spec-default.yaml +314 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +581 -0
- package/dist/cli.js.map +1 -0
- package/dist/cycle-doc-validator/index.d.ts +43 -0
- package/dist/cycle-doc-validator/index.d.ts.map +1 -0
- package/dist/cycle-doc-validator/index.js +69 -0
- package/dist/cycle-doc-validator/index.js.map +1 -0
- package/dist/cycle-doc-validator/validate_cycle_doc.py +1260 -0
- package/dist/cycle-tracker-sync/attribute_pr_cycle_ref.py +384 -0
- package/dist/cycle-tracker-sync/index.d.ts +20 -0
- package/dist/cycle-tracker-sync/index.d.ts.map +1 -0
- package/dist/cycle-tracker-sync/index.js +71 -0
- package/dist/cycle-tracker-sync/index.js.map +1 -0
- package/dist/cycle-tracker-sync/sync_cycle_trackers.py +1093 -0
- package/dist/evidence/audit-trail.d.ts +59 -0
- package/dist/evidence/audit-trail.d.ts.map +1 -0
- package/dist/evidence/audit-trail.js +283 -0
- package/dist/evidence/audit-trail.js.map +1 -0
- package/dist/evidence/index.d.ts +4 -0
- package/dist/evidence/index.d.ts.map +1 -0
- package/dist/evidence/index.js +29 -0
- package/dist/evidence/index.js.map +1 -0
- package/dist/evidence/per-sha.d.ts +13 -0
- package/dist/evidence/per-sha.d.ts.map +1 -0
- package/dist/evidence/per-sha.js +97 -0
- package/dist/evidence/per-sha.js.map +1 -0
- package/dist/evidence/quality-gates.d.ts +19 -0
- package/dist/evidence/quality-gates.d.ts.map +1 -0
- package/dist/evidence/quality-gates.js +212 -0
- package/dist/evidence/quality-gates.js.map +1 -0
- package/dist/git.d.ts +40 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +414 -0
- package/dist/git.js.map +1 -0
- package/dist/glob.d.ts +4 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +99 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +42 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy/baseline.d.ts +15 -0
- package/dist/policy/baseline.d.ts.map +1 -0
- package/dist/policy/baseline.js +115 -0
- package/dist/policy/baseline.js.map +1 -0
- package/dist/policy/config.d.ts +64 -0
- package/dist/policy/config.d.ts.map +1 -0
- package/dist/policy/config.js +363 -0
- package/dist/policy/config.js.map +1 -0
- package/dist/policy/gate.d.ts +80 -0
- package/dist/policy/gate.d.ts.map +1 -0
- package/dist/policy/gate.js +1019 -0
- package/dist/policy/gate.js.map +1 -0
- package/dist/policy/index.d.ts +7 -0
- package/dist/policy/index.d.ts.map +1 -0
- package/dist/policy/index.js +14 -0
- package/dist/policy/index.js.map +1 -0
- package/dist/policy/merge-queue.d.ts +183 -0
- package/dist/policy/merge-queue.d.ts.map +1 -0
- package/dist/policy/merge-queue.js +310 -0
- package/dist/policy/merge-queue.js.map +1 -0
- package/dist/policy/profile.d.ts +98 -0
- package/dist/policy/profile.d.ts.map +1 -0
- package/dist/policy/profile.js +156 -0
- package/dist/policy/profile.js.map +1 -0
- package/dist/policy/tdd-classifier.d.ts +18 -0
- package/dist/policy/tdd-classifier.d.ts.map +1 -0
- package/dist/policy/tdd-classifier.js +79 -0
- package/dist/policy/tdd-classifier.js.map +1 -0
- package/dist/prompt.d.ts +13 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +175 -0
- package/dist/prompt.js.map +1 -0
- package/dist/report.d.ts +88 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +376 -0
- package/dist/report.js.map +1 -0
- package/dist/runner.d.ts +30 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +456 -0
- package/dist/runner.js.map +1 -0
- package/dist/security.d.ts +2 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +19 -0
- package/dist/security.js.map +1 -0
- package/dist/trusted-surface/rebind.d.ts +10 -0
- package/dist/trusted-surface/rebind.d.ts.map +1 -0
- package/dist/trusted-surface/rebind.js +154 -0
- package/dist/trusted-surface/rebind.js.map +1 -0
- 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 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"AAYA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD"}
|
package/dist/security.js
ADDED
|
@@ -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"}
|