@abelxiaoxing/cadence 1.5.3 → 1.7.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 (38) hide show
  1. package/README.md +61 -1
  2. package/config/plan-draft.example.json +3 -0
  3. package/config/plan-draft.multiple-tasks.example.json +30 -0
  4. package/package.json +1 -1
  5. package/prompts/abel-design.md +33 -3
  6. package/prompts/abel-implement.md +36 -4
  7. package/src/apply-transaction.ts +1 -9
  8. package/src/artifact-store.ts +1 -9
  9. package/src/change-verification.ts +758 -65
  10. package/src/contracts.ts +8 -0
  11. package/src/delivery-compiler.ts +452 -9
  12. package/src/design-control.ts +2 -2
  13. package/src/design-diagnostics.ts +6 -4
  14. package/src/directory-sync.ts +36 -0
  15. package/src/durable-contracts.ts +19 -3
  16. package/src/durable-workflow.ts +47 -38
  17. package/src/implement-continuation.ts +559 -0
  18. package/src/implement-graph.ts +114 -0
  19. package/src/implement-plan.ts +2 -0
  20. package/src/index.ts +179 -1
  21. package/src/operator-cli.mjs +12 -7
  22. package/src/package-state.ts +309 -0
  23. package/src/package-verification.ts +17 -1
  24. package/src/package-workflow.ts +219 -171
  25. package/src/phase-execution.ts +7 -1
  26. package/src/plan-draft-summary.ts +385 -7
  27. package/src/plan-draft.ts +9 -0
  28. package/src/run-store.ts +39 -15
  29. package/src/storage-schema.ts +14 -6
  30. package/src/subagent-activity.ts +3 -1
  31. package/src/verification-capability.ts +17 -5
  32. package/src/verification-environment.ts +20 -2
  33. package/src/workflow-policy.ts +296 -5
  34. package/src/workflow-recovery-policy.ts +2 -0
  35. package/src/workflow-state-machine.ts +400 -131
  36. package/src/workflow-status.ts +251 -59
  37. package/src/workspace-io-worker.mjs +48 -42
  38. package/src/workspace-store.ts +1 -9
@@ -1,5 +1,8 @@
1
1
  import type { ArtifactStore } from "./artifact-store.ts";
2
- import type { StructuredVerificationContract } from "./contracts.ts";
2
+ import type {
3
+ StructuredVerificationContract,
4
+ VerificationInputObservation,
5
+ } from "./contracts.ts";
3
6
  import type { ImplementPlan, PlanTaskDraft } from "./delivery-compiler.ts";
4
7
  import type { RoutePolicy, WorkerRoutePolicy } from "./route-policy.ts";
5
8
 
@@ -15,6 +18,7 @@ import type {
15
18
  WorkflowContextRequest,
16
19
  WorkflowDeliverySource,
17
20
  WorkflowRecoveryFeedback,
21
+ WorkflowVerificationPrerequisite,
18
22
  } from "./workflow-policy.ts";
19
23
 
20
24
  import type { WorkspaceStore } from "./workspace-store.ts";
@@ -38,6 +42,7 @@ export type DurablePhaseVerificationResult =
38
42
  ok: false;
39
43
  kind: "paused" | "retryable" | "approval-needed";
40
44
  code: string;
45
+ inputObservation?: VerificationInputObservation;
41
46
  };
42
47
 
43
48
  export type DurableChangeVerificationResult =
@@ -60,6 +65,7 @@ export type DurableChangeVerificationResult =
60
65
  code: string;
61
66
  failureIdentities?: string[];
62
67
  attributionReliable?: boolean;
68
+ inputObservation?: VerificationInputObservation;
63
69
  };
64
70
 
