@fro.bot/systematic 3.5.5 → 3.5.6

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.
@@ -1,4 +1,24 @@
1
1
  export type OperationObserverReasonCode = 'target-unavailable' | 'command-failed' | 'command-timeout' | 'command-output-limit' | 'file-limit' | 'file-output-limit' | 'file-read-failed' | 'remote-command-failed' | 'remote-command-output-limit' | 'remote-invalid-json' | 'remote-missing-field' | 'remote-item-limit' | 'remote-not-advanced' | 'commit-not-closed';
2
+ export interface RegisteredWorktreeParentIdentity {
3
+ readonly targetRoot: string;
4
+ readonly gitDir: string;
5
+ readonly commonDir: string;
6
+ readonly registeredWorktreeRoots: readonly string[];
7
+ }
8
+ export interface RegisteredWorktreeValidationOptions {
9
+ readonly commandRunner?: OperationObserverCommandRunner;
10
+ readonly limits?: OperationObserverLimits;
11
+ readonly realPath?: (filePath: string) => string;
12
+ }
13
+ export type RegisteredWorktreeValidationResult = {
14
+ readonly status: 'ok';
15
+ readonly targetRoot: string;
16
+ readonly gitDir: string;
17
+ readonly commonDir: string;
18
+ } | {
19
+ readonly status: 'error';
20
+ readonly reasonCode: OperationObserverReasonCode;
21
+ };
2
22
  export type RemoteOperation = 'push' | 'pr-creation' | 'check-readback' | 'review-readback';
3
23
  export type RemoteReadbackPhase = 'before' | 'after';
