@abelxiaoxing/cadence 1.1.0 → 1.2.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.
- package/README.md +19 -3
- package/agents/implementation-worker.md +17 -11
- package/config/routes.example.json +0 -2
- package/package.json +2 -2
- package/prompts/abel-design.md +77 -17
- package/prompts/abel-diagnose.md +2 -0
- package/prompts/abel-implement.md +23 -11
- package/skills/abel-workflow/SKILL.md +42 -5
- package/src/agent-registry.ts +0 -1
- package/src/candidate-patch.ts +250 -0
- package/src/child-session.ts +27 -24
- package/src/contracts.ts +19 -10
- package/src/control-contracts.ts +15 -62
- package/src/delivery-compiler.ts +47 -17
- package/src/design-control.ts +1053 -0
- package/src/design-journal.ts +1616 -0
- package/src/index.ts +626 -196
- package/src/packet-runtime.ts +6 -6
- package/src/route-policy.ts +45 -17
- package/src/run-state.ts +43 -4
- package/src/run-store.ts +103 -15
- package/src/subagent-activity.ts +1 -1
- package/src/submit-tool.ts +149 -49
- package/src/verification-capability.ts +43 -15
- package/src/worker-broker.ts +0 -1
- package/src/workflow-engine.ts +416 -250
- package/agents/contract-reviewer.md +0 -11
package/src/delivery-compiler.ts
CHANGED
|
@@ -21,7 +21,7 @@ import { validateVerificationAdapterCapability } from "./verification-capability
|
|
|
21
21
|
|
|
22
22
|
export const IMPLEMENT_PLAN_SCHEMA_VERSION = 3 as const;
|
|
23
23
|
export const IMPLEMENT_PLAN_PATH = "implement-plan.json" as const;
|
|
24
|
-
export const DELIVERY_RECEIPT_VERSION =
|
|
24
|
+
export const DELIVERY_RECEIPT_VERSION = 4 as const;
|
|
25
25
|
export const GATE_A_RECEIPT_PATH = "gate-a.yaml" as const;
|
|
26
26
|
export const READY_RECEIPT_PATH = "ready.yaml" as const;
|
|
27
27
|
|
|
@@ -35,14 +35,17 @@ export interface DeliveryArtifactBinding {
|
|
|
35
35
|
rawSha256: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export interface GateApprovalProof {
|
|
39
|
+
revision: number;
|
|
40
|
+
contractHash: string;
|
|
41
|
+
recordHash: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
38
44
|
export interface GateAReceipt {
|
|
39
45
|
receiptVersion: typeof DELIVERY_RECEIPT_VERSION;
|
|
40
46
|
change: string;
|
|
41
47
|
schema: string;
|
|
42
|
-
approval:
|
|
43
|
-
approved: true;
|
|
44
|
-
blockingDecisions: 0;
|
|
45
|
-
};
|
|
48
|
+
approval: GateApprovalProof;
|
|
46
49
|
artifacts: DeliveryArtifactBinding[];
|
|
47
50
|
}
|
|
48
51
|
|
|
@@ -65,8 +68,9 @@ export interface ReadyReceipt {
|
|
|
65
68
|
rawSha256: string;
|
|
66
69
|
};
|
|
67
70
|
gateB: {
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
revision: number;
|
|
72
|
+
contractHash: string;
|
|
73
|
+
recordHash: string;
|
|
70
74
|
};
|
|
71
75
|
};
|
|
72
76
|
artifacts: DeliveryArtifactBinding[];
|
|
@@ -320,6 +324,22 @@ function requireReceiptIdentity(
|
|
|
320
324
|
}
|
|
321
325
|
}
|
|
322
326
|
|
|
327
|
+
function normalizeGateProof(value: GateApprovalProof): GateApprovalProof {
|
|
328
|
+
if (
|
|
329
|
+
!isRecord(value) ||
|
|
330
|
+
!exactKeys(value, ["revision", "contractHash", "recordHash"]) ||
|
|
331
|
+
!Number.isSafeInteger(value.revision) ||
|
|
332
|
+
value.revision < 1 ||
|
|
333
|
+
typeof value.contractHash !== "string" ||
|
|
334
|
+
!SHA256.test(value.contractHash) ||
|
|
335
|
+
typeof value.recordHash !== "string" ||
|
|
336
|
+
!SHA256.test(value.recordHash)
|
|
337
|
+
) {
|
|
338
|
+
throw new Error("delivery-gate-proof-invalid");
|
|
339
|
+
}
|
|
340
|
+
return structuredClone(value);
|
|
341
|
+
}
|
|
342
|
+
|
|
323
343
|
function parseCanonicalReceipt<T>(bytes: Uint8Array, code: string): T {
|
|
324
344
|
const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
325
345
|
let parsed: unknown;
|
|
@@ -335,6 +355,7 @@ function parseCanonicalReceipt<T>(bytes: Uint8Array, code: string): T {
|
|
|
335
355
|
export function compileGateAReceipt(input: {
|
|
336
356
|
change: string;
|
|
337
357
|
schema: string;
|
|
358
|
+
approval: GateApprovalProof;
|
|
338
359
|
artifacts: readonly DeliveryArtifactBinding[];
|
|
339
360
|
}): { receipt: GateAReceipt; bytes: Uint8Array; rawSha256: string } {
|
|
340
361
|
requireReceiptIdentity(input.change, input.schema);
|
|
@@ -342,7 +363,7 @@ export function compileGateAReceipt(input: {
|
|
|
342
363
|
receiptVersion: DELIVERY_RECEIPT_VERSION,
|
|
343
364
|
change: input.change,
|
|
344
365
|
schema: input.schema,
|
|
345
|
-
approval:
|
|
366
|
+
approval: normalizeGateProof(input.approval),
|
|
346
367
|
artifacts: normalizeArtifactBindings(input.artifacts),
|
|
347
368
|
};
|
|
348
369
|
const bytes = canonicalBytes(receipt);
|
|
@@ -369,15 +390,17 @@ export function parseGateAReceipt(bytes: Uint8Array): GateAReceipt {
|
|
|
369
390
|
]) ||
|
|
370
391
|
receipt.receiptVersion !== DELIVERY_RECEIPT_VERSION ||
|
|
371
392
|
!isRecord(receipt.approval) ||
|
|
372
|
-
!exactKeys(receipt.approval, ["
|
|
373
|
-
receipt.approval.approved !== true ||
|
|
374
|
-
receipt.approval.blockingDecisions !== 0
|
|
393
|
+
!exactKeys(receipt.approval, ["revision", "contractHash", "recordHash"])
|
|
375
394
|
) {
|
|
376
395
|
throw new Error("gate-a-receipt-invalid");
|
|
377
396
|
}
|
|
378
397
|
requireReceiptIdentity(receipt.change, receipt.schema);
|
|
398
|
+
const approval = normalizeGateProof(receipt.approval);
|
|
379
399
|
const artifacts = normalizeArtifactBindings(receipt.artifacts);
|
|
380
|
-
if (
|
|
400
|
+
if (
|
|
401
|
+
canonicalJson(approval) !== canonicalJson(receipt.approval) ||
|
|
402
|
+
canonicalJson(artifacts) !== canonicalJson(receipt.artifacts)
|
|
403
|
+
) {
|
|
381
404
|
throw new Error("gate-a-receipt-invalid");
|
|
382
405
|
}
|
|
383
406
|
return structuredClone(receipt);
|
|
@@ -415,6 +438,7 @@ export function compileReadyReceipt(input: {
|
|
|
415
438
|
schema: string;
|
|
416
439
|
deliveryRevision: number;
|
|
417
440
|
gateA: { rawSha256: string };
|
|
441
|
+
gateB: GateApprovalProof;
|
|
418
442
|
artifacts: readonly DeliveryArtifactBinding[];
|
|
419
443
|
compiledPlan: CompiledDelivery;
|
|
420
444
|
traceability: DeliveryTraceability;
|
|
@@ -424,7 +448,8 @@ export function compileReadyReceipt(input: {
|
|
|
424
448
|
!Number.isSafeInteger(input.deliveryRevision) ||
|
|
425
449
|
input.deliveryRevision < 1 ||
|
|
426
450
|
!SHA256.test(input.gateA.rawSha256) ||
|
|
427
|
-
input.compiledPlan.plan.changeId !== input.change
|
|
451
|
+
input.compiledPlan.plan.changeId !== input.change ||
|
|
452
|
+
input.gateB.contractHash !== input.compiledPlan.planHash
|
|
428
453
|
) {
|
|
429
454
|
throw new Error("delivery-receipt-invalid");
|
|
430
455
|
}
|
|
@@ -438,7 +463,7 @@ export function compileReadyReceipt(input: {
|
|
|
438
463
|
path: GATE_A_RECEIPT_PATH,
|
|
439
464
|
rawSha256: input.gateA.rawSha256,
|
|
440
465
|
},
|
|
441
|
-
gateB:
|
|
466
|
+
gateB: normalizeGateProof(input.gateB),
|
|
442
467
|
},
|
|
443
468
|
artifacts: normalizeArtifactBindings(input.artifacts),
|
|
444
469
|
plan: structuredClone(input.compiledPlan.receipt.plan),
|
|
@@ -485,9 +510,11 @@ export function parseReadyReceipt(bytes: Uint8Array): ReadyReceipt {
|
|
|
485
510
|
receipt.approvals.gateA.path !== GATE_A_RECEIPT_PATH ||
|
|
486
511
|
!SHA256.test(receipt.approvals.gateA.rawSha256) ||
|
|
487
512
|
!isRecord(receipt.approvals.gateB) ||
|
|
488
|
-
!exactKeys(receipt.approvals.gateB, [
|
|
489
|
-
|
|
490
|
-
|
|
513
|
+
!exactKeys(receipt.approvals.gateB, [
|
|
514
|
+
"revision",
|
|
515
|
+
"contractHash",
|
|
516
|
+
"recordHash",
|
|
517
|
+
]) ||
|
|
491
518
|
!isRecord(receipt.plan) ||
|
|
492
519
|
!exactKeys(receipt.plan, [
|
|
493
520
|
"path",
|
|
@@ -513,8 +540,11 @@ export function parseReadyReceipt(bytes: Uint8Array): ReadyReceipt {
|
|
|
513
540
|
}
|
|
514
541
|
requireReceiptIdentity(receipt.change, receipt.schema);
|
|
515
542
|
const artifacts = normalizeArtifactBindings(receipt.artifacts);
|
|
543
|
+
const gateB = normalizeGateProof(receipt.approvals.gateB);
|
|
516
544
|
const traceability = normalizeTraceability(receipt.traceability);
|
|
517
545
|
if (
|
|
546
|
+
gateB.contractHash !== receipt.plan.canonicalHash ||
|
|
547
|
+
canonicalJson(gateB) !== canonicalJson(receipt.approvals.gateB) ||
|
|
518
548
|
canonicalJson(artifacts) !== canonicalJson(receipt.artifacts) ||
|
|
519
549
|
canonicalJson(traceability) !== canonicalJson(receipt.traceability)
|
|
520
550
|
) {
|