@cassiomc1/forgeloop 1.3.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/.github/copilot-instructions.md +1 -0
  2. package/AGENTS.md +1 -0
  3. package/CLAUDE.md +1 -0
  4. package/DOCS_INDEX.md +20 -8
  5. package/EXECUTION_STATE.md +60 -0
  6. package/LOOP_ENGINEERING.md +135 -5
  7. package/LOOP_SYSTEM_DESIGN.md +54 -1
  8. package/PROTOCOL_INTEGRATION.md +87 -0
  9. package/QUALITY_SCORECARD.md +2 -0
  10. package/README.md +69 -9
  11. package/TERMINOLOGY.md +15 -0
  12. package/THIRD_PARTY_NOTICES.md +30 -0
  13. package/THREAT_MODEL.md +59 -1
  14. package/docs/ARTIFACT_REFERENCE.md +183 -0
  15. package/docs/CLI_REFERENCE.md +391 -6
  16. package/docs/CROSS_HARNESS_CONTINUITY.md +23 -0
  17. package/docs/DIAGNOSTIC_MODEL.md +181 -0
  18. package/docs/DOCUMENTATION_GUIDE.md +36 -13
  19. package/docs/EXECUTION_TRACE.md +76 -0
  20. package/docs/GETTING_STARTED.md +1 -0
  21. package/docs/MCP.md +159 -0
  22. package/docs/RECIPES.md +149 -0
  23. package/docs/RELEASE_CHECKLIST_1_4.md +38 -0
  24. package/docs/RELEASE_CHECKLIST_1_5_MCP.md +78 -0
  25. package/docs/TROUBLESHOOTING.md +217 -3
  26. package/docs/UNIVERSAL_INTEGRATION.md +48 -0
  27. package/docs/assets/diagrams/forgeloop-engineering-flow.html +13797 -0
  28. package/docs/assets/diagrams/forgeloop-engineering-flow.receipt.json +37 -0
  29. package/docs/assets/diagrams/forgeloop-engineering-flow.svg +5002 -0
  30. package/docs/diagrams/README.md +55 -0
  31. package/docs/diagrams/forgeloop-engineering-flow.workflow.json +122 -0
  32. package/docs/diagrams/manifest.json +42 -0
  33. package/docs/diagrams/reviews/forgeloop-engineering-flow.review.json +20 -0
  34. package/package.json +21 -8
  35. package/schemas/action.schema.json +100 -0
  36. package/schemas/approval.schema.json +51 -0
  37. package/schemas/capability-policy.schema.json +41 -0
  38. package/schemas/diagnostic-case.schema.json +85 -0
  39. package/schemas/execution-receipt.schema.json +16 -0
  40. package/schemas/hypothesis-disposition.schema.json +16 -0
  41. package/schemas/intervention.schema.json +27 -0
  42. package/schemas/policy-lock.schema.json +1 -0
  43. package/schemas/policy-snapshot.schema.json +2 -0
  44. package/schemas/task-recovery.schema.json +61 -0
  45. package/schemas/trajectory-evaluation.schema.json +64 -0
  46. package/schemas/trajectory-scenario.schema.json +42 -0
  47. package/src/cli.js +267 -347
  48. package/src/commands/action-authorize.js +41 -0
  49. package/src/commands/action-propose.js +10 -0
  50. package/src/commands/action-reconcile.js +10 -0
  51. package/src/commands/action-record.js +47 -0
  52. package/src/commands/action-show.js +10 -0
  53. package/src/commands/action-verify.js +10 -0
  54. package/src/commands/advance.js +7 -2
  55. package/src/commands/approval-request.js +64 -0
  56. package/src/commands/approval-resolve.js +10 -0
  57. package/src/commands/audit.js +5 -0
  58. package/src/commands/baseline.js +3 -3
  59. package/src/commands/eval.js +6 -0
  60. package/src/commands/history.js +18 -0
  61. package/src/commands/init.js +2 -2
  62. package/src/commands/inspect.js +55 -0
  63. package/src/commands/metrics.js +7 -0
  64. package/src/commands/next.js +8 -2
  65. package/src/commands/policy-discover.js +2 -2
  66. package/src/commands/progress.js +6 -2
  67. package/src/commands/record-diagnosis.js +37 -1
  68. package/src/commands/record-hypothesis-disposition.js +45 -0
  69. package/src/commands/record-intervention.js +35 -0
  70. package/src/commands/reflect.js +38 -0
  71. package/src/commands/report.js +9 -1
  72. package/src/commands/run-action.js +18 -0
  73. package/src/commands/status.js +17 -0
  74. package/src/commands/task-create.js +39 -1
  75. package/src/commands/task-list.js +14 -1
  76. package/src/commands/task-lock-status.js +2 -2
  77. package/src/commands/task-recover.js +202 -0
  78. package/src/commands/task-repair-legacy-recovery.js +417 -0
  79. package/src/commands/task-resume.js +172 -0
  80. package/src/commands/task-scope.js +23 -4
  81. package/src/commands/task-show.js +18 -4
  82. package/src/commands/trace.js +34 -0
  83. package/src/commands/validate-protocol.js +40 -15
  84. package/src/core/action-authorization.js +106 -0
  85. package/src/core/action-constants.js +86 -0
  86. package/src/core/action-execution.js +105 -0
  87. package/src/core/action-ledger-projection.js +302 -0
  88. package/src/core/action-model.js +581 -0
  89. package/src/core/action-readiness.js +141 -0
  90. package/src/core/action-reconciliation-policy.js +49 -0
  91. package/src/core/action-reconciliation.js +66 -0
  92. package/src/core/action-verification.js +111 -0
  93. package/src/core/actions.js +462 -0
  94. package/src/core/approvals.js +405 -0
  95. package/src/core/artifact-registry.js +60 -0
  96. package/src/core/audit.js +45 -4
  97. package/src/core/bundles.js +30 -0
  98. package/src/core/capability-policy.js +226 -0
  99. package/src/core/cli-command-definitions.js +260 -5
  100. package/src/core/command-executors.js +543 -0
  101. package/src/core/command-input.js +107 -0
  102. package/src/core/command-runtime.js +117 -0
  103. package/src/core/completion-artifacts.js +39 -15
  104. package/src/core/completion-ownership.js +88 -0
  105. package/src/core/completion-recovery-rebind.js +194 -0
  106. package/src/core/completion.js +70 -0
  107. package/src/core/continuity-reconciliation.js +24 -5
  108. package/src/core/diagnostic-model.js +396 -0
  109. package/src/core/diagnostic-projection.js +51 -0
  110. package/src/core/diagnostic-record.js +360 -0
  111. package/src/core/error-codes.js +461 -1
  112. package/src/core/events.js +171 -2
  113. package/src/core/execution-prerequisites.js +4 -1
  114. package/src/core/execution.js +26 -188
  115. package/src/core/failure-signature.js +70 -0
  116. package/src/core/failure-surface.js +57 -0
  117. package/src/core/filesystem.js +55 -6
  118. package/src/core/history.js +110 -0
  119. package/src/core/hypothesis-projection.js +85 -0
  120. package/src/core/information-gain-projection.js +283 -0
  121. package/src/core/information-gain.js +138 -0
  122. package/src/core/inspect.js +132 -7
  123. package/src/core/integration-invocation-policy.js +217 -0
  124. package/src/core/integration-limits.js +20 -0
  125. package/src/core/integration-resources.js +178 -0
  126. package/src/core/next-action-model.js +94 -0
  127. package/src/core/next-action.js +490 -3
  128. package/src/core/phase.js +42 -22
  129. package/src/core/policy-engine.js +113 -6
  130. package/src/core/preflight-consistency.js +31 -5
  131. package/src/core/preflight.js +19 -2
  132. package/src/core/prepared-execution.js +227 -0
  133. package/src/core/progress.js +41 -4
  134. package/src/core/project-root.js +21 -0
  135. package/src/core/protocol-info.js +61 -0
  136. package/src/core/protocol.js +14 -0
  137. package/src/core/receipt.js +1 -0
  138. package/src/core/reconcile-closure.js +35 -10
  139. package/src/core/recovery-history.js +116 -0
  140. package/src/core/reflection.js +305 -0
  141. package/src/core/resumability.js +57 -3
  142. package/src/core/schema-validation.js +9 -0
  143. package/src/core/strategy-analysis.js +97 -0
  144. package/src/core/task-claim-state.js +272 -0
  145. package/src/core/task-command.js +5 -1
  146. package/src/core/task-conflict-inspection.js +321 -0
  147. package/src/core/task-context.js +32 -29
  148. package/src/core/task-discovery.js +14 -1
  149. package/src/core/task-lock.js +216 -22
  150. package/src/core/task-paths.js +31 -2
  151. package/src/core/task-recovery-migration.js +192 -0
  152. package/src/core/task-recovery.js +205 -0
  153. package/src/core/task-scope.js +33 -1
  154. package/src/core/task-snapshot.js +53 -0
  155. package/src/core/templates.js +9 -0
  156. package/src/core/trace.js +548 -0
  157. package/src/core/trajectory-evaluation.js +71 -0
  158. package/src/core/trajectory-metrics.js +80 -0
  159. package/src/core/transaction.js +36 -2
  160. package/src/core/work-state.js +10 -5
  161. package/src/integration.js +47 -0
  162. package/docs/assets/forgeloop-flow.svg +0 -1
  163. package/docs/forgeloop-flow.mmd +0 -51
