@getripple/core 1.0.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/dist/policy.js ADDED
@@ -0,0 +1,380 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.explainRipplePolicyForIntent = exports.explainRipplePolicyForTarget = exports.resolveRipplePolicyForTarget = exports.loadRipplePolicy = exports.ripplePolicyPath = exports.formatRipplePolicy = exports.defaultRipplePolicy = exports.RIPPLE_POLICY_PATH = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ exports.RIPPLE_POLICY_PATH = ".ripple/policy.json";
30
+ const CONTROL_MODES = ["brainstorm", "function", "file", "task", "pr"];
31
+ const RISK_LEVELS = ["low", "medium", "high", "critical"];
32
+ function defaultRipplePolicy() {
33
+ return {
34
+ protocol: "ripple-policy",
35
+ version: 1,
36
+ defaultMode: "file",
37
+ riskRules: [
38
+ {
39
+ paths: ["src/auth/**", "src/security/**", "src/session/**"],
40
+ risk: "high",
41
+ requireHumanBeforeEdit: true,
42
+ },
43
+ {
44
+ paths: ["src/payments/**", "migrations/**", "database/**", "db/**"],
45
+ risk: "critical",
46
+ requireHumanBeforeEdit: true,
47
+ requireHumanBeforeMerge: true,
48
+ },
49
+ {
50
+ paths: ["docs/**", "**/*.md"],
51
+ risk: "low",
52
+ allowPrMode: true,
53
+ },
54
+ ],
55
+ };
56
+ }
57
+ exports.defaultRipplePolicy = defaultRipplePolicy;
58
+ function formatRipplePolicy(policy = defaultRipplePolicy()) {
59
+ return `${JSON.stringify(policy, null, 2)}\n`;
60
+ }
61
+ exports.formatRipplePolicy = formatRipplePolicy;
62
+ function ripplePolicyPath(workspaceRoot) {
63
+ return path.join(workspaceRoot, exports.RIPPLE_POLICY_PATH);
64
+ }
65
+ exports.ripplePolicyPath = ripplePolicyPath;
66
+ function loadRipplePolicy(workspaceRoot) {
67
+ const policyPath = ripplePolicyPath(workspaceRoot);
68
+ if (!fs.existsSync(policyPath)) {
69
+ return {
70
+ policy: {},
71
+ path: policyPath,
72
+ exists: false,
73
+ };
74
+ }
75
+ const parsed = JSON.parse(fs.readFileSync(policyPath, "utf8"));
76
+ return {
77
+ policy: normalizeRipplePolicy(parsed, policyPath),
78
+ path: policyPath,
79
+ exists: true,
80
+ };
81
+ }
82
+ exports.loadRipplePolicy = loadRipplePolicy;
83
+ function resolveRipplePolicyForTarget(loaded, targetFile) {
84
+ const policy = loaded.policy;
85
+ const source = loaded.exists ? "file" : "built-in";
86
+ const matchedRules = [];
87
+ let risk;
88
+ let requireHumanBeforeEdit = false;
89
+ let requireHumanBeforeMerge = false;
90
+ let allowPrMode;
91
+ (policy.riskRules ?? []).forEach((rule, index) => {
92
+ if (!rule.paths.some((pattern) => matchesPolicyPath(pattern, targetFile))) {
93
+ return;
94
+ }
95
+ matchedRules.push(describeRiskRule(rule, index));
96
+ if (rule.risk) {
97
+ risk = strongestRisk(risk, rule.risk);
98
+ }
99
+ requireHumanBeforeEdit = requireHumanBeforeEdit || rule.requireHumanBeforeEdit === true;
100
+ requireHumanBeforeMerge = requireHumanBeforeMerge || rule.requireHumanBeforeMerge === true;
101
+ if (rule.allowPrMode !== undefined) {
102
+ allowPrMode = allowPrMode === undefined ? rule.allowPrMode : allowPrMode || rule.allowPrMode;
103
+ }
104
+ });
105
+ return {
106
+ source,
107
+ sourcePath: loaded.exists ? exports.RIPPLE_POLICY_PATH : undefined,
108
+ defaultMode: policy.defaultMode,
109
+ risk,
110
+ requireHumanBeforeEdit,
111
+ requireHumanBeforeMerge,
112
+ allowPrMode,
113
+ matchedRules,
114
+ };
115
+ }
116
+ exports.resolveRipplePolicyForTarget = resolveRipplePolicyForTarget;
117
+ function explainRipplePolicyForTarget(loaded, targetFile, options = {}) {
118
+ const resolution = resolveRipplePolicyForTarget(loaded, targetFile);
119
+ const policyDefaultMode = resolution.defaultMode ?? "file";
120
+ const effectiveMode = options.controlMode ?? policyDefaultMode;
121
+ const humanGate = policyHumanGate(resolution, effectiveMode);
122
+ const policySource = resolution.sourcePath ?? "built-in default";
123
+ const why = [];
124
+ const nextSteps = [];
125
+ if (loaded.exists) {
126
+ why.push(`Trust policy loaded from ${policySource}.`);
127
+ }
128
+ else {
129
+ why.push("No .ripple/policy.json found; Ripple will use built-in defaults.");
130
+ nextSteps.push("Run ripple policy init to create repo-level trust defaults.");
131
+ }
132
+ if (resolution.defaultMode) {
133
+ why.push(`Default control mode: ${resolution.defaultMode}.`);
134
+ }
135
+ else {
136
+ why.push("No defaultMode set; Ripple will default to file mode.");
137
+ }
138
+ if (options.controlMode && options.controlMode !== policyDefaultMode) {
139
+ why.push(`Requested control mode overrides policy default: ${options.controlMode}.`);
140
+ }
141
+ if (resolution.matchedRules.length > 0) {
142
+ why.push(`Matched policy rules: ${resolution.matchedRules.join("; ")}.`);
143
+ }
144
+ else {
145
+ why.push("No path-specific policy rule matched this file.");
146
+ if (loaded.exists) {
147
+ nextSteps.push("Add a riskRules entry if this path needs a stronger trust boundary.");
148
+ }
149
+ }
150
+ if (resolution.risk) {
151
+ why.push(`Policy risk: ${resolution.risk}.`);
152
+ }
153
+ if (resolution.requireHumanBeforeEdit) {
154
+ why.push("Policy requires human approval before editing.");
155
+ }
156
+ if (resolution.requireHumanBeforeMerge) {
157
+ why.push("Policy requires human approval before merge.");
158
+ }
159
+ if (effectiveMode === "brainstorm") {
160
+ why.push("Brainstorm mode means no file edits are allowed.");
161
+ }
162
+ if (effectiveMode === "pr") {
163
+ why.push("PR mode still requires human review before merge.");
164
+ }
165
+ if (humanGate === "required-before-edit") {
166
+ nextSteps.push("Ask the human to approve before the agent edits this file.");
167
+ }
168
+ else if (humanGate === "required-before-merge") {
169
+ nextSteps.push("Require human review before merging this change.");
170
+ }
171
+ else {
172
+ nextSteps.push("Use ripple plan to create a saved intent before editing.");
173
+ }
174
+ return {
175
+ protocol: "ripple-policy-explanation",
176
+ version: 1,
177
+ targetFile,
178
+ policySource,
179
+ policyExists: loaded.exists,
180
+ effectiveMode,
181
+ policyRisk: resolution.risk ?? "none",
182
+ humanGate,
183
+ humanRequired: humanGate !== "none",
184
+ allowPrMode: resolution.allowPrMode === true,
185
+ matchedRules: resolution.matchedRules,
186
+ why: uniqueItems(why),
187
+ nextSteps: uniqueItems(nextSteps),
188
+ };
189
+ }
190
+ exports.explainRipplePolicyForTarget = explainRipplePolicyForTarget;
191
+ function explainRipplePolicyForIntent(loaded, intent) {
192
+ const explanation = explainRipplePolicyForTarget(loaded, intent.targetFile, {
193
+ controlMode: intent.controlMode,
194
+ });
195
+ const boundaryGate = humanGateFromIntentBoundary(intent);
196
+ const humanGate = strongestHumanGate(explanation.humanGate, boundaryGate);
197
+ if (humanGate === explanation.humanGate) {
198
+ return explanation;
199
+ }
200
+ return {
201
+ ...explanation,
202
+ humanGate,
203
+ humanRequired: humanGate !== "none",
204
+ why: uniqueItems([
205
+ ...explanation.why,
206
+ ...boundaryGateWhy(intent, boundaryGate),
207
+ ]),
208
+ nextSteps: uniqueItems([
209
+ ...humanGateNextSteps(humanGate),
210
+ ...explanation.nextSteps,
211
+ ]),
212
+ };
213
+ }
214
+ exports.explainRipplePolicyForIntent = explainRipplePolicyForIntent;
215
+ function policyHumanGate(resolution, effectiveMode) {
216
+ if (resolution.requireHumanBeforeEdit || effectiveMode === "brainstorm") {
217
+ return "required-before-edit";
218
+ }
219
+ if (resolution.requireHumanBeforeMerge || effectiveMode === "pr") {
220
+ return "required-before-merge";
221
+ }
222
+ return "none";
223
+ }
224
+ function humanGateFromIntentBoundary(intent) {
225
+ if (intent.controlMode === "brainstorm") {
226
+ return "required-before-edit";
227
+ }
228
+ if (intent.boundaryRisk === "critical" || intent.boundaryRisk === "high") {
229
+ return "required-before-edit";
230
+ }
231
+ if (intent.controlMode === "pr") {
232
+ return "required-before-merge";
233
+ }
234
+ return "none";
235
+ }
236
+ function strongestHumanGate(first, second) {
237
+ return humanGateRank(second) > humanGateRank(first) ? second : first;
238
+ }
239
+ function humanGateRank(gate) {
240
+ if (gate === "required-before-edit") {
241
+ return 2;
242
+ }
243
+ if (gate === "required-before-merge") {
244
+ return 1;
245
+ }
246
+ return 0;
247
+ }
248
+ function boundaryGateWhy(intent, gate) {
249
+ if (gate === "required-before-edit") {
250
+ if (intent.controlMode === "brainstorm") {
251
+ return ["Ripple boundary requires human approval because brainstorm mode does not allow file edits."];
252
+ }
253
+ return [
254
+ `Ripple boundary requires human approval before editing because the saved target is ${intent.boundaryRisk} risk.`,
255
+ ];
256
+ }
257
+ if (gate === "required-before-merge") {
258
+ return ["Ripple boundary requires human review before merge because PR mode was selected."];
259
+ }
260
+ return [];
261
+ }
262
+ function humanGateNextSteps(gate) {
263
+ if (gate === "required-before-edit") {
264
+ return ["Ask the human to approve before the agent edits this file."];
265
+ }
266
+ if (gate === "required-before-merge") {
267
+ return ["Require human review before merging this change."];
268
+ }
269
+ return ["Use ripple plan to create a saved intent before editing."];
270
+ }
271
+ function normalizeRipplePolicy(value, sourcePath) {
272
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
273
+ throw new Error(`${sourcePath} must contain a JSON object.`);
274
+ }
275
+ const raw = value;
276
+ if (raw.protocol !== undefined && raw.protocol !== "ripple-policy") {
277
+ throw new Error(`${sourcePath} has unsupported protocol: ${String(raw.protocol)}`);
278
+ }
279
+ if (raw.version !== undefined && raw.version !== 1) {
280
+ throw new Error(`${sourcePath} has unsupported version: ${String(raw.version)}`);
281
+ }
282
+ if (raw.defaultMode !== undefined && !isControlMode(raw.defaultMode)) {
283
+ throw new Error(`${sourcePath} defaultMode must be one of: ${CONTROL_MODES.join(", ")}`);
284
+ }
285
+ return {
286
+ protocol: raw.protocol,
287
+ version: raw.version,
288
+ defaultMode: raw.defaultMode,
289
+ riskRules: normalizeRiskRules(raw.riskRules, sourcePath),
290
+ };
291
+ }
292
+ function normalizeRiskRules(value, sourcePath) {
293
+ if (value === undefined) {
294
+ return [];
295
+ }
296
+ if (!Array.isArray(value)) {
297
+ throw new Error(`${sourcePath} riskRules must be an array.`);
298
+ }
299
+ return value.map((rule, index) => {
300
+ if (!rule || typeof rule !== "object" || Array.isArray(rule)) {
301
+ throw new Error(`${sourcePath} riskRules[${index}] must be an object.`);
302
+ }
303
+ if (!Array.isArray(rule.paths) || rule.paths.some((item) => typeof item !== "string")) {
304
+ throw new Error(`${sourcePath} riskRules[${index}].paths must be a string array.`);
305
+ }
306
+ if (rule.risk !== undefined && !isRisk(rule.risk)) {
307
+ throw new Error(`${sourcePath} riskRules[${index}].risk must be one of: ${RISK_LEVELS.join(", ")}`);
308
+ }
309
+ return {
310
+ paths: rule.paths,
311
+ risk: rule.risk,
312
+ requireHumanBeforeEdit: rule.requireHumanBeforeEdit === true,
313
+ requireHumanBeforeMerge: rule.requireHumanBeforeMerge === true,
314
+ allowPrMode: rule.allowPrMode,
315
+ };
316
+ });
317
+ }
318
+ function describeRiskRule(rule, index) {
319
+ const risk = rule.risk ? ` risk=${rule.risk}` : "";
320
+ return `riskRules[${index}] paths=${rule.paths.join(",")}${risk}`;
321
+ }
322
+ function matchesPolicyPath(pattern, filePath) {
323
+ const normalizedPattern = normalizePolicyPath(pattern);
324
+ const normalizedFile = normalizePolicyPath(filePath);
325
+ const hasGlob = normalizedPattern.includes("*");
326
+ if (!hasGlob) {
327
+ return normalizedFile === normalizedPattern || normalizedFile.startsWith(`${normalizedPattern}/`);
328
+ }
329
+ return globPatternToRegExp(normalizedPattern).test(normalizedFile);
330
+ }
331
+ function normalizePolicyPath(value) {
332
+ return value.replace(/\\/g, "/").replace(/^\/+/, "").toLowerCase();
333
+ }
334
+ function globPatternToRegExp(pattern) {
335
+ let source = "^";
336
+ for (let i = 0; i < pattern.length; i++) {
337
+ const char = pattern[i];
338
+ if (char === "*" && pattern[i + 1] === "*") {
339
+ source += ".*";
340
+ i++;
341
+ continue;
342
+ }
343
+ if (char === "*") {
344
+ source += "[^/]*";
345
+ continue;
346
+ }
347
+ source += escapeRegExp(char);
348
+ }
349
+ source += "$";
350
+ return new RegExp(source);
351
+ }
352
+ function escapeRegExp(value) {
353
+ return value.replace(/[\\^$+?.()|[\]{}]/g, "\\$&");
354
+ }
355
+ function strongestRisk(first, second) {
356
+ if (!first) {
357
+ return second;
358
+ }
359
+ return riskRank(second) > riskRank(first) ? second : first;
360
+ }
361
+ function riskRank(risk) {
362
+ return RISK_LEVELS.indexOf(risk);
363
+ }
364
+ function isControlMode(value) {
365
+ return CONTROL_MODES.includes(value);
366
+ }
367
+ function isRisk(value) {
368
+ return RISK_LEVELS.includes(value);
369
+ }
370
+ function uniqueItems(items) {
371
+ const seen = new Set();
372
+ return items.filter((item) => {
373
+ if (seen.has(item)) {
374
+ return false;
375
+ }
376
+ seen.add(item);
377
+ return true;
378
+ });
379
+ }
380
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { RippleAdapterDetectionSummary } from "./adapters";
2
+ import { GraphEngine } from "./graph";
3
+ export declare const RIPPLE_CI_WORKFLOW_PATH = ".github/workflows/ripple.yml";
4
+ export type RippleReadinessCheck = {
5
+ ok: boolean;
6
+ detail: string;
7
+ fix?: string;
8
+ };
9
+ export type RippleEnforcementLevel = "none" | "advisory" | "drift-check-ready" | "ci-gate-ready";
10
+ export type RippleEnforcementReadiness = {
11
+ level: RippleEnforcementLevel;
12
+ summary: string;
13
+ canGuideAgents: boolean;
14
+ canDetectDrift: boolean;
15
+ canBlockInCi: boolean;
16
+ explicitPolicy: RippleReadinessCheck;
17
+ gaps: string[];
18
+ };
19
+ export type RippleReadinessSummary = {
20
+ status: "ready" | "needs_setup";
21
+ workspace: string;
22
+ sourceFiles: number;
23
+ symbols: number;
24
+ callEdges: number;
25
+ adapterSupport: RippleAdapterDetectionSummary;
26
+ enforcement: RippleEnforcementReadiness;
27
+ checks: {
28
+ graph: RippleReadinessCheck;
29
+ git: RippleReadinessCheck;
30
+ ciWorkflow: RippleReadinessCheck;
31
+ latestIntent: RippleReadinessCheck;
32
+ };
33
+ nextSteps: string[];
34
+ };
35
+ export declare function buildRippleReadinessSummary(workspaceRoot: string, engine: GraphEngine): RippleReadinessSummary;
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.buildRippleReadinessSummary = exports.RIPPLE_CI_WORKFLOW_PATH = void 0;
27
+ const fs = __importStar(require("fs"));
28
+ const path = __importStar(require("path"));
29
+ const child_process_1 = require("child_process");
30
+ const adapters_1 = require("./adapters");
31
+ const change_intent_1 = require("./change-intent");
32
+ exports.RIPPLE_CI_WORKFLOW_PATH = ".github/workflows/ripple.yml";
33
+ function buildRippleReadinessSummary(workspaceRoot, engine) {
34
+ const sourceFiles = engine.graph.files.size;
35
+ const symbols = engine.graph.symbols.size;
36
+ const callEdges = countCallEdges(engine);
37
+ const adapterSupport = (0, adapters_1.detectWorkspaceAdapters)(workspaceRoot);
38
+ const workflowPath = path.join(workspaceRoot, exports.RIPPLE_CI_WORKFLOW_PATH);
39
+ const latestIntentPath = (0, change_intent_1.defaultChangeIntentPath)(workspaceRoot);
40
+ const policyPath = path.join(workspaceRoot, ".ripple", "policy.json");
41
+ const graphOk = sourceFiles > 0;
42
+ const gitOk = isGitWorktree(workspaceRoot);
43
+ const ciWorkflowOk = fs.existsSync(workflowPath);
44
+ const latestIntentOk = fs.existsSync(latestIntentPath);
45
+ const explicitPolicyOk = fs.existsSync(policyPath);
46
+ const checks = {
47
+ graph: {
48
+ ok: graphOk,
49
+ detail: graphOk
50
+ ? `${sourceFiles} source files, ${symbols} symbols, ${callEdges} call edges`
51
+ : "No supported source files were found",
52
+ fix: graphOk ? undefined : "Run Ripple from a JavaScript, TypeScript, or Python repo root.",
53
+ },
54
+ git: {
55
+ ok: gitOk,
56
+ detail: gitOk ? "Inside a git worktree" : "Not inside a git worktree",
57
+ fix: gitOk ? undefined : "Run Ripple inside a git repository.",
58
+ },
59
+ ciWorkflow: {
60
+ ok: ciWorkflowOk,
61
+ detail: ciWorkflowOk
62
+ ? exports.RIPPLE_CI_WORKFLOW_PATH
63
+ : "Missing .github/workflows/ripple.yml",
64
+ fix: ciWorkflowOk ? undefined : "Run ripple init.",
65
+ },
66
+ latestIntent: {
67
+ ok: latestIntentOk,
68
+ detail: latestIntentOk
69
+ ? formatWorkspacePath(workspaceRoot, latestIntentPath)
70
+ : "Missing .ripple/intents/latest.json",
71
+ fix: latestIntentOk
72
+ ? undefined
73
+ : "Run ripple plan --file <file> --task \"<task>\" --save before CI.",
74
+ },
75
+ };
76
+ const enforcement = buildEnforcementReadiness({
77
+ graphOk,
78
+ gitOk,
79
+ ciWorkflowOk,
80
+ latestIntentOk,
81
+ explicitPolicyOk,
82
+ });
83
+ const nextSteps = Object.values(checks)
84
+ .map((check) => check.fix)
85
+ .filter((fix) => Boolean(fix));
86
+ if (nextSteps.length === 0) {
87
+ nextSteps.push("Run ripple ci --base origin/main --intent latest --github-annotations.");
88
+ }
89
+ return {
90
+ status: Object.values(checks).every((check) => check.ok) ? "ready" : "needs_setup",
91
+ workspace: workspaceRoot,
92
+ sourceFiles,
93
+ symbols,
94
+ callEdges,
95
+ adapterSupport,
96
+ enforcement,
97
+ checks,
98
+ nextSteps,
99
+ };
100
+ }
101
+ exports.buildRippleReadinessSummary = buildRippleReadinessSummary;
102
+ function buildEnforcementReadiness(input) {
103
+ const canGuideAgents = input.graphOk;
104
+ const canDetectDrift = input.graphOk && input.gitOk && input.latestIntentOk;
105
+ const canBlockInCi = canDetectDrift && input.ciWorkflowOk;
106
+ const level = enforcementLevel({
107
+ canGuideAgents,
108
+ canDetectDrift,
109
+ canBlockInCi,
110
+ });
111
+ const gaps = enforcementGaps(input);
112
+ return {
113
+ level,
114
+ summary: enforcementSummary(level),
115
+ canGuideAgents,
116
+ canDetectDrift,
117
+ canBlockInCi,
118
+ explicitPolicy: {
119
+ ok: input.explicitPolicyOk,
120
+ detail: input.explicitPolicyOk
121
+ ? ".ripple/policy.json"
122
+ : "Using built-in policy defaults",
123
+ fix: input.explicitPolicyOk
124
+ ? undefined
125
+ : "Run ripple policy init to make repo trust boundaries explicit.",
126
+ },
127
+ gaps,
128
+ };
129
+ }
130
+ function enforcementLevel(input) {
131
+ if (input.canBlockInCi) {
132
+ return "ci-gate-ready";
133
+ }
134
+ if (input.canDetectDrift) {
135
+ return "drift-check-ready";
136
+ }
137
+ if (input.canGuideAgents) {
138
+ return "advisory";
139
+ }
140
+ return "none";
141
+ }
142
+ function enforcementSummary(level) {
143
+ if (level === "ci-gate-ready") {
144
+ return "Ripple can guide agents, detect drift, and fail CI when the saved intent or boundary is violated.";
145
+ }
146
+ if (level === "drift-check-ready") {
147
+ return "Ripple can guide agents and detect drift locally, but CI blocking is not installed yet.";
148
+ }
149
+ if (level === "advisory") {
150
+ return "Ripple can provide context, but saved-intent drift checks or CI blocking are not fully ready.";
151
+ }
152
+ return "Ripple cannot enforce or guide safely until a supported repo graph is available.";
153
+ }
154
+ function enforcementGaps(input) {
155
+ const gaps = [];
156
+ if (!input.graphOk) {
157
+ gaps.push("No supported source graph is available.");
158
+ }
159
+ if (!input.gitOk) {
160
+ gaps.push("Git worktree is required for changed-file and CI drift checks.");
161
+ }
162
+ if (!input.latestIntentOk) {
163
+ gaps.push("No latest saved intent exists, so Ripple cannot compare agent work to a plan.");
164
+ }
165
+ if (!input.ciWorkflowOk) {
166
+ gaps.push("Ripple setup is missing the CI workflow, so unsafe changes cannot be blocked in PR checks.");
167
+ }
168
+ if (!input.explicitPolicyOk) {
169
+ gaps.push("No explicit .ripple/policy.json exists; Ripple is using built-in policy defaults.");
170
+ }
171
+ return gaps;
172
+ }
173
+ function countCallEdges(engine) {
174
+ let count = 0;
175
+ engine.graph.symbols.forEach((symbol) => {
176
+ count += symbol.calls.size;
177
+ });
178
+ return count;
179
+ }
180
+ function isGitWorktree(workspaceRoot) {
181
+ try {
182
+ const output = (0, child_process_1.execFileSync)("git", ["rev-parse", "--is-inside-work-tree"], {
183
+ cwd: workspaceRoot,
184
+ encoding: "utf8",
185
+ stdio: ["ignore", "pipe", "ignore"],
186
+ });
187
+ return output.trim() === "true";
188
+ }
189
+ catch {
190
+ return false;
191
+ }
192
+ }
193
+ function formatWorkspacePath(workspaceRoot, filePath) {
194
+ const relative = path.relative(workspaceRoot, filePath);
195
+ if (relative && !relative.startsWith("..") && !path.isAbsolute(relative)) {
196
+ return relative.split(path.sep).join("/");
197
+ }
198
+ return filePath;
199
+ }
200
+ //# sourceMappingURL=readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readiness.js","sourceRoot":"","sources":["../src/readiness.ts"],"names":[],"mappings":"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"}