4
24
  export interface OperationObserverSnapshot {
@@ -73,7 +93,9 @@ export interface OpencodeOperationObserverOptions {
73
93
  }
74
94
  export interface OpencodeOperationObserver {
75
95
  readonly targetDigest: string;
96
+ validateRegisteredWorktree(candidateDirectory: string): RegisteredWorktreeValidationResult;
76
97
  snapshot(): Promise<OperationObserverResult>;
77
98
  remoteSnapshot?(operation: RemoteOperation, phase: RemoteReadbackPhase): Promise<OperationObserverRemoteResult>;
78
99
  }
100
+ export declare function validateRegisteredWorktree(candidateDirectory: string, parentIdentity: RegisteredWorktreeParentIdentity, options?: RegisteredWorktreeValidationOptions): RegisteredWorktreeValidationResult;
79
101
  export declare function createOpencodeOperationObserver(options: OpencodeOperationObserverOptions): OpencodeOperationObserver;
@@ -1,5 +1,5 @@
1
1
  import type { ToolDefinition } from '@opencode-ai/plugin';
2
- import type { OpencodeOperationObserver } from './opencode-operation-observer.js';
2
+ import type { OpencodeOperationObserver, RegisteredWorktreeValidationResult } from './opencode-operation-observer.js';
3
3
  import type { ReceiptClassifier } from './receipt-classifier.js';
4
4
  import { type ReceiptLedger, type ReceiptOperation } from './receipt-ledger.js';
5
5
  import { type EvidenceObservationResult, type RuntimeUnitPolicy, type TransitionPrepareResult, type WorkflowReasonCode, type WorkflowStatus } from './workflow-guard.js';
@@ -26,6 +26,8 @@ export interface OpencodeWorkflowGuardOptions {
26
26
  hostReadback?: OpencodeWorkflowHostReadback;
27
27
  readonly registrationIdentity?: string;
28
28
  readonly sessionSalt?: Uint8Array;
29
+ readonly targetDirectory?: string;
30
+ readonly sessionLocation?: string;
29
31
  }
30
32
  export interface OpencodeWorkflowChildSession {
31
33
  readonly sessionId: string;
@@ -50,5 +52,20 @@ export interface OpencodeWorkflowGuard {
50
52
  prepareTransition(sessionID: unknown, input: unknown): TransitionPrepareResult;
51
53
  startUnit(sessionID: unknown, input: unknown, policy?: RuntimeUnitPolicy): unknown;
52
54
  }
55
+ export type LocalOperationTool = 'write' | 'edit' | 'apply_patch' | 'bash';
56
+ export interface OpencodeOperationTargetDerivationOptions {
57
+ readonly parentTargetRoot: string;
58
+ readonly sessionLocation?: string;
59
+ readonly validateRegisteredWorktree: (candidateDirectory: string) => RegisteredWorktreeValidationResult;
60
+ readonly realPath?: (filePath: string) => string;
61
+ }
62
+ export type OpencodeOperationTargetDerivationResult = {
63
+ readonly status: 'available';
64
+ readonly targetRoot: string;
65
+ } | {
66
+ readonly status: 'unavailable';
67
+ readonly reasonCode: 'target-unavailable';
68
+ };
69
+ export declare function deriveOpencodeOperationTarget(tool: LocalOperationTool, args: unknown, options: OpencodeOperationTargetDerivationOptions): OpencodeOperationTargetDerivationResult;
53
70
  export declare function createOpencodeWorkflowGuard(options: OpencodeWorkflowGuardOptions): OpencodeWorkflowGuard;
54
71
  export {};
@@ -1,6 +1,8 @@
1
1
  import type { ReceiptDigestDomain, ReceiptReadbackFailureCategory, ReceiptReadbackProgression } from './receipt-readback.js';
2
- export declare const RECEIPT_SCHEMA_VERSION: 1;
3
- export declare const RECEIPT_PROTOCOL_VERSION: 1;
2
+ export declare const RECEIPT_SCHEMA_VERSION: 2;
3
+ export declare const RECEIPT_PROTOCOL_VERSION: 2;
4
+ declare const LEGACY_RECEIPT_SCHEMA_VERSION: 1;
5
+ declare const LEGACY_RECEIPT_PROTOCOL_VERSION: 1;
4
6
  export type ReceiptOperation = 'implementation' | 'verification' | 'commit' | 'push' | 'pr-creation' | 'check-readback' | 'review-readback';
5
7
  export type ReceiptClassificationOutcome = 'accepted' | 'rejected' | 'unavailable';
6
8
  export type ReceiptAttribution = 'runtime-verified' | 'unattributed';
@@ -24,12 +26,14 @@ export interface ReceiptContext {
24
26
  workspaceIdentity: string;
25
27
  repositoryIdentity?: string;
26
28
  worktreeIdentity?: string;
29
+ operationTargetIdentity?: string;
27
30
  resourceIdentity?: string;
28
31
  }
29
32
  export interface ReceiptObservationAfter {
30
33
  workspaceIdentity: string;
31
34
  repositoryIdentity?: string;
32
35
  worktreeIdentity?: string;
36
+ operationTargetIdentity?: string;
33
37
  resourceIdentity?: string;
34
38
  }
35
39
  export interface TerminalObservation {
@@ -57,6 +61,7 @@ export interface CanonicalReceiptFields {
57
61
  workspaceDigest: string;
58
62
  repositoryDigest?: string;
59
63
  worktreeDigest?: string;
64
+ operationTargetIdentity?: string;
60
65
  resourceDigest?: string;
61
66
  operation: ReceiptOperation;
62
67
  result: 'success';
@@ -65,8 +70,8 @@ export interface CanonicalReceiptFields {
65
70
  timestamp: number;
66
71
  }
67
72
  export interface ReceiptEnvelope {
68
- schemaVersion: typeof RECEIPT_SCHEMA_VERSION;
69
- protocolVersion: typeof RECEIPT_PROTOCOL_VERSION;
73
+ schemaVersion: typeof RECEIPT_SCHEMA_VERSION | typeof LEGACY_RECEIPT_SCHEMA_VERSION;
74
+ protocolVersion: typeof RECEIPT_PROTOCOL_VERSION | typeof LEGACY_RECEIPT_PROTOCOL_VERSION;
70
75
  registrationDigest: string;
71
76
  capabilityFlags: readonly string[];
72
77
  compatibility: 'compatible';
@@ -128,12 +133,14 @@ export interface ReceiptLedger {
128
133
  finalizeObservation(input: unknown): FinalizeObservationResult;
129
134
  abandonObservation(input: unknown): AbandonObservationResult;
130
135
  consumeReceipt(receiptId: unknown, context: unknown): ConsumeReceiptResult;
131
- recoverReceipt(input: unknown): RecoverReceiptResult;
132
- recoverReadback(input: readonly unknown[]): RecoverReadbackResult;
136
+ recoverReceipt(input: unknown, operationTargetIdentity?: string): RecoverReceiptResult;
137
+ recoverReadback(input: readonly unknown[], operationTargetIdentity?: string): RecoverReadbackResult;
133
138
  getProgressionState(): ReceiptReadbackProgression;
134
139
  validateEnvelope(input: unknown): EnvelopeValidationResult;
135
140
  getEnvelope(receiptId: unknown): ReceiptEnvelope | undefined;
136
141
  listReceipts(): readonly ReceiptEnvelope[];
137
142
  getSessionSalt(): Uint8Array;
138
143
  }
144
+ export declare function isLocalOperation(operation: ReceiptOperation): operation is 'implementation' | 'verification' | 'commit';
139
145
  export declare function createReceiptLedger(options?: ReceiptLedgerOptions): ReceiptLedger;
146
+ export {};
@@ -1,6 +1,8 @@
1
1
  import type { ReceiptEnvelope, ReceiptLedgerMetadata, ReceiptOperation } from './receipt-ledger.js';
2
- export declare const RECEIPT_READBACK_SCHEMA_VERSION: 1;
3
- export declare const RECEIPT_READBACK_PROTOCOL_VERSION: 1;
2
+ export declare const RECEIPT_READBACK_SCHEMA_VERSION: 2;
3
+ export declare const RECEIPT_READBACK_PROTOCOL_VERSION: 2;
4
+ declare const LEGACY_RECEIPT_READBACK_SCHEMA_VERSION: 1;
5
+ type ReceiptReadbackVersion = typeof RECEIPT_READBACK_SCHEMA_VERSION | typeof LEGACY_RECEIPT_READBACK_SCHEMA_VERSION;
4
6
  export type ReceiptDigestDomain = 'repository' | 'worktree' | 'resource' | 'workspace' | 'epoch' | 'unit' | 'call' | 'registration';
5
7
  export type ReceiptProgressionStateName = 'started' | 'completed';
6
8
  export type ReceiptEpochFamily = 'work' | 'shipping';
@@ -11,16 +13,16 @@ export interface ReceiptResourceScope {
11
13
  export type ReceiptReadbackFailureCategory = 'malformed' | 'forbidden-field' | 'unknown-kind' | 'unknown-schema' | 'unknown-protocol' | 'unknown-capability' | 'integrity-mismatch' | 'missing-mint' | 'control-before-mint' | 'conflicting-marker' | 'out-of-order' | 'cross-registration' | 'capability-mismatch' | 'salt-mismatch' | 'receipt-mismatch' | 'progression-mismatch' | 'inconsistent-evidence' | 'missing-internal-id' | 'identity-digest-mismatch' | 'conflicting-seed' | 'missing-seed';
12
14
  export interface ReceiptMintMarker {
13
15
  readonly kind: 'mint';
14
- readonly schemaVersion: typeof RECEIPT_READBACK_SCHEMA_VERSION;
15
- readonly protocolVersion: typeof RECEIPT_READBACK_PROTOCOL_VERSION;
16
+ readonly schemaVersion: ReceiptReadbackVersion;
17
+ readonly protocolVersion: ReceiptReadbackVersion;
16
18
  readonly envelope: ReceiptEnvelope;
17
19
  readonly sessionSalt: string;
18
20
  readonly integrity: string;
19
21
  }
20
22
  export interface ReceiptConsumeMarker {
21
23
  readonly kind: 'control';
22
- readonly schemaVersion: typeof RECEIPT_READBACK_SCHEMA_VERSION;
23
- readonly protocolVersion: typeof RECEIPT_READBACK_PROTOCOL_VERSION;
24
+ readonly schemaVersion: ReceiptReadbackVersion;
25
+ readonly protocolVersion: ReceiptReadbackVersion;
24
26
  readonly registrationDigest: string;
25
27
  readonly capabilityFlags: readonly string[];
26
28
  readonly control: 'consume';
@@ -31,8 +33,8 @@ export interface ReceiptConsumeMarker {
31
33
  }
32
34
  export interface ReceiptEpochProgressionMarker {
33
35
  readonly kind: 'control';
34
- readonly schemaVersion: typeof RECEIPT_READBACK_SCHEMA_VERSION;
35
- readonly protocolVersion: typeof RECEIPT_READBACK_PROTOCOL_VERSION;
36
+ readonly schemaVersion: ReceiptReadbackVersion;
37
+ readonly protocolVersion: ReceiptReadbackVersion;
36
38
  readonly registrationDigest: string;
37
39
  readonly capabilityFlags: readonly string[];
38
40
  readonly control: 'progression';
@@ -48,8 +50,8 @@ export interface ReceiptEpochProgressionMarker {
48
50
  }
49
51
  export interface ReceiptUnitProgressionMarker {
50
52
  readonly kind: 'control';
51
- readonly schemaVersion: typeof RECEIPT_READBACK_SCHEMA_VERSION;
52
- readonly protocolVersion: typeof RECEIPT_READBACK_PROTOCOL_VERSION;
53
+ readonly schemaVersion: ReceiptReadbackVersion;
54
+ readonly protocolVersion: ReceiptReadbackVersion;
53
55
  readonly registrationDigest: string;
54
56
  readonly capabilityFlags: readonly string[];
55
57
  readonly control: 'progression';
@@ -61,6 +63,7 @@ export interface ReceiptUnitProgressionMarker {
61
63
  readonly family: ReceiptEpochFamily;
62
64
  readonly requiredOperations: readonly ReceiptOperation[];
63
65
  readonly resourceScopes: readonly ReceiptResourceScope[];
66
+ readonly pinnedOperationTargetIdentity?: string;
64
67
  readonly state: ReceiptProgressionStateName;
65
68
  readonly transitionDigest: string;
66
69
  readonly timestamp: number;
@@ -85,6 +88,7 @@ export type ReceiptProgressionMarkerInput = {
85
88
  readonly family: ReceiptEpochFamily;
86
89
  readonly requiredOperations: readonly ReceiptOperation[];
87
90
  readonly resourceScopes: readonly ReceiptResourceScope[];
91
+ readonly pinnedOperationTargetIdentity?: string;
88
92
  readonly transitionDigest: string;
89
93
  readonly timestamp?: number;
90
94
  };
@@ -98,6 +102,12 @@ export interface ReceiptReadbackExpectation {
98
102
  readonly capabilityFlags: readonly string[];
99
103
  readonly sessionSalt: Uint8Array;
100
104
  readonly source?: 'runtime-verified';
105
+ /**
106
+ * When present, legacy v1 mint markers are rejected because they cannot
107
+ * authenticate a foreign/worktree target. Absence retains the narrow v1
108
+ * parent-target recovery shim; callers must validate that parent separately.
109
+ */
110
+ readonly operationTargetIdentity?: string;
101
111
  }
102
112
  export type ReceiptEpochProgressionSnapshot = {
103
113
  readonly target: 'epoch';
@@ -117,6 +127,7 @@ export type ReceiptUnitProgressionSnapshot = {
117
127
  readonly family: ReceiptEpochFamily;
118
128
  readonly requiredOperations: readonly ReceiptOperation[];
119
129
  readonly resourceScopes: readonly ReceiptResourceScope[];
130
+ readonly pinnedOperationTargetIdentity?: string;
120
131
  readonly transitionDigest: string;
121
132
  };
122
133
  export type ReceiptProgressionSnapshot = ReceiptEpochProgressionSnapshot | ReceiptUnitProgressionSnapshot;
@@ -171,4 +182,5 @@ export declare function projectReceiptMintMarker(receipt: unknown, sessionSalt:
171
182
  export declare function projectReceiptConsumptionMarker(receipt: unknown, transitionDigest: string, timestamp?: number): ReceiptConsumeMarker | undefined;
172
183
  export declare function projectReceiptProgressionMarker(source: ReceiptProgressionProjectionSource, input: ReceiptProgressionMarkerInput): ReceiptProgressionMarker | undefined;
173
184
  export declare function foldReceiptReadback(inputs: readonly unknown[], expectation: ReceiptReadbackExpectation): ReceiptReadbackResult;
174
- export declare function receiptReadbackExpectationFromMetadata(metadata: ReceiptLedgerMetadata, sessionSalt: Uint8Array): ReceiptReadbackExpectation;
185
+ export declare function receiptReadbackExpectationFromMetadata(metadata: ReceiptLedgerMetadata, sessionSalt: Uint8Array, operationTargetIdentity?: string): ReceiptReadbackExpectation;
186
+ export {};
@@ -6,7 +6,7 @@ export type WorkflowState = 'protected' | 'waiting' | 'rejected' | 'disabled' |
6
6
  export type RepairKind = 'fresh-readback' | 'rerun-operation' | 'question-attestation';
7
7
  export type TransitionTarget = 'unit' | 'epoch';
8
8
  export type EpochFamily = 'work' | 'shipping';
9
- export type WorkflowReasonCode = 'abandoned-transition' | 'call-context-conflict' | 'cancelled-operation' | 'consumed-receipt' | 'disabled' | 'epoch-completed' | 'epoch-mismatch' | 'failed-operation' | 'family-conflict' | 'finalization-failed' | 'foreign-registration' | 'forbidden-field' | 'guard-unavailable' | 'incompatible-receipt' | 'invalid-configuration' | 'invalid-control' | 'invalid-receipt' | 'invalid-transition' | 'missing-evidence' | 'no-supported-repair' | 'no-active-epoch' | 'no-active-unit' | 'no-op-operation' | 'operation-not-required' | 'receipt-mismatch' | 'rejected-operation' | 'resource-mismatch' | 'running-operation' | 'stale-receipt' | 'transition-finalized' | 'transition-terminal' | 'transition-replayed' | 'unattributed-operation' | 'unit-active' | 'unit-completed' | 'unit-incomplete' | 'unit-mismatch' | 'unit-ready' | 'workspace-mismatch' | 'runtime-scope-conflict' | 'invalid-recovery' | 'recovery-conflict' | 'fork-copy-not-lineage';
9
+ export type WorkflowReasonCode = 'abandoned-transition' | 'call-context-conflict' | 'cancelled-operation' | 'consumed-receipt' | 'disabled' | 'epoch-completed' | 'epoch-mismatch' | 'failed-operation' | 'family-conflict' | 'finalization-failed' | 'foreign-registration' | 'forbidden-field' | 'guard-unavailable' | 'incompatible-receipt' | 'invalid-configuration' | 'invalid-control' | 'invalid-receipt' | 'invalid-transition' | 'missing-evidence' | 'no-supported-repair' | 'no-active-epoch' | 'no-active-unit' | 'no-op-operation' | 'operation-not-required' | 'operation-target-mismatch' | 'receipt-mismatch' | 'rejected-operation' | 'resource-mismatch' | 'running-operation' | 'stale-receipt' | 'transition-finalized' | 'transition-terminal' | 'transition-replayed' | 'unattributed-operation' | 'unit-active' | 'unit-completed' | 'unit-incomplete' | 'unit-mismatch' | 'unit-ready' | 'workspace-mismatch' | 'runtime-scope-conflict' | 'invalid-recovery' | 'recovery-conflict' | 'fork-copy-not-lineage';
10
10
  export interface WorkflowGuardOptions {
11
11
  ledger: ReceiptLedger;
12
12
  classifier?: ReceiptClassifier;
@@ -36,6 +36,7 @@ export interface UnitSnapshot {
36
36
  requiredOperations: readonly ReceiptOperation[];
37
37
  requiredResourceOperations: readonly ReceiptOperation[];
38
38
  resourceScopes: readonly ReceiptResourceScope[];
39
+ pinnedOperationTargetIdentity?: string;
39
40
  }
40
41
  export interface CurrentOperationContext {
41
42
  readonly workspaceIdentity: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "3.5.5",
3
+ "version": "3.5.6",
4
4
  "description": "Compound-engineering loops for OpenCode, Pi, and Claude Code",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -93,8 +93,8 @@
93
93
  "devDependencies": {
94
94
  "@biomejs/biome": "2.5.6",
95
95
  "@earendil-works/pi-coding-agent": "0.80.10",
96
- "@opencode-ai/plugin": "1.18.9",
97
- "@opencode-ai/sdk": "1.18.9",
96
+ "@opencode-ai/plugin": "1.18.10",
97
+ "@opencode-ai/sdk": "1.18.10",
98
98
  "@semantic-release/exec": "7.1.0",
99
99
  "@tintinweb/pi-subagents": "0.14.3",
100
100
  "@types/bun": "latest",