@fro.bot/systematic 3.2.8 → 3.3.1

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.
@@ -0,0 +1,136 @@
1
+ import { type ReceiptClassifier } from './receipt-classifier.js';
2
+ import type { ReceiptLedger, ReceiptOperation } from './receipt-ledger.js';
3
+ export type WorkflowMode = 'protected' | 'disabled' | 'unavailable';
4
+ export type WorkflowState = 'protected' | 'waiting' | 'rejected' | 'disabled' | 'unavailable';
5
+ export type RepairKind = 'fresh-readback' | 'rerun-operation' | 'question-attestation';
6
+ export type TransitionTarget = 'unit' | 'epoch';
7
+ export type EpochFamily = 'work' | 'shipping';
8
+ 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 interface WorkflowGuardOptions {
10
+ ledger: ReceiptLedger;
11
+ classifier?: ReceiptClassifier;
12
+ workspaceIdentity: string;
13
+ repositoryIdentity?: string;
14
+ worktreeIdentity?: string;
15
+ supportedRepairs?: readonly RepairKind[];
16
+ questionEligibleOperations?: readonly ReceiptOperation[];
17
+ runtimeRequiredOperations?: readonly ReceiptOperation[];
18
+ runtimeResourceScopes?: Readonly<Record<string, string>>;
19
+ mode?: WorkflowMode;
20
+ maxReceiptAgeMs?: number;
21
+ clock?: () => number;
22
+ }
23
+ export interface RuntimeUnitPolicy {
24
+ requiredOperations?: readonly ReceiptOperation[];
25
+ resourceScopes?: Readonly<Record<string, string>>;
26
+ }
27
+ export interface EpochSnapshot {
28
+ epochId: string;
29
+ family: EpochFamily;
30
+ status: 'active' | 'completed';
31
+ }
32
+ export interface UnitSnapshot {
33
+ unitId: string;
34
+ status: 'active' | 'completed';
35
+ requiredOperations: readonly ReceiptOperation[];
36
+ requiredResourceOperations: readonly ReceiptOperation[];
37
+ }
38
+ export interface WorkflowStatus {
39
+ state: WorkflowState;
40
+ reasonCode: WorkflowReasonCode;
41
+ repair?: RepairKind;
42
+ statusKey: string;
43
+ epoch: EpochSnapshot | null;
44
+ unit: UnitSnapshot | null;
45
+ satisfiedOperations: readonly ReceiptOperation[];
46
+ missingOperations: readonly ReceiptOperation[];
47
+ }
48
+ export type ActivationResult = {
49
+ status: 'activated' | 'reused' | 'attached';
50
+ epoch: EpochSnapshot;
51
+ } | {
52
+ status: 'ignored';
53
+ reasonCode: WorkflowReasonCode;
54
+ } | {
55
+ status: 'rejected';
56
+ reasonCode: WorkflowReasonCode;
57
+ };
58
+ export type StartUnitResult = {
59
+ status: 'started';
60
+ unit: UnitSnapshot;
61
+ } | {
62
+ status: 'rejected';
63
+ reasonCode: WorkflowReasonCode;
64
+ };
65
+ export type EvidenceObservationResult = {
66
+ status: 'accepted';
67
+ operation: ReceiptOperation;
68
+ } | {
69
+ status: 'rejected';
70
+ reasonCode: WorkflowReasonCode;
71
+ } | {
72
+ status: 'unavailable';
73
+ reasonCode: WorkflowReasonCode;
74
+ };
75
+ export type ReadbackObservationResult = {
76
+ status: 'accepted';
77
+ changed: boolean;
78
+ } | {
79
+ status: 'rejected';
80
+ reasonCode: WorkflowReasonCode;
81
+ };
82
+ export type TransitionPrepareResult = {
83
+ status: 'allowed';
84
+ transitionId: string;
85
+ } | {
86
+ status: 'waiting' | 'rejected' | 'unavailable';
87
+ reasonCode: WorkflowReasonCode;
88
+ };
89
+ export type TransitionFinalizeResult = {
90
+ status: 'completed' | 'duplicate';
91
+ target: TransitionTarget;
92
+ transitionId: string;
93
+ } | {
94
+ status: 'waiting' | 'rejected' | 'unavailable';
95
+ reasonCode: WorkflowReasonCode;
96
+ };
97
+ export type AbandonTransitionResult = {
98
+ status: 'abandoned';
99
+ } | {
100
+ status: 'duplicate';
101
+ reasonCode: 'abandoned-transition';
102
+ } | {
103
+ status: 'rejected';
104
+ reasonCode: WorkflowReasonCode;
105
+ };
106
+ export type ControlResult = {
107
+ status: 'changed' | 'unchanged';
108
+ mode: WorkflowMode;
109
+ } | {
110
+ status: 'rejected';
111
+ reasonCode: WorkflowReasonCode;
112
+ };
113
+ export type WorkflowRecoveryResult = {
114
+ status: 'restored' | 'duplicate';
115
+ provenance: 'restart';
116
+ epoch: EpochSnapshot;
117
+ unit: UnitSnapshot | null;
118
+ } | {
119
+ status: 'rejected';
120
+ reasonCode: WorkflowReasonCode;
121
+ };
122
+ export interface WorkflowGuard {
123
+ activate(input: unknown): ActivationResult;
124
+ startUnit(input: unknown, policy?: RuntimeUnitPolicy): StartUnitResult;
125
+ observeReceipt(input: unknown): EvidenceObservationResult;
126
+ observeAttempt(input: unknown): EvidenceObservationResult;
127
+ observeOperation(input: unknown): Promise<EvidenceObservationResult>;
128
+ observeReadback(input: unknown): ReadbackObservationResult;
129
+ status(): WorkflowStatus;
130
+ prepareTransition(input: unknown): TransitionPrepareResult;
131
+ finalizeTransition(input: unknown): TransitionFinalizeResult;
132
+ abandonTransition(input: unknown): AbandonTransitionResult;
133
+ restore(input: unknown): WorkflowRecoveryResult;
134
+ setMode(input: unknown): ControlResult;
135
+ }
136
+ export declare function createWorkflowGuard(options: WorkflowGuardOptions): WorkflowGuard;
@@ -23,8 +23,11 @@
23
23
  "bootstrap": {
24
24
  "$ref": "#/definitions/__schema51"
25
25
  },