65
71
  export interface DurableVerificationObservation {
@@ -68,6 +74,8 @@ export interface DurableVerificationObservation {
68
74
  failureIdentities: string[];
69
75
  code?: string;
70
76
  attributionReliable?: boolean;
77
+ /** Code-owned comparable verification obligation, excluding display identity. */
78
+ contractIdentity?: string;
71
79
  }
72
80
 
73
81
  export interface DurableVerificationBaseline {
@@ -89,7 +97,11 @@ export type DurableObservedVerification =
89
97
  | {
90
98
  ok: false;
91
99
  outcome:
92
- | { kind: "paused"; code: string }
100
+ | {
101
+ kind: "paused";
102
+ code: string;
103
+ prerequisite?: WorkflowVerificationPrerequisite;
104
+ }
93
105
  | { kind: "approval-needed"; code: string }
94
106
  | { kind: "operation-cancelled"; code: "cancelled" };
95
107
  };
@@ -175,11 +187,15 @@ export interface DurableExecutionResources {
175
187
  artifacts: ArtifactStore;
176
188
  workspaces: WorkspaceStore;
177
189
  ledgers: Map<number, TaskLedger>;
190
+ /** Run-shared original-baseline observations, independent of delivery revision. */
191
+ baselineLedger?: TaskLedger;
178
192
  baselineRevisionId: string;
193
+ /** Root capture before any authorized boundary expansion; immutable evidence source. */
194
+ originalBaselineRevisionId?: string;
179
195
  currentRevisionId: string;
180
196
  mergeTail: Promise<void>;
181
197
  verificationFact?: object;
182
- baselinePromises: Map<number, Promise<DurableBaselineResult>>;
198
+ baselinePromises: Map<string | number, Promise<DurableBaselineResult>>;
183
199
  environmentIdentity?: string;
184
200
  }
185
201
 
@@ -1,9 +1,4 @@
1
- import {
2
- ChangeVerification,
3
- parseVerificationBaseline,
4
- sha256Bytes,
5
- verificationBaselineFact,
6
- } from "./change-verification.ts";
1
+ import { ChangeVerification, sha256Bytes } from "./change-verification.ts";
7
2
  import type {
8
3
  DurableExecutionResources,
9
4
  DurablePhaseFact,
@@ -358,7 +353,16 @@ class DurableWorkflowComposition
358
353
  const currentRevisionId = input.currentWorkspaceRevisionId;
359
354
  if (!baselineRevisionId || !currentRevisionId)
360
355
  throw new Error("workflow-workspace-revision-unavailable");
361
- workspaces.getRevision(baselineRevisionId);
356
+ let originalBaseline = workspaces.getRevision(baselineRevisionId);
357
+ const ancestors = new Set<string>();
358
+ while (originalBaseline.parentRevisionId !== null) {
359
+ if (ancestors.has(originalBaseline.revisionId))
360
+ throw new Error("workflow-baseline-revision-conflict");
361
+ ancestors.add(originalBaseline.revisionId);
362
+ originalBaseline = workspaces.getRevision(
363
+ originalBaseline.parentRevisionId,
364
+ );
365
+ }
362
366
  workspaces.getRevision(currentRevisionId);
363
367
  let resources!: DurableRunResources;
364
368
  const transactions = new ApplyTransaction({
@@ -385,11 +389,13 @@ class DurableWorkflowComposition
385
389
  ledgers: new Map(),
386
390
  transactions,
387
391
  baselineRevisionId,
392
+ originalBaselineRevisionId: originalBaseline.revisionId,
388
393
  currentRevisionId,
389
394
  mergeTail: Promise.resolve(),
390
395
  baselinePromises: new Map(),
391
396
  closed: false,
392
397
  };
398
+ resources.baselineLedger = this.#ledger(resources, 1);
393
399
  this.#runs.set(input.runId, resources);
394
400
  return resources;
395
401
  }
@@ -729,37 +735,10 @@ class DurableWorkflowComposition
729
735
  }
730
736
  if (!grew) break;
731
737
  }
732
- if (hasVerificationLifecycle(input.plan)) {
733
- const retainedRevisions = new Set(
734
- input.tasks
735
- .filter((task) => !invalidated.has(task.taskId))
736
- .map((task) => task.deliveryRevision),
737
- );
738
- for (const deliveryRevision of retainedRevisions) {
739
- const ledger = this.#ledger(resources, deliveryRevision);
740
- const stored = ledger.durableFact(
741
- this.#verification.baselineFactKey(resources),
742
- );
743
- resources.baselinePromises.delete(deliveryRevision);
744
- if (stored === undefined) continue;
745
- const baseline = parseVerificationBaseline(stored, resources.artifacts);
746
- if (baseline.revisionId === expandedBaseline.revisionId) continue;
747
- if (baseline.revisionId !== input.baselineRevisionId) {
748
- throw new Error("workflow-verification-baseline-conflict");
749
- }
750
- ledger.replaceDurableFact(
751
- this.#verification.baselineFactKey(resources),
752
- stored,
753
- verificationBaselineFact(
754
- {
755
- ...baseline,
756
- revisionId: expandedBaseline.revisionId,
757
- },
758
- resources.artifacts,
759
- ),
760
- );
761
- }
762
- }
738
+ // Boundary expansion changes candidate/apply inputs, never the root capture
739
+ // or its verification observations. Their contract-bound caches revalidate
740
+ // only the obligations changed by this delivery.
741
+ resources.baselinePromises.clear();
763
742
  resources.baselineRevisionId = expandedBaseline.revisionId;
764
743
  resources.currentRevisionId = rebuilt.revisionId;
765
744
  if (hasVerificationLifecycle(input.plan)) {
@@ -932,6 +911,36 @@ class DurableWorkflowComposition
932
911
  runAttempt(input: Parameters<WorkflowWorker["runAttempt"]>[0]) {
933
912
  return this.#phase.runAttempt(input);
934
913
  }
914
+
915
+ async prepareTask(input: Parameters<WorkflowWorker["runAttempt"]>[0]) {
916
+ const resources = await this.#prepareResources(input, input.signal);
917
+ const workspace = {
918
+ baselineRevisionId: resources.baselineRevisionId,
919
+ currentWorkspaceRevisionId: resources.currentRevisionId,
920
+ };
921
+ if (hasVerificationLifecycle(input.plan)) {
922
+ const captured = await this.#verification.ensureVerificationBaseline({
923
+ resources,
924
+ ledger: this.#ledger(resources, input.deliveryRevision),
925
+ taskId: input.taskId,
926
+ signal: input.signal,
927
+ });
928
+ if (!captured.ok)
929
+ return {
930
+ ...captured.outcome,
931
+ ...workspace,
932
+ ...(captured.outcome.kind === "paused"
933
+ ? {
934
+ verification: {
935
+ scope: "baseline" as const,
936
+ attribution: "environment" as const,
937
+ },
938
+ }
939
+ : {}),
940
+ };
941
+ }
942
+ return { kind: "prepared" as const, ...workspace };
943
+ }
935
944
  hasPendingVerification(input: Parameters<WorkflowWorker["runAttempt"]>[0]) {
936
945
  return this.#phase.hasPendingVerification(input);
937
946
  }