@@ -0,0 +1,205 @@
1
+ import { PROTOCOL_VERSION } from "./protocol.js";
2
+ import { LEGACY_RECOVERY_MIGRATION_EVENT } from "./task-recovery-migration.js";
3
+ import { readJsonArtifact, writeJsonArtifact } from "./artifacts.js";
4
+ import {
5
+ E_TASK_RECOVERY_AUTHORITY_INVALID,
6
+ } from "./error-codes.js";
7
+ import { taskArtifactPath } from "./task-paths.js";
8
+ import { getActiveTaskTransaction } from "./transaction.js";
9
+ import { classifyRecoveryHistory } from "./recovery-history.js";
10
+
11
+ export const TASK_RECOVERY_SCHEMA_VERSION = 1;
12
+ export const TASK_RECOVERY_EVENT_TYPES = Object.freeze(new Set([
13
+ "TASK_RECOVERY_RECORDED",
14
+ "OPERATOR_RECOVERY_RECORDED",
15
+ LEGACY_RECOVERY_MIGRATION_EVENT,
16
+ ]));
17
+
18
+ export function createTaskRecovery({
19
+ taskId,
20
+ recoveredAt,
21
+ recoveryId,
22
+ recoveryEventSeq,
23
+ classificationAtRecovery,
24
+ reasonCodes,
25
+ releasedClaims,
26
+ previousPhase,
27
+ previousRevision,
28
+ repositoryFingerprint,
29
+ authority,
30
+ }) {
31
+ const recovery = {
32
+ schemaVersion: TASK_RECOVERY_SCHEMA_VERSION,
33
+ protocolVersion: PROTOCOL_VERSION,
34
+ taskId,
35
+ status: "RECOVERED",
36
+ recoveredAt,
37
+ recoveryId,
38
+ recoveryEventSeq,
39
+ classificationAtRecovery,
40
+ reasonCodes: [...reasonCodes],
41
+ releasedClaims: [...releasedClaims],
42
+ previousPhase,
43
+ previousRevision,
44
+ repositoryFingerprint: { ...repositoryFingerprint },
45
+ authority: { ...authority },
46
+ };
47
+ assertTaskRecoveryAuthority(recovery);
48
+ return recovery;
49
+ }
50
+
51
+ export function assertTaskRecoveryAuthority(recovery) {
52
+ const authority = recovery?.authority;
53
+ const validCaller = authority?.kind === "CALLER_ACKNOWLEDGED" && authority.grantRef === undefined;
54
+ const validHost = authority?.kind === "HOST_ATTESTED"
55
+ && typeof authority.grantRef === "string"
56
+ && authority.grantRef.trim() !== "";
57
+ if (validCaller || validHost) return recovery;
58
+ const error = new Error(
59
+ "Recovery authority must be caller acknowledgement or host attestation with a trusted grant reference",
60
+ );
61
+ error.code = E_TASK_RECOVERY_AUTHORITY_INVALID;
62
+ throw error;
63
+ }
64
+
65
+ export async function readTaskRecovery(target, { taskId, packageRoot } = {}) {
66
+ try {
67
+ const artifact = await readJsonArtifact(target, taskArtifactPath(taskId, "recovery"), "task-recovery", packageRoot);
68
+ assertTaskRecoveryAuthority(artifact.value);
69
+ return artifact;
70
+ } catch (error) {
71
+ if (error.code === "ARTIFACT_MISSING") return null;
72
+ throw error;
73
+ }
74
+ }
75
+
76
+ export function writeTaskRecovery(target, recovery, packageRoot) {
77
+ assertTaskRecoveryAuthority(recovery);
78
+ return writeJsonArtifact(
79
+ target,
80
+ taskArtifactPath(recovery.taskId, "recovery"),
81
+ recovery,
82
+ "task-recovery",
83
+ packageRoot,
84
+ { taskId: recovery.taskId, operation: "write-task-recovery" },
85
+ );
86
+ }
87
+
88
+ export async function clearTaskRecovery(target, { taskId } = {}) {
89
+ const transaction = getActiveTaskTransaction();
90
+ if (!transaction) {
91
+ throw new Error("clearTaskRecovery requires an active task transaction");
92
+ }
93
+ await transaction.stageDelete(taskArtifactPath(taskId, "recovery"));
94
+ }
95
+
96
+ export function isTaskRecovered(recovery) {
97
+ return recovery?.status === "RECOVERED";
98
+ }
99
+
100
+ export async function assertTaskNotRecovered(target, { taskId, packageRoot } = {}) {
101
+ const { assertTaskMutationAllowed } = await import("./task-claim-state.js");
102
+ return assertTaskMutationAllowed(target, { taskId, packageRoot });
103
+ }
104
+
105
+ export function effectiveTaskClaims({
106
+ validatedClaimState = null,
107
+ historicalWriteClaims = null,
108
+ writeClaims = [],
109
+ } = {}) {
110
+ const historical = historicalWriteClaims ?? writeClaims;
111
+ // Only VALIDATED canonical ownership may release claims. A bare
112
+ // `phase === "COMPLETE"` never proves completion ownership.
113
+ const validatedRelease = validatedClaimState?.valid === true
114
+ && ["RELEASED_BY_COMPLETION", "RELEASED_BY_RECOVERY"].includes(validatedClaimState.claimState);
115
+ return validatedRelease ? [] : [...historical];
116
+ }
117
+
118
+ export function taskClaimProjection({
119
+ validatedClaimState = null,
120
+ historicalWriteClaims: suppliedHistoricalClaims = null,
121
+ writeClaims = [],
122
+ } = {}) {
123
+ const historicalWriteClaims = [...(suppliedHistoricalClaims ?? writeClaims)];
124
+ const effectiveWriteClaims = effectiveTaskClaims({
125
+ validatedClaimState,
126
+ historicalWriteClaims,
127
+ });
128
+ const claimState = validatedClaimState?.valid === true
129
+ ? validatedClaimState.claimState
130
+ : "ACTIVE";
131
+ return {
132
+ writeClaims: effectiveWriteClaims,
133
+ historicalWriteClaims,
134
+ effectiveWriteClaims,
135
+ claimState,
136
+ mutationAllowed: claimState === "ACTIVE",
137
+ };
138
+ }
139
+
140
+ function sameList(left, right) {
141
+ return Array.isArray(left)
142
+ && Array.isArray(right)
143
+ && left.length === right.length
144
+ && left.every((value, index) => value === right[index]);
145
+ }
146
+
147
+ function recoveryConsistencyError(message) {
148
+ return { code: "E_TASK_RECOVERY_INCONSISTENT", message };
149
+ }
150
+
151
+ export function validateTaskRecoveryConsistency({
152
+ taskId,
153
+ recovery = null,
154
+ events = [],
155
+ historicalWriteClaims = null,
156
+ recoveryHistory = null,
157
+ } = {}) {
158
+ const history = recoveryHistory ?? classifyRecoveryHistory(events);
159
+ const errors = [...history.errors];
160
+
161
+ if (!recovery) {
162
+ if (history.valid && history.activeRecovery) {
163
+ errors.push(recoveryConsistencyError(
164
+ `Recovery event ${history.activeRecovery.recoveryId} has neither an active recovery artifact nor a resume event`,
165
+ ));
166
+ }
167
+ return errors;
168
+ }
169
+ if (!history.activeRecovery || history.activeRecovery.recoveryId !== recovery.recoveryId) {
170
+ errors.push(recoveryConsistencyError(
171
+ `Recovery artifact ${recovery.recoveryId ?? "unknown"} does not match the active recovery history`,
172
+ ));
173
+ }
174
+ if (recovery.taskId !== taskId) {
175
+ errors.push(recoveryConsistencyError(`Recovery artifact belongs to ${recovery.taskId}, not ${taskId}`));
176
+ }
177
+ const event = events.find((candidate) => candidate.seq === recovery.recoveryEventSeq);
178
+ if (!event || !TASK_RECOVERY_EVENT_TYPES.has(event.event)) {
179
+ errors.push(recoveryConsistencyError(
180
+ `Recovery artifact references missing recovery event seq ${recovery.recoveryEventSeq}`,
181
+ ));
182
+ return errors;
183
+ }
184
+
185
+ const comparisons = [
186
+ [event.taskId === recovery.taskId, "taskId"],
187
+ [event.at === recovery.recoveredAt, "recoveredAt"],
188
+ [event.details?.recoveryId === recovery.recoveryId, "recoveryId"],
189
+ [event.details?.classification === recovery.classificationAtRecovery, "classificationAtRecovery"],
190
+ [sameList(event.details?.reasonCodes, recovery.reasonCodes), "reasonCodes"],
191
+ [sameList(event.details?.releasedClaims, recovery.releasedClaims), "releasedClaims"],
192
+ [event.details?.previousPhase === recovery.previousPhase, "previousPhase"],
193
+ [event.details?.previousRevision === recovery.previousRevision, "previousRevision"],
194
+ [event.details?.currentBranch === recovery.repositoryFingerprint?.branch, "repositoryFingerprint.branch"],
195
+ [event.details?.currentHead === recovery.repositoryFingerprint?.head, "repositoryFingerprint.head"],
196
+ [event.details?.authorityKind === recovery.authority?.kind, "authority.kind"],
197
+ ];
198
+ for (const [matches, field] of comparisons) {
199
+ if (!matches) errors.push(recoveryConsistencyError(`Recovery artifact and ledger disagree on ${field}`));
200
+ }
201
+ if (historicalWriteClaims && !sameList(historicalWriteClaims, recovery.releasedClaims)) {
202
+ errors.push(recoveryConsistencyError("Recovery releasedClaims do not match the task descriptor's historical claims"));
203
+ }
204
+ return errors;
205
+ }
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import {
3
3
  E_TASK_CHANGE_OUTSIDE_SCOPE,
4
+ E_TASK_CLAIM_OWNERSHIP_INCONSISTENT,
4
5
  E_TASK_DESCRIPTOR_INVALID,
5
6
  E_TASK_SCOPE_CONFLICT,
6
7
  E_TASK_SCOPE_DIRTY,
@@ -93,7 +94,9 @@ export function checkScopeConflicts(newClaims, existingTasks = [], currentTaskId
93
94
  // Only non-COMPLETE tasks hold active write claims
94
95
  if (task.phase === "COMPLETE") continue;
95
96
 
96
- const taskClaims = normalizeWriteClaims(task.writeClaims ?? task.descriptor?.writeClaims ?? []);
97
+ const taskClaims = normalizeWriteClaims(task.claimState === undefined
98
+ ? (task.writeClaims ?? task.descriptor?.writeClaims ?? [])
99
+ : (task.effectiveWriteClaims ?? []));
97
100
  for (const newClaim of normalizedNew) {
98
101
  for (const existingClaim of taskClaims) {
99
102
  if (claimsOverlap(newClaim, existingClaim)) {
@@ -112,6 +115,35 @@ export function checkScopeConflicts(newClaims, existingTasks = [], currentTaskId
112
115
  }
113
116
 
114
117
  export function assertNoScopeConflicts(newClaims, existingTasks = [], currentTaskId = null) {
118
+ const normalizedNew = normalizeWriteClaims(newClaims);
119
+ if (normalizedNew.length > 0) {
120
+ const ownershipBlockers = existingTasks.filter((task) => {
121
+ if (task.taskId === currentTaskId) return false;
122
+ if (task.healthy === false) return true;
123
+ if (task.claimState !== "INCONSISTENT" && task.ownershipValid !== false) return false;
124
+ const retainedClaims = normalizeWriteClaims(
125
+ task.effectiveWriteClaims ?? task.writeClaims ?? task.descriptor?.writeClaims ?? [],
126
+ );
127
+ return retainedClaims.length === 0
128
+ || normalizedNew.some((claim) => retainedClaims.some((retained) => claimsOverlap(claim, retained)));
129
+ });
130
+ if (ownershipBlockers.length > 0) {
131
+ const error = new Error(
132
+ `Cannot acquire write claims while task ownership is inconsistent: ${ownershipBlockers
133
+ .map((task) => task.taskId ?? task.taskKey)
134
+ .join(", ")}`,
135
+ );
136
+ error.code = E_TASK_CLAIM_OWNERSHIP_INCONSISTENT;
137
+ error.tasks = ownershipBlockers.map((task) => ({
138
+ taskId: task.taskId ?? null,
139
+ taskKey: task.taskKey ?? null,
140
+ claimState: task.claimState ?? "INCONSISTENT",
141
+ reasonCodes: task.reasonCodes ?? [task.error?.code].filter(Boolean),
142
+ }));
143
+ throw error;
144
+ }
145
+ }
146
+
115
147
  const conflicts = checkScopeConflicts(newClaims, existingTasks, currentTaskId);
116
148
  if (conflicts.length > 0) {
117
149
  const first = conflicts[0];
@@ -0,0 +1,53 @@
1
+ import { readEvents, validateEventLedger } from "./events.js";
2
+ import { readWorkState } from "./work-state.js";
3
+ import { canonicalFingerprint } from "./artifacts.js";
4
+
5
+ function ledgerTail(events) {
6
+ const last = events.at(-1) ?? null;
7
+ return {
8
+ sequence: last?.seq ?? 0,
9
+ hash: last?.hash ?? null,
10
+ };
11
+ }
12
+
13
+ export async function buildTaskSnapshot({
14
+ target,
15
+ packageRoot,
16
+ taskId = null,
17
+ eventsPath = null,
18
+ stateFile = null,
19
+ } = {}) {
20
+ const options = { packageRoot, taskId, ...(eventsPath ? { eventsPath } : {}) };
21
+ const state = await readWorkState(target, { ...options, ...(stateFile ? { statePath: stateFile } : {}) });
22
+ const events = await readEvents(target, packageRoot, options);
23
+ const before = {
24
+ stateRevision: state?.revision ?? null,
25
+ ...ledgerTail(events),
26
+ };
27
+
28
+ const validation = await validateEventLedger(target, packageRoot, options);
29
+
30
+ const rereadState = await readWorkState(target, { ...options, ...(stateFile ? { statePath: stateFile } : {}) });
31
+ const rereadEvents = await readEvents(target, packageRoot, options);
32
+ const after = {
33
+ stateRevision: rereadState?.revision ?? null,
34
+ ...ledgerTail(rereadEvents),
35
+ };
36
+
37
+ const consistent = JSON.stringify(before) === JSON.stringify(after);
38
+
39
+ return {
40
+ consistent,
41
+ taskId: taskId ?? state?.taskId ?? rereadState?.taskId ?? null,
42
+ anchors: before,
43
+ capturedAt: new Date().toISOString(),
44
+ integrity: {
45
+ valid: validation.valid,
46
+ errors: validation.errors,
47
+ eventCount: validation.events.length,
48
+ fingerprint: canonicalFingerprint(validation.events.map(({ seq, event, at }) => ({ seq, event, at }))),
49
+ },
50
+ state: rereadState,
51
+ events: validation.events,
52
+ };
53
+ }
@@ -66,6 +66,15 @@ export const TEMPLATE_PATHS = [
66
66
  "schemas/task-bundle.schema.json",
67
67
  "schemas/authority.schema.json",
68
68
  "schemas/task-descriptor.schema.json",
69
+ "schemas/task-recovery.schema.json",
70
+ "schemas/diagnostic-case.schema.json",
71
+ "schemas/intervention.schema.json",
72
+ "schemas/hypothesis-disposition.schema.json",
73
+ "schemas/action.schema.json",
74
+ "schemas/approval.schema.json",
75
+ "schemas/capability-policy.schema.json",
76
+ "schemas/trajectory-evaluation.schema.json",
77
+ "schemas/trajectory-scenario.schema.json",
69
78
  ];
70
79
 
71
80
  export function getPackageRoot() {