26
- "skills_as_commands": {
26
+ "workflow_guard": {
27
27
  "$ref": "#/definitions/__schema57"
28
+ },
29
+ "skills_as_commands": {
30
+ "$ref": "#/definitions/__schema61"
28
31
  }
29
32
  },
30
33
  "additionalProperties": false,
@@ -1314,16 +1317,67 @@
1314
1317
  "type": "string"
1315
1318
  },
1316
1319
  "__schema57": {
1320
+ "default": {
1321
+ "mode": "observe",
1322
+ "debug": false
1323
+ },
1324
+ "description": "Workflow guard configuration",
1325
+ "examples": [
1326
+ {
1327
+ "mode": "observe",
1328
+ "debug": false
1329
+ }
1330
+ ],
1331
+ "allOf": [
1332
+ {
1333
+ "$ref": "#/definitions/__schema58"
1334
+ }
1335
+ ]
1336
+ },
1337
+ "__schema58": {
1338
+ "type": "object",
1339
+ "properties": {
1340
+ "mode": {
1341
+ "default": "observe",
1342
+ "description": "Workflow guard mode",
1343
+ "examples": ["observe", "protected", "disabled"],
1344
+ "allOf": [
1345
+ {
1346
+ "$ref": "#/definitions/__schema59"
1347
+ }
1348
+ ]
1349
+ },
1350
+ "debug": {
1351
+ "default": false,
1352
+ "description": "Enable workflow guard debugging",
1353
+ "examples": [false, true],
1354
+ "allOf": [
1355
+ {
1356
+ "$ref": "#/definitions/__schema60"
1357
+ }
1358
+ ]
1359
+ }
1360
+ },
1361
+ "additionalProperties": false
1362
+ },
1363
+ "__schema59": {
1364
+ "type": "string",
1365
+ "enum": ["observe", "protected", "disabled"]
1366
+ },
1367
+ "__schema60": {
1368
+ "type": "boolean"
1369
+ },
1370
+ "__schema61": {
1317
1371
  "default": true,
1318
1372
  "description": "Register skills discovered from user/project skill directories (OpenCode config and other agent-harness-standard locations) as slash commands. Default true.",
1319
1373
  "examples": [true, false],
1320
1374
  "allOf": [
1321
1375
  {
1322
- "$ref": "#/definitions/__schema58"
1376
+ "$ref": "#/definitions/__schema62"
1323
1377
  }
1324
1378
  ]
1325
1379
  },
1326
- "__schema58": {
1380
+ "__schema62": {
1327
1381
  "type": "boolean"
1328
1382
  }
1329
1383
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fro.bot/systematic",
3
- "version": "3.2.8",
3
+ "version": "3.3.1",
4
4
  "description": "Structured engineering workflows for OpenCode",
5
5
  "type": "module",
6
6
  "homepage": "https://fro.bot/systematic",
@@ -103,12 +103,14 @@
103
103
  "rimraf": "6.1.3",
104
104
  "semantic-release": "25.0.8",
105
105
  "semantic-release-export-data": "1.2.0",
106
- "typebox": "1.3.6",
106
+ "typebox": "1.3.8",
107
107
  "typescript": "6.0.3"
108
108
  },
109
109
  "dependencies": {
110
110
  "js-yaml": "^4.1.1",
111
111
  "jsonc-parser": "^3.3.0",
112
+ "tree-sitter-bash": "0.25.1",
113
+ "web-tree-sitter": "0.25.10",
112
114
  "zod": "4.4.3"
113
115
  },
114
116
  "overrides": {