@cassiomc1/forgeloop 1.2.1 → 1.2.2
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/.cursor/rules/project-loop.mdc +1 -1
- package/.github/copilot-instructions.md +1 -1
- package/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/DOCS_INDEX.md +3 -0
- package/ENG/design-code-eng.md +59 -0
- package/ENG/premium-sites-studio-eng.md +28 -0
- package/LOOP_ENGINEERING.md +23 -0
- package/LOOP_SYSTEM_DESIGN.md +9 -5
- package/ORCHESTRATOR_INTEGRATION.md +37 -4
- package/PROTOCOL_INTEGRATION.md +13 -0
- package/README.md +34 -2
- package/TERMINOLOGY.md +10 -0
- package/THIRD_PARTY_NOTICES.md +34 -0
- package/THREAT_MODEL.md +12 -1
- package/docs/ARTIFACT_REFERENCE.md +150 -0
- package/docs/CLI_REFERENCE.md +263 -30
- package/docs/CROSS_HARNESS_CONTINUITY.md +1 -0
- package/docs/DOCUMENTATION_GUIDE.md +41 -4
- package/docs/GETTING_STARTED.md +9 -4
- package/docs/RECIPES.md +31 -1
- package/docs/TROUBLESHOOTING.md +191 -0
- package/package.json +1 -1
- package/schemas/policy-baseline.schema.json +26 -0
- package/schemas/policy-discovery.schema.json +45 -0
- package/schemas/policy-lock.schema.json +16 -0
- package/schemas/policy-rules.schema.json +48 -0
- package/schemas/policy-snapshot.schema.json +16 -0
- package/src/cli.js +69 -1
- package/src/commands/baseline.js +120 -0
- package/src/commands/init.js +304 -6
- package/src/commands/policy-diff.js +51 -0
- package/src/commands/policy-discover.js +42 -0
- package/src/commands/policy-status.js +33 -0
- package/src/commands/profile-interview.js +50 -0
- package/src/commands/reconcile-closure.js +49 -0
- package/src/commands/rule-verify.js +36 -0
- package/src/commands/validate-receipt.js +38 -3
- package/src/core/artifact-registry.js +60 -0
- package/src/core/audit.js +24 -0
- package/src/core/cli-command-definitions.js +114 -7
- package/src/core/cli-metadata.js +1 -1
- package/src/core/completion-artifacts.js +29 -3
- package/src/core/completion.js +101 -10
- package/src/core/error-codes.js +227 -0
- package/src/core/events.js +22 -0
- package/src/core/execution-prerequisites.js +38 -20
- package/src/core/execution.js +20 -3
- package/src/core/native-adapters.js +14 -4
- package/src/core/next-action-model.js +9 -0
- package/src/core/next-action.js +128 -82
- package/src/core/policy-adapters.js +276 -0
- package/src/core/policy-baseline.js +144 -0
- package/src/core/policy-diff.js +133 -0
- package/src/core/policy-discovery.js +225 -0
- package/src/core/policy-engine.js +533 -0
- package/src/core/policy-mutation.js +139 -0
- package/src/core/preflight-consistency.js +23 -15
- package/src/core/preflight.js +65 -1
- package/src/core/reconcile-closure.js +173 -0
- package/src/core/schema-validation.js +6 -0
- package/src/core/task-context.js +11 -0
- package/src/core/task-discovery.js +67 -1
- package/src/core/task-paths.js +9 -0
- package/src/core/templates.js +5 -0
package/src/core/completion.js
CHANGED
|
@@ -11,7 +11,29 @@ import { assertSafePath, ensureWithin, fileExists } from "./filesystem.js";
|
|
|
11
11
|
import { evaluateStartExecutionPrerequisites, hasExecutionStarted } from "./execution-prerequisites.js";
|
|
12
12
|
import { isRecoverableCompletionEvidenceCode } from "./completion-recovery.js";
|
|
13
13
|
import { evaluateTerminalRequirements } from "./evidence-readiness.js";
|
|
14
|
-
import { taskArtifactPath } from "./task-paths.js";
|
|
14
|
+
import { PROJECT_ARTIFACT_PATHS, taskArtifactPath } from "./task-paths.js";
|
|
15
|
+
import { detectPolicyCapability, evaluateTargetPolicy } from "./policy-engine.js";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Canonical completion return statuses shared by the runtime, tests, and
|
|
19
|
+
* documentation conformance. The CLI reference's return-status prose is
|
|
20
|
+
* mechanically checked against this set.
|
|
21
|
+
*/
|
|
22
|
+
export const COMPLETION_STATUSES = Object.freeze(["VALID", "REJECTED"]);
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Canonical completion verification-status values returned by
|
|
26
|
+
* evaluateCompletion. The asymmetric casing (VALID / invalid) is the actual
|
|
27
|
+
* runtime contract and is intentionally preserved; documentation conformance
|
|
28
|
+
* checks documented examples and prose against this exact set, and the runtime
|
|
29
|
+
* derives its output from these same named constants.
|
|
30
|
+
*/
|
|
31
|
+
export const VERIFICATION_STATUS_VALID = "VALID";
|
|
32
|
+
export const VERIFICATION_STATUS_INVALID = "invalid";
|
|
33
|
+
export const VERIFICATION_STATUSES = Object.freeze([
|
|
34
|
+
VERIFICATION_STATUS_VALID,
|
|
35
|
+
VERIFICATION_STATUS_INVALID,
|
|
36
|
+
]);
|
|
15
37
|
|
|
16
38
|
function issue(code, message, artifacts = [], details = {}) {
|
|
17
39
|
return { code, message, artifacts, ...details };
|
|
@@ -74,13 +96,20 @@ function repairNext(error) {
|
|
|
74
96
|
return "Do not edit work-state or receipt manually; recover through supported lifecycle commands.";
|
|
75
97
|
case "E_COMPLETION_RECOVERY_UNAUTHORIZED":
|
|
76
98
|
case "E_COMPLETION_REJECTION_LEDGER_MISMATCH":
|
|
77
|
-
case "
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
case "
|
|
81
|
-
case "
|
|
82
|
-
return "
|
|
83
|
-
case "
|
|
99
|
+
case "E_CYCLE_CLOSED":
|
|
100
|
+
return "Advance the task through valid lifecycle phases (PLANNED -> EXECUTING -> VERIFYING -> REVIEWING).";
|
|
101
|
+
case "E_LEDGER_INVALID":
|
|
102
|
+
case "E_LEDGER_STALE":
|
|
103
|
+
case "E_STATE_LEDGER_MISMATCH":
|
|
104
|
+
return "Inspect the event ledger and repair sequence or integrity violations.";
|
|
105
|
+
case "E_EVIDENCE_MISSING":
|
|
106
|
+
case "E_EVIDENCE_BLOCKED":
|
|
107
|
+
case "E_CHECK_FAILED":
|
|
108
|
+
case "E_REQUIREMENT_UNMET":
|
|
109
|
+
return "Execute and pass all required checks using forgeloop run-check before completion.";
|
|
110
|
+
case "E_CHECK_EXECUTION_PROVENANCE_MISSING":
|
|
111
|
+
return "Re-run checks via forgeloop run-check to ensure ForgeLoop execution provenance.";
|
|
112
|
+
case "E_CONTRACT_PROFILE_STRICT_UNVERIFIED":
|
|
84
113
|
return "Use Standard mode for a fresh target, or verify PROJECT_PROFILE.md before Strict completion.";
|
|
85
114
|
case "E_INSTALLATION_AUTHORITY_REQUIRED":
|
|
86
115
|
case "E_AUTHORITY_INVALID":
|
|
@@ -89,6 +118,28 @@ function repairNext(error) {
|
|
|
89
118
|
return "Do not execute installation-capable verification commands without explicit scoped installation authority; use local equivalents or record NOT_VERIFIED.";
|
|
90
119
|
case "E_VERIFICATION_TOOL_UNAVAILABLE":
|
|
91
120
|
return "Use an available local verifier, an existing equivalent, or record NOT_VERIFIED if installation was not authorized.";
|
|
121
|
+
case "E_NEW_POLICY_VIOLATION":
|
|
122
|
+
return "Resolve the new policy violation or record baseline if adopted debt before completion.";
|
|
123
|
+
case "E_POLICY_WEAKENING":
|
|
124
|
+
return "Restore the original policy configuration or obtain explicit project authority before retrying completion.";
|
|
125
|
+
case "E_CHECK_INERT":
|
|
126
|
+
return "Configure an applicable target scope or mark the inert check unsupported.";
|
|
127
|
+
case "E_CHECK_MUTATION_NOT_DETECTED":
|
|
128
|
+
return "Fix checker logic to properly detect intentional mutation fixtures.";
|
|
129
|
+
case "E_CHECK_MUTATION_EXECUTION_ERROR":
|
|
130
|
+
return "Repair the checker execution path and rerun rule verification.";
|
|
131
|
+
case "E_POLICY_LOCK_MISMATCH":
|
|
132
|
+
return "Re-evaluate effective rules and update policy.lock or restore modified rules.";
|
|
133
|
+
case "E_POLICY_DRIFT":
|
|
134
|
+
case "E_POLICY_DRIFT_UNKNOWN":
|
|
135
|
+
return "Re-verify affected checks or restore original policy.";
|
|
136
|
+
case "E_POLICY_INVALID":
|
|
137
|
+
return "Validate and repair rules.json, baseline.json, or discovery.json against schema.";
|
|
138
|
+
case "E_POLICY_EVALUATION_FAILED":
|
|
139
|
+
return "Inspect policy configuration and checker adapters for unhandled errors.";
|
|
140
|
+
case "E_BASELINE_EXPANSION":
|
|
141
|
+
case "E_BASELINE_RECORD_DURING_ACTIVE_TASK":
|
|
142
|
+
return "Resolve new violations rather than expanding the baseline.";
|
|
92
143
|
default:
|
|
93
144
|
return "Resolve this validator finding in the named artifact before retrying completion.";
|
|
94
145
|
}
|
|
@@ -333,12 +384,52 @@ export async function evaluateCompletion({
|
|
|
333
384
|
}
|
|
334
385
|
}
|
|
335
386
|
|
|
387
|
+
const policyCapability = await detectPolicyCapability(target, packageRoot);
|
|
388
|
+
if (policyCapability === "INVALID") {
|
|
389
|
+
errors.push(issue(
|
|
390
|
+
"E_POLICY_INVALID",
|
|
391
|
+
"Policy configuration or baseline artifacts are malformed or fail schema validation.",
|
|
392
|
+
[PROJECT_ARTIFACT_PATHS.policyRules, PROJECT_ARTIFACT_PATHS.policyBaseline],
|
|
393
|
+
));
|
|
394
|
+
} else if (policyCapability === "AVAILABLE") {
|
|
395
|
+
try {
|
|
396
|
+
const policyEval = await evaluateTargetPolicy({
|
|
397
|
+
target,
|
|
398
|
+
packageRoot,
|
|
399
|
+
taskId: contract?.value?.taskId ?? taskId,
|
|
400
|
+
});
|
|
401
|
+
for (const policyErr of policyEval.errors ?? []) {
|
|
402
|
+
const code = policyErr.code === "NEW_VIOLATION" ? "E_NEW_POLICY_VIOLATION"
|
|
403
|
+
: policyErr.code === "POLICY_WEAKENING" ? "E_POLICY_WEAKENING"
|
|
404
|
+
: policyErr.code === "CHECK_INERT" ? "E_CHECK_INERT"
|
|
405
|
+
: policyErr.code === "CHECK_MUTATION_NOT_DETECTED" ? "E_CHECK_MUTATION_NOT_DETECTED"
|
|
406
|
+
: policyErr.code === "CHECK_MUTATION_EXECUTION_ERROR" ? "E_CHECK_MUTATION_EXECUTION_ERROR"
|
|
407
|
+
: policyErr.code === "POLICY_LOCK_MISMATCH" ? "E_POLICY_LOCK_MISMATCH"
|
|
408
|
+
: policyErr.code === "POLICY_DRIFT_UNKNOWN" ? "E_POLICY_DRIFT_UNKNOWN"
|
|
409
|
+
: policyErr.code === "POLICY_EVALUATION_FAILED" ? "E_POLICY_EVALUATION_FAILED"
|
|
410
|
+
: policyErr.code;
|
|
411
|
+
errors.push(issue(
|
|
412
|
+
code,
|
|
413
|
+
policyErr.why || policyErr.message,
|
|
414
|
+
[PROJECT_ARTIFACT_PATHS.policyLock],
|
|
415
|
+
{ ruleId: policyErr.ruleId, fix: policyErr.fix },
|
|
416
|
+
));
|
|
417
|
+
}
|
|
418
|
+
} catch (error) {
|
|
419
|
+
errors.push(issue(
|
|
420
|
+
"E_POLICY_EVALUATION_FAILED",
|
|
421
|
+
`Policy evaluation threw an unexpected error: ${error.message}`,
|
|
422
|
+
[PROJECT_ARTIFACT_PATHS.policyLock],
|
|
423
|
+
));
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
336
427
|
const sortedErrors = sortIssues(errors);
|
|
337
428
|
const valid = sortedErrors.length === 0;
|
|
338
429
|
return {
|
|
339
|
-
status: valid ?
|
|
430
|
+
status: valid ? COMPLETION_STATUSES[0] : COMPLETION_STATUSES[1],
|
|
340
431
|
taskStatus: valid ? "COMPLETE" : receiptValue?.status === "blocked" ? "BLOCKED" : "INCOMPLETE",
|
|
341
|
-
verificationStatus: valid ?
|
|
432
|
+
verificationStatus: valid ? VERIFICATION_STATUS_VALID : VERIFICATION_STATUS_INVALID,
|
|
342
433
|
publicationStatus: publication,
|
|
343
434
|
productionReadiness: receiptValue?.productionReadiness ?? "not-verified",
|
|
344
435
|
errors: sortedErrors,
|
package/src/core/error-codes.js
CHANGED
|
@@ -39,6 +39,15 @@ export const E_PROGRESS_STALLED = "E_PROGRESS_STALLED";
|
|
|
39
39
|
export const E_DECISION_CRITERION_INVALID = "E_DECISION_CRITERION_INVALID";
|
|
40
40
|
export const E_DECISION_NOT_UNRESOLVED = "E_DECISION_NOT_UNRESOLVED";
|
|
41
41
|
|
|
42
|
+
export const E_RECONCILE_NOT_STALE = "E_RECONCILE_NOT_STALE";
|
|
43
|
+
export const E_RECONCILE_PHASE_INVALID = "E_RECONCILE_PHASE_INVALID";
|
|
44
|
+
export const E_RECONCILE_UNSUPPORTED_DRIFT = "E_RECONCILE_UNSUPPORTED_DRIFT";
|
|
45
|
+
export const E_RECONCILE_LEDGER_INVALID = "E_RECONCILE_LEDGER_INVALID";
|
|
46
|
+
export const E_RECONCILE_REQUIREMENT_UNKNOWN = "E_RECONCILE_REQUIREMENT_UNKNOWN";
|
|
47
|
+
export const E_RECONCILE_EVIDENCE_FAILED = "E_RECONCILE_EVIDENCE_FAILED";
|
|
48
|
+
export const E_REPOSITORY_CHANGED = "E_REPOSITORY_CHANGED";
|
|
49
|
+
export const E_STATE_REVALIDATION_REQUIRED = "E_STATE_REVALIDATION_REQUIRED";
|
|
50
|
+
|
|
42
51
|
/**
|
|
43
52
|
* Public, stable ForgeLoop error and reason codes documented for users and harnesses.
|
|
44
53
|
*/
|
|
@@ -169,6 +178,62 @@ export const PUBLIC_ERROR_CODES = Object.freeze({
|
|
|
169
178
|
meaning: "Modified paths in repository exceed the declared task write claims.",
|
|
170
179
|
safeResolution: "Update write claims with forgeloop task-scope or revert out-of-scope modifications.",
|
|
171
180
|
}),
|
|
181
|
+
E_RECONCILE_NOT_STALE: Object.freeze({
|
|
182
|
+
code: "E_RECONCILE_NOT_STALE",
|
|
183
|
+
category: "lifecycle",
|
|
184
|
+
classification: "PUBLIC_STABLE",
|
|
185
|
+
meaning: "reconcile-closure was invoked for a work-state checkpoint that is already fresh.",
|
|
186
|
+
safeResolution: "No reconciliation is required; continue the normal lifecycle.",
|
|
187
|
+
}),
|
|
188
|
+
E_RECONCILE_PHASE_INVALID: Object.freeze({
|
|
189
|
+
code: "E_RECONCILE_PHASE_INVALID",
|
|
190
|
+
category: "lifecycle",
|
|
191
|
+
classification: "PUBLIC_STABLE",
|
|
192
|
+
meaning: "reconcile-closure was invoked for a task that is not EXECUTING.",
|
|
193
|
+
safeResolution: "reconcile-closure supports EXECUTING tasks whose objective is already satisfied.",
|
|
194
|
+
}),
|
|
195
|
+
E_RECONCILE_UNSUPPORTED_DRIFT: Object.freeze({
|
|
196
|
+
code: "E_RECONCILE_UNSUPPORTED_DRIFT",
|
|
197
|
+
category: "freshness",
|
|
198
|
+
classification: "PUBLIC_STABLE",
|
|
199
|
+
meaning: "Work-state drift includes kinds other than REPOSITORY_CHANGED (contract or required-artifact drift).",
|
|
200
|
+
safeResolution: "Resolve contract or artifact drift through their dedicated recovery surfaces; reconcile-closure only refreshes repository fingerprint drift.",
|
|
201
|
+
}),
|
|
202
|
+
E_RECONCILE_LEDGER_INVALID: Object.freeze({
|
|
203
|
+
code: "E_RECONCILE_LEDGER_INVALID",
|
|
204
|
+
category: "integrity",
|
|
205
|
+
classification: "PUBLIC_STABLE",
|
|
206
|
+
meaning: "The append-only event ledger is not valid, so reconciliation cannot be recorded.",
|
|
207
|
+
safeResolution: "Inspect the ledger errors and repair before reconciling.",
|
|
208
|
+
}),
|
|
209
|
+
E_RECONCILE_REQUIREMENT_UNKNOWN: Object.freeze({
|
|
210
|
+
code: "E_RECONCILE_REQUIREMENT_UNKNOWN",
|
|
211
|
+
category: "verification",
|
|
212
|
+
classification: "PUBLIC_STABLE",
|
|
213
|
+
meaning: "The supplied check id and requirement text do not exactly match a contract verification item of type VERIFICATION.",
|
|
214
|
+
safeResolution: "Supply the exact id and requirement text of an existing contract verification item.",
|
|
215
|
+
}),
|
|
216
|
+
E_RECONCILE_EVIDENCE_FAILED: Object.freeze({
|
|
217
|
+
code: "E_RECONCILE_EVIDENCE_FAILED",
|
|
218
|
+
category: "verification",
|
|
219
|
+
classification: "PUBLIC_STABLE",
|
|
220
|
+
meaning: "The executed objective-satisfaction evidence command did not pass.",
|
|
221
|
+
safeResolution: "Inspect the execution artifact; reconciliation is refused until evidence passes in the current repository.",
|
|
222
|
+
}),
|
|
223
|
+
E_REPOSITORY_CHANGED: Object.freeze({
|
|
224
|
+
code: "E_REPOSITORY_CHANGED",
|
|
225
|
+
category: "freshness",
|
|
226
|
+
classification: "PUBLIC_STABLE",
|
|
227
|
+
meaning: "The repository fingerprint (branch or HEAD) moved after the work-state checkpoint was recorded.",
|
|
228
|
+
safeResolution: "If the task objective is already satisfied in the current repository, run forgeloop reconcile-closure; otherwise resume from a checkpoint that matches the current repository.",
|
|
229
|
+
}),
|
|
230
|
+
E_STATE_REVALIDATION_REQUIRED: Object.freeze({
|
|
231
|
+
code: "E_STATE_REVALIDATION_REQUIRED",
|
|
232
|
+
category: "freshness",
|
|
233
|
+
classification: "PUBLIC_STABLE",
|
|
234
|
+
meaning: "The work-state checkpoint must be revalidated before the lifecycle can continue.",
|
|
235
|
+
safeResolution: "Run forgeloop reconcile-closure for externally satisfied EXECUTING tasks, or inspect the freshness reasons for other drift.",
|
|
236
|
+
}),
|
|
172
237
|
E_DIAGNOSIS_REQUIRED: Object.freeze({
|
|
173
238
|
code: "E_DIAGNOSIS_REQUIRED",
|
|
174
239
|
category: "diagnosis",
|
|
@@ -225,8 +290,145 @@ export const PUBLIC_ERROR_CODES = Object.freeze({
|
|
|
225
290
|
meaning: "A settlement criterion referenced a decision not present in current unresolvedDecisions.",
|
|
226
291
|
safeResolution: "Use the exact current unresolved decision text or update the contract first.",
|
|
227
292
|
}),
|
|
293
|
+
E_CHECK_INERT: Object.freeze({
|
|
294
|
+
code: "E_CHECK_INERT",
|
|
295
|
+
category: "policy",
|
|
296
|
+
classification: "PUBLIC_STABLE",
|
|
297
|
+
meaning: "An enabled check has no effective scope or target files.",
|
|
298
|
+
safeResolution: "Provide an applicable target scope, configure matching files, or mark the rule unsupported.",
|
|
299
|
+
}),
|
|
300
|
+
E_CHECK_MUTATION_NOT_DETECTED: Object.freeze({
|
|
301
|
+
code: "E_CHECK_MUTATION_NOT_DETECTED",
|
|
302
|
+
category: "policy",
|
|
303
|
+
classification: "PUBLIC_STABLE",
|
|
304
|
+
meaning: "A blocking rule checker failed to detect an intentional mutation fixture.",
|
|
305
|
+
safeResolution: "Fix checker logic to properly identify target violations.",
|
|
306
|
+
}),
|
|
307
|
+
E_POLICY_DRIFT: Object.freeze({
|
|
308
|
+
code: "E_POLICY_DRIFT",
|
|
309
|
+
category: "policy",
|
|
310
|
+
classification: "PUBLIC_STABLE",
|
|
311
|
+
meaning: "Active policy lock does not match the policy snapshot captured at task activation.",
|
|
312
|
+
safeResolution: "Re-verify affected checks or restore original policy.",
|
|
313
|
+
}),
|
|
314
|
+
E_POLICY_WEAKENING: Object.freeze({
|
|
315
|
+
code: "E_POLICY_WEAKENING",
|
|
316
|
+
category: "policy",
|
|
317
|
+
classification: "PUBLIC_STABLE",
|
|
318
|
+
meaning: "Policy rules were weakened during task execution without explicit authority.",
|
|
319
|
+
safeResolution: "Restore the original policy configuration.",
|
|
320
|
+
}),
|
|
321
|
+
E_POLICY_LOCK_INVALID: Object.freeze({
|
|
322
|
+
code: "E_POLICY_LOCK_INVALID",
|
|
323
|
+
category: "policy",
|
|
324
|
+
classification: "PUBLIC_STABLE",
|
|
325
|
+
meaning: "Policy lockfile is missing, malformed, or corrupt.",
|
|
326
|
+
safeResolution: "Run forgeloop policy-status or regenerate policy.lock.",
|
|
327
|
+
}),
|
|
328
|
+
E_NEW_POLICY_VIOLATION: Object.freeze({
|
|
329
|
+
code: "E_NEW_POLICY_VIOLATION",
|
|
330
|
+
category: "policy",
|
|
331
|
+
classification: "PUBLIC_STABLE",
|
|
332
|
+
meaning: "New executable policy violation detected that is not present in brownfield baseline.",
|
|
333
|
+
safeResolution: "Fix the violation before completing the task.",
|
|
334
|
+
}),
|
|
335
|
+
E_BASELINE_EXPANSION: Object.freeze({
|
|
336
|
+
code: "E_BASELINE_EXPANSION",
|
|
337
|
+
category: "policy",
|
|
338
|
+
classification: "PUBLIC_STABLE",
|
|
339
|
+
meaning: "Attempted unauthorized addition of new violations to brownfield baseline.",
|
|
340
|
+
safeResolution: "Resolve new violations rather than expanding the baseline.",
|
|
341
|
+
}),
|
|
342
|
+
E_POLICY_PROOF_STALE: Object.freeze({
|
|
343
|
+
code: "E_POLICY_PROOF_STALE",
|
|
344
|
+
category: "policy",
|
|
345
|
+
classification: "PUBLIC_STABLE",
|
|
346
|
+
meaning: "Mutation verification proof is stale due to checker or fixture modifications.",
|
|
347
|
+
safeResolution: "Re-run forgeloop rule-verify to refresh mutation proof.",
|
|
348
|
+
}),
|
|
349
|
+
E_CHECK_MUTATION_EXECUTION_ERROR: Object.freeze({
|
|
350
|
+
code: "E_CHECK_MUTATION_EXECUTION_ERROR",
|
|
351
|
+
category: "policy",
|
|
352
|
+
classification: "PUBLIC_STABLE",
|
|
353
|
+
meaning: "A policy checker threw an unhandled exception while evaluating its mutation fixture.",
|
|
354
|
+
safeResolution: "Repair the checker execution path and rerun rule verification.",
|
|
355
|
+
}),
|
|
356
|
+
E_POLICY_EVALUATION_FAILED: Object.freeze({
|
|
357
|
+
code: "E_POLICY_EVALUATION_FAILED",
|
|
358
|
+
category: "policy",
|
|
359
|
+
classification: "PUBLIC_STABLE",
|
|
360
|
+
meaning: "Policy evaluation threw an unexpected error during execution.",
|
|
361
|
+
safeResolution: "Inspect policy configuration and checker adapters for unhandled errors.",
|
|
362
|
+
}),
|
|
363
|
+
E_POLICY_INVALID: Object.freeze({
|
|
364
|
+
code: "E_POLICY_INVALID",
|
|
365
|
+
category: "policy",
|
|
366
|
+
classification: "PUBLIC_STABLE",
|
|
367
|
+
meaning: "Policy artifact is malformed, corrupt, or schema-invalid.",
|
|
368
|
+
safeResolution: "Validate and repair rules.json, baseline.json, or discovery.json against schema.",
|
|
369
|
+
}),
|
|
370
|
+
E_POLICY_SNAPSHOT_WRITE_FAILED: Object.freeze({
|
|
371
|
+
code: "E_POLICY_SNAPSHOT_WRITE_FAILED",
|
|
372
|
+
category: "policy",
|
|
373
|
+
classification: "PUBLIC_STABLE",
|
|
374
|
+
meaning: "Failed to persist task policy snapshot during preflight.",
|
|
375
|
+
safeResolution: "Ensure the target task directory is writable and repair filesystem permissions.",
|
|
376
|
+
}),
|
|
377
|
+
E_POLICY_LOCK_MISMATCH: Object.freeze({
|
|
378
|
+
code: "E_POLICY_LOCK_MISMATCH",
|
|
379
|
+
category: "policy",
|
|
380
|
+
classification: "PUBLIC_STABLE",
|
|
381
|
+
meaning: "Persisted policy lock digest does not match current effective policy state.",
|
|
382
|
+
safeResolution: "Re-evaluate effective rules and update policy.lock or restore modified rules.",
|
|
383
|
+
}),
|
|
384
|
+
E_POLICY_DRIFT_UNKNOWN: Object.freeze({
|
|
385
|
+
code: "E_POLICY_DRIFT_UNKNOWN",
|
|
386
|
+
category: "policy",
|
|
387
|
+
classification: "PUBLIC_STABLE",
|
|
388
|
+
meaning: "Task policy drift was detected but baseline snapshot details are unavailable.",
|
|
389
|
+
safeResolution: "Re-verify the task under the current policy state.",
|
|
390
|
+
}),
|
|
391
|
+
E_BASELINE_RECORD_DURING_ACTIVE_TASK: Object.freeze({
|
|
392
|
+
code: "E_BASELINE_RECORD_DURING_ACTIVE_TASK",
|
|
393
|
+
category: "policy",
|
|
394
|
+
classification: "PUBLIC_STABLE",
|
|
395
|
+
meaning: "Cannot re-record baseline during an active task with policy snapshot.",
|
|
396
|
+
safeResolution: "Resolve new violations or use monotonic baseline --update.",
|
|
397
|
+
}),
|
|
398
|
+
E_POLICY_INITIALIZATION_FAILED: Object.freeze({
|
|
399
|
+
code: "E_POLICY_INITIALIZATION_FAILED",
|
|
400
|
+
category: "policy",
|
|
401
|
+
classification: "PUBLIC_STABLE",
|
|
402
|
+
meaning: "Executable policy bootstrap could not complete during initialization.",
|
|
403
|
+
safeResolution: "Repair the reported filesystem/schema error and rerun `forgeloop init`. Initialization is restartable while no committed manifest exists.",
|
|
404
|
+
}),
|
|
405
|
+
E_INIT_KIT_CONFLICT: Object.freeze({
|
|
406
|
+
code: "E_INIT_KIT_CONFLICT",
|
|
407
|
+
category: "project-maintenance",
|
|
408
|
+
classification: "PUBLIC_STABLE",
|
|
409
|
+
meaning: "A canonical ForgeLoop kit destination already exists with content that does not match the shipped canonical template.",
|
|
410
|
+
safeResolution: "Inspect the conflicting `.forgeloop/kit/...` file. If it is stale or partial ForgeLoop output, remove or restore it and rerun `forgeloop init`. Do not overwrite unknown content automatically.",
|
|
411
|
+
}),
|
|
228
412
|
});
|
|
229
413
|
|
|
414
|
+
export const E_CHECK_INERT = "E_CHECK_INERT";
|
|
415
|
+
export const E_CHECK_MUTATION_NOT_DETECTED = "E_CHECK_MUTATION_NOT_DETECTED";
|
|
416
|
+
export const E_POLICY_DRIFT = "E_POLICY_DRIFT";
|
|
417
|
+
export const E_POLICY_WEAKENING = "E_POLICY_WEAKENING";
|
|
418
|
+
export const E_POLICY_LOCK_INVALID = "E_POLICY_LOCK_INVALID";
|
|
419
|
+
export const E_NEW_POLICY_VIOLATION = "E_NEW_POLICY_VIOLATION";
|
|
420
|
+
export const E_BASELINE_EXPANSION = "E_BASELINE_EXPANSION";
|
|
421
|
+
export const E_POLICY_PROOF_STALE = "E_POLICY_PROOF_STALE";
|
|
422
|
+
export const E_CHECK_MUTATION_EXECUTION_ERROR = "E_CHECK_MUTATION_EXECUTION_ERROR";
|
|
423
|
+
export const E_POLICY_EVALUATION_FAILED = "E_POLICY_EVALUATION_FAILED";
|
|
424
|
+
export const E_POLICY_INVALID = "E_POLICY_INVALID";
|
|
425
|
+
export const E_POLICY_SNAPSHOT_WRITE_FAILED = "E_POLICY_SNAPSHOT_WRITE_FAILED";
|
|
426
|
+
export const E_POLICY_LOCK_MISMATCH = "E_POLICY_LOCK_MISMATCH";
|
|
427
|
+
export const E_POLICY_DRIFT_UNKNOWN = "E_POLICY_DRIFT_UNKNOWN";
|
|
428
|
+
export const E_BASELINE_RECORD_DURING_ACTIVE_TASK = "E_BASELINE_RECORD_DURING_ACTIVE_TASK";
|
|
429
|
+
export const E_POLICY_INITIALIZATION_FAILED = "E_POLICY_INITIALIZATION_FAILED";
|
|
430
|
+
export const E_INIT_KIT_CONFLICT = "E_INIT_KIT_CONFLICT";
|
|
431
|
+
|
|
230
432
|
export const ALL_KNOWN_ERROR_CODES = Object.freeze(new Set([
|
|
231
433
|
...FAILURE_CODES,
|
|
232
434
|
E_VERIFICATION_TOOL_UNAVAILABLE,
|
|
@@ -255,8 +457,33 @@ export const ALL_KNOWN_ERROR_CODES = Object.freeze(new Set([
|
|
|
255
457
|
E_TASK_SCOPE_DIRTY,
|
|
256
458
|
E_TASK_SCOPE_FROZEN,
|
|
257
459
|
E_TASK_CHANGE_OUTSIDE_SCOPE,
|
|
460
|
+
E_RECONCILE_NOT_STALE,
|
|
461
|
+
E_RECONCILE_PHASE_INVALID,
|
|
462
|
+
E_RECONCILE_UNSUPPORTED_DRIFT,
|
|
463
|
+
E_RECONCILE_LEDGER_INVALID,
|
|
464
|
+
E_RECONCILE_REQUIREMENT_UNKNOWN,
|
|
465
|
+
E_RECONCILE_EVIDENCE_FAILED,
|
|
466
|
+
E_REPOSITORY_CHANGED,
|
|
467
|
+
E_STATE_REVALIDATION_REQUIRED,
|
|
258
468
|
E_TASK_CHANGE_ATTRIBUTION_UNAVAILABLE,
|
|
259
469
|
E_TASK_LAYOUT_LEGACY,
|
|
260
470
|
E_TASK_MIGRATION_INVALID,
|
|
261
471
|
E_TASK_MIGRATION_IDENTITY_MISMATCH,
|
|
472
|
+
E_CHECK_INERT,
|
|
473
|
+
E_CHECK_MUTATION_NOT_DETECTED,
|
|
474
|
+
E_POLICY_DRIFT,
|
|
475
|
+
E_POLICY_WEAKENING,
|
|
476
|
+
E_POLICY_LOCK_INVALID,
|
|
477
|
+
E_NEW_POLICY_VIOLATION,
|
|
478
|
+
E_BASELINE_EXPANSION,
|
|
479
|
+
E_POLICY_PROOF_STALE,
|
|
480
|
+
E_CHECK_MUTATION_EXECUTION_ERROR,
|
|
481
|
+
E_POLICY_EVALUATION_FAILED,
|
|
482
|
+
E_POLICY_INVALID,
|
|
483
|
+
E_POLICY_SNAPSHOT_WRITE_FAILED,
|
|
484
|
+
E_POLICY_LOCK_MISMATCH,
|
|
485
|
+
E_POLICY_DRIFT_UNKNOWN,
|
|
486
|
+
E_BASELINE_RECORD_DURING_ACTIVE_TASK,
|
|
487
|
+
E_POLICY_INITIALIZATION_FAILED,
|
|
488
|
+
E_INIT_KIT_CONFLICT,
|
|
262
489
|
]));
|
package/src/core/events.js
CHANGED
|
@@ -49,11 +49,33 @@ export function validateKnownEventDetails(event) {
|
|
|
49
49
|
case "DECISION_CRITERION_RECORDED":
|
|
50
50
|
assertDecisionCriterionDetails(event.details);
|
|
51
51
|
return;
|
|
52
|
+
case "CHECKPOINT_RECONCILED":
|
|
53
|
+
assertReconcileClosureDetails(event.details);
|
|
54
|
+
return;
|
|
52
55
|
default:
|
|
53
56
|
return;
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
|
|
60
|
+
function assertReconcileClosureDetails(details) {
|
|
61
|
+
if (!details || typeof details !== "object" || Array.isArray(details)) {
|
|
62
|
+
throw protocolError("E_EVENT_INVALID", "CHECKPOINT_RECONCILED requires structured details");
|
|
63
|
+
}
|
|
64
|
+
for (const key of ["checkId", "command", "executionId"]) {
|
|
65
|
+
if (typeof details[key] !== "string") {
|
|
66
|
+
throw protocolError("E_EVENT_INVALID", `CHECKPOINT_RECONCILED details.${key} must be a string`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const key of ["previousBranch", "currentBranch", "previousHead", "currentHead"]) {
|
|
70
|
+
if (typeof details[key] !== "string" && details[key] !== null) {
|
|
71
|
+
throw protocolError("E_EVENT_INVALID", `CHECKPOINT_RECONCILED details.${key} must be a string or null`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (typeof details.exitCode !== "number" || !Number.isInteger(details.exitCode) || details.exitCode < 0) {
|
|
75
|
+
throw protocolError("E_EVENT_INVALID", "CHECKPOINT_RECONCILED details.exitCode must be a non-negative integer");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
57
79
|
function eventHash(event) {
|
|
58
80
|
const { hash, ...body } = event;
|
|
59
81
|
return canonicalFingerprint(body);
|
|
@@ -5,6 +5,7 @@ import { evaluatePreflight, validatePersistedPreflight } from "./preflight.js";
|
|
|
5
5
|
import { readPersistedRoute } from "./route-artifact.js";
|
|
6
6
|
import { stateIdentityErrors } from "./completion-relationships.js";
|
|
7
7
|
import { classifyLoadedWorkState } from "./work-state.js";
|
|
8
|
+
import { taskArtifactPath } from "./task-paths.js";
|
|
8
9
|
|
|
9
10
|
const START_EXECUTION_EVENTS = Object.freeze([
|
|
10
11
|
"CONTRACT_VALIDATED",
|
|
@@ -128,34 +129,51 @@ function prerequisiteLedgerErrors(ledger, taskId, preflight, route) {
|
|
|
128
129
|
return errors;
|
|
129
130
|
}
|
|
130
131
|
|
|
131
|
-
export async function evaluateStartExecutionPrerequisites({
|
|
132
|
+
export async function evaluateStartExecutionPrerequisites({
|
|
133
|
+
target,
|
|
134
|
+
state,
|
|
135
|
+
packageRoot,
|
|
136
|
+
taskId = null,
|
|
137
|
+
contractPath = null,
|
|
138
|
+
routePath = null,
|
|
139
|
+
statePath = null,
|
|
140
|
+
preflightPath = null,
|
|
141
|
+
eventsPath = null,
|
|
142
|
+
} = {}) {
|
|
143
|
+
const effectiveTaskId = taskId ?? null;
|
|
144
|
+
const contractRel = contractPath ?? (effectiveTaskId ? taskArtifactPath(effectiveTaskId, "contract") : ARTIFACT_PATHS.contract);
|
|
145
|
+
const routeRel = routePath ?? (effectiveTaskId ? taskArtifactPath(effectiveTaskId, "route") : ARTIFACT_PATHS.route);
|
|
146
|
+
const stateRel = statePath ?? (effectiveTaskId ? taskArtifactPath(effectiveTaskId, "state") : ARTIFACT_PATHS.state);
|
|
147
|
+
const preflightRel = preflightPath ?? (effectiveTaskId ? taskArtifactPath(effectiveTaskId, "preflight") : ARTIFACT_PATHS.preflight);
|
|
148
|
+
const eventsRel = eventsPath ?? (effectiveTaskId ? taskArtifactPath(effectiveTaskId, "events") : ARTIFACT_PATHS.events);
|
|
149
|
+
|
|
132
150
|
const errors = [];
|
|
133
151
|
const requiredArtifacts = [
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
stateRel,
|
|
153
|
+
contractRel,
|
|
154
|
+
routeRel,
|
|
155
|
+
preflightRel,
|
|
156
|
+
eventsRel,
|
|
139
157
|
];
|
|
140
158
|
if (!state) {
|
|
141
159
|
return {
|
|
142
|
-
errors: [issue("E_PHASE_PREREQUISITE_MISSING", "EXECUTING requires a work state", [
|
|
160
|
+
errors: [issue("E_PHASE_PREREQUISITE_MISSING", "EXECUTING requires a work state", [stateRel])],
|
|
143
161
|
requiredArtifacts,
|
|
144
162
|
};
|
|
145
163
|
}
|
|
146
164
|
|
|
147
165
|
const contract = await load(
|
|
148
|
-
() => readContract(target, packageRoot),
|
|
166
|
+
() => readContract(target, packageRoot, { taskId: effectiveTaskId, contractPath }),
|
|
149
167
|
"E_PHASE_PREREQUISITE_MISSING",
|
|
150
|
-
`EXECUTING requires ${
|
|
151
|
-
[
|
|
168
|
+
`EXECUTING requires ${contractRel}`,
|
|
169
|
+
[contractRel],
|
|
152
170
|
errors,
|
|
153
171
|
);
|
|
154
172
|
const route = await load(
|
|
155
|
-
() => readPersistedRoute(target, packageRoot),
|
|
173
|
+
() => readPersistedRoute(target, packageRoot, { taskId: effectiveTaskId, routePath }),
|
|
156
174
|
"E_PHASE_PREREQUISITE_MISSING",
|
|
157
|
-
`EXECUTING requires ${
|
|
158
|
-
[
|
|
175
|
+
`EXECUTING requires ${routeRel}`,
|
|
176
|
+
[routeRel],
|
|
159
177
|
errors,
|
|
160
178
|
);
|
|
161
179
|
if (!contract || !route) return { errors, requiredArtifacts, contract, route };
|
|
@@ -164,7 +182,7 @@ export async function evaluateStartExecutionPrerequisites({ target, state, packa
|
|
|
164
182
|
errors.push(issue(
|
|
165
183
|
"E_ROUTE_STALE",
|
|
166
184
|
"EXECUTING requires work state and route to match the current contract",
|
|
167
|
-
[
|
|
185
|
+
[stateRel, routeRel, contractRel],
|
|
168
186
|
));
|
|
169
187
|
}
|
|
170
188
|
errors.push(...stateIdentityErrors({ contract, route, state }));
|
|
@@ -172,14 +190,14 @@ export async function evaluateStartExecutionPrerequisites({ target, state, packa
|
|
|
172
190
|
const freshness = await classifyLoadedWorkState({
|
|
173
191
|
target,
|
|
174
192
|
state,
|
|
175
|
-
contractFile:
|
|
193
|
+
contractFile: contractRel,
|
|
176
194
|
});
|
|
177
195
|
errors.push(...freshnessErrors(state, freshness));
|
|
178
196
|
|
|
179
|
-
const preflight = await evaluatePreflight({ target, packageRoot });
|
|
197
|
+
const preflight = await evaluatePreflight({ target, packageRoot, taskId: effectiveTaskId, contractPath, routePath, statePath });
|
|
180
198
|
let persistedPreflight = null;
|
|
181
199
|
try {
|
|
182
|
-
persistedPreflight = await readJsonArtifact(target,
|
|
200
|
+
persistedPreflight = await readJsonArtifact(target, preflightRel, "preflight", packageRoot);
|
|
183
201
|
} catch {
|
|
184
202
|
// validatePersistedPreflight reports the stable, actionable preflight reason.
|
|
185
203
|
}
|
|
@@ -189,16 +207,16 @@ export async function evaluateStartExecutionPrerequisites({ target, state, packa
|
|
|
189
207
|
errors.push(issue(
|
|
190
208
|
"E_PREFLIGHT_GATES_STALE",
|
|
191
209
|
"Work state gate sets do not match the current preflight evaluation",
|
|
192
|
-
[
|
|
210
|
+
[stateRel, preflightRel, ARTIFACT_PATHS.gates],
|
|
193
211
|
));
|
|
194
212
|
}
|
|
195
213
|
|
|
196
|
-
const ledger = await validateEventLedger(target, packageRoot);
|
|
214
|
+
const ledger = await validateEventLedger(target, packageRoot, { taskId: effectiveTaskId, eventsPath });
|
|
197
215
|
errors.push(...prerequisiteLedgerErrors(ledger, contract.value.taskId, preflight, route));
|
|
198
216
|
errors.push(...validateStateLedgerCoherence(state, ledger.events).map((error) => issue(
|
|
199
217
|
error.code,
|
|
200
218
|
error.message,
|
|
201
|
-
[
|
|
219
|
+
[stateRel, eventsRel],
|
|
202
220
|
)));
|
|
203
221
|
errors.push(...persistedPreflightErrors);
|
|
204
222
|
return { errors, requiredArtifacts, contract, route, preflight, persistedPreflight, ledger };
|
package/src/core/execution.js
CHANGED
|
@@ -2,14 +2,14 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
3
|
import { readdir } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { fileExists } from "./filesystem.js";
|
|
5
|
+
import { ensureWithin, fileExists } from "./filesystem.js";
|
|
6
6
|
import {
|
|
7
7
|
ARTIFACT_PATHS,
|
|
8
8
|
executionArtifactPath,
|
|
9
9
|
readJsonArtifact,
|
|
10
10
|
writeJsonArtifact,
|
|
11
11
|
} from "./artifacts.js";
|
|
12
|
-
import { taskExecutionPath } from "./task-paths.js";
|
|
12
|
+
import { taskArtifactPath, taskExecutionPath } from "./task-paths.js";
|
|
13
13
|
import {
|
|
14
14
|
resolveExecutionResolution,
|
|
15
15
|
validateVerificationAuthority,
|
|
@@ -77,6 +77,23 @@ function executeProcess(argv, cwd) {
|
|
|
77
77
|
});
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Resolves where a new execution artifact should be written. Task-scoped
|
|
82
|
+
* execution artifacts require a real modern task namespace (a task.json
|
|
83
|
+
* descriptor). A descriptor-less task is legacy: writing task-scoped here
|
|
84
|
+
* would create a phantom `.forgeloop/task-state/<key>/executions/` namespace
|
|
85
|
+
* that corrupts task discovery. Reads already fall back across both
|
|
86
|
+
* locations, so a legacy execution stays resolvable.
|
|
87
|
+
*/
|
|
88
|
+
export async function resolveExecutionArtifactPath(target, taskId, executionId) {
|
|
89
|
+
if (!taskId) return executionArtifactPath(executionId);
|
|
90
|
+
const descriptorRel = taskArtifactPath(taskId, "descriptor");
|
|
91
|
+
if (await fileExists(ensureWithin(target, descriptorRel))) {
|
|
92
|
+
return taskExecutionPath(taskId, executionId);
|
|
93
|
+
}
|
|
94
|
+
return executionArtifactPath(executionId);
|
|
95
|
+
}
|
|
96
|
+
|
|
80
97
|
export async function runCommandExecution({
|
|
81
98
|
target,
|
|
82
99
|
packageRoot,
|
|
@@ -153,7 +170,7 @@ export async function runCommandExecution({
|
|
|
153
170
|
status: processResult.exitCode === 0 && !processResult.spawnError ? "passed" : "failed",
|
|
154
171
|
exitCode: processResult.exitCode,
|
|
155
172
|
};
|
|
156
|
-
const execPath = executionPath ?? (
|
|
173
|
+
const execPath = executionPath ?? await resolveExecutionArtifactPath(target, taskId, executionId);
|
|
157
174
|
const written = await writeJsonArtifact(target, execPath, execution, "execution", packageRoot);
|
|
158
175
|
return {
|
|
159
176
|
path: written.path,
|
|
@@ -41,10 +41,20 @@ Before changing product or executable files, establish the ForgeLoop contract,
|
|
|
41
41
|
route, required gates, and READY preflight.
|
|
42
42
|
|
|
43
43
|
Before creating or activating new lifecycle state:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
\`forgeloop
|
|
47
|
-
|
|
44
|
+
|
|
45
|
+
1. Inspect existing ForgeLoop tasks first.
|
|
46
|
+
2. Use \`forgeloop task-list --json\` to discover current task namespaces.
|
|
47
|
+
3. If an existing task is selected or identifiable, use
|
|
48
|
+
\`forgeloop next --task <id> --json\` before creating another task.
|
|
49
|
+
4. Reconcile continuity when the selected task has continuity state.
|
|
50
|
+
5. Inspect the checkout before resuming work.
|
|
51
|
+
|
|
52
|
+
A change of harness, model, provider, IDE, process, terminal, or session
|
|
53
|
+
does not create a new task.
|
|
54
|
+
|
|
55
|
+
Legacy singleton state such as \`.forgeloop/work-state.json\` remains
|
|
56
|
+
supported only for backward compatibility and must not be treated as the
|
|
57
|
+
primary modern discovery mechanism.
|
|
48
58
|
|
|
49
59
|
Use the project-local ForgeLoop CLI for lifecycle-owned protocol state.
|
|
50
60
|
Never manually synthesize lifecycle chronology or assign ForgeLoop COMPLETE.
|
|
@@ -22,6 +22,15 @@ export const NEXT_ACTIONS = Object.freeze({
|
|
|
22
22
|
RUN_COMPLETE: "RUN_COMPLETE",
|
|
23
23
|
RESOLVE_STALE_ROUTE: "RESOLVE_STALE_ROUTE",
|
|
24
24
|
RESOLVE_BLOCKER: "RESOLVE_BLOCKER",
|
|
25
|
+
RESTORE_POLICY: "RESTORE_POLICY",
|
|
26
|
+
REVERIFY_AFTER_POLICY_CHANGE: "REVERIFY_AFTER_POLICY_CHANGE",
|
|
27
|
+
VERIFY_RULE: "VERIFY_RULE",
|
|
28
|
+
RESOLVE_INERT_CHECK: "RESOLVE_INERT_CHECK",
|
|
29
|
+
RUN_REQUIRED_CHECK: "RUN_REQUIRED_CHECK",
|
|
30
|
+
REPAIR_CHECKER: "REPAIR_CHECKER",
|
|
31
|
+
REPAIR_POLICY: "REPAIR_POLICY",
|
|
32
|
+
RESTORE_BASELINE: "RESTORE_BASELINE",
|
|
33
|
+
CONTINUE_WITH_EXISTING_BASELINE: "CONTINUE_WITH_EXISTING_BASELINE",
|
|
25
34
|
NONE: "NONE",
|
|
26
35
|
});
|
|
27
36
|
|