@mstar-harness/engine 3.9.4 → 3.10.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.
- package/dist/audit.d.ts +15 -0
- package/dist/audit.js +131 -31
- package/dist/coordination-write.d.ts +1 -1
- package/dist/coordination.d.ts +85 -0
- package/dist/dispatch.d.ts +15 -1
- package/dist/engine.js +1269 -131
- package/dist/index.d.ts +4 -4
- package/dist/iteration.d.ts +33 -1
- package/dist/migrate.d.ts +40 -1
- package/dist/sdd.d.ts +9 -1
- package/dist/workflow.d.ts +324 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -45,8 +45,8 @@ export type { PlanRow, ResidualEntry, StatusDoc, StatusV2Doc, WorkflowEntry, } f
|
|
|
45
45
|
export { normalizeSeverity, registerWorkflow, resolveCompassEnforcement, resolveMstarcEnforcement, resolveRepoEnforcement, unregisterWorkflow, validatePlanRow, validateResidual, validateStatus, validateStatusV2, validateWorkflowEntry, } from "./status.js";
|
|
46
46
|
export type { ClaimLeaseFields, ExecutionLease, ExecutionLeaseLocations, IntegrationMergeLease, LeaseTransition, LeaseVerifyResult, } from "./lease.js";
|
|
47
47
|
export { canSteal, claimLease, planExecutionLeaseLocations, releaseLease, sameHolderResume, validateExecutionLease, validateIntegrationMergeLease, verifyPlanExecutionLease, withStatusWriteLock, } from "./lease.js";
|
|
48
|
-
export type { CloseWorkflowOptions, WorkflowBranchAnchors, WorkflowExecutionPolicy, WorkflowLifecycleStatus, WorkflowLifecycleType, WorkflowSnapshot, WorkflowSnapshotRead, } from "./workflow.js";
|
|
49
|
-
export { closeWorkflow, isTerminalSnapshot, LEGACY_WORKTREE_PATH_CODE, WORKFLOW_LIFECYCLE_STATUSES, WORKFLOW_LIFECYCLE_TYPES, WORKFLOW_SNAPSHOT_FILE, WORKFLOW_TERMINAL_STATUSES, readWorkflowSnapshot, validateWorkflowSnapshot, writeWorkflowSnapshot, } from "./workflow.js";
|
|
48
|
+
export type { CloseWorkflowOptions, DeclareWorkflowDeliveryKindOptions, DeliveryRegistrationEvidence, RecordWorkflowDeliveryOptions, RecordWorkflowDeliveryResult, RegisterPlanWorkflowOptions, RegisterPlanWorkflowResult, WorkflowBranchAnchors, WorkflowCompoundOutcome, WorkflowDeliveryEvidence, WorkflowDeliveryKind, WorkflowExecutionPolicy, WorkflowLifecycleStatus, WorkflowLifecycleType, WorkflowSnapshot, WorkflowSnapshotRead, } from "./workflow.js";
|
|
49
|
+
export { assertDeliveryRegistrationCoherence, closeWorkflow, consultDeliveryEvidence, declareWorkflowDeliveryKind, isTerminalSnapshot, LEGACY_WORKTREE_PATH_CODE, recordWorkflowDelivery, registerPlanWorkflow, WORKFLOW_COMPOUND_OUTCOMES, WORKFLOW_DELIVERY_KINDS, WORKFLOW_LIFECYCLE_STATUSES, WORKFLOW_LIFECYCLE_TYPES, WORKFLOW_SNAPSHOT_FILE, WORKFLOW_TERMINAL_STATUSES, readWorkflowSnapshot, validateWorkflowSnapshot, writeWorkflowSnapshot, } from "./workflow.js";
|
|
50
50
|
export type { CleanupDecision, CleanupFacts, CleanupTarget, CleanupTargetKind, } from "./cleanup.js";
|
|
51
51
|
export { planWorktreeCleanup } from "./cleanup.js";
|
|
52
52
|
export type { EvidenceArtifactFact, EvidenceAssessment, EvidenceCaptureRequest, EvidenceCoverage, EvidenceEnvironmentKey, EvidenceExpectation, EvidenceInputEntry, EvidenceInputSnapshot, EvidenceInputSpec, EvidenceLimits, EvidenceLog, EvidenceOutcome, EvidenceToolFingerprint, SddEvidenceRecord, } from "./evidence.js";
|
|
@@ -87,5 +87,5 @@ export type { ArtifactDoc, ArtifactKind, ArtifactRef, ArtifactStore } from "./st
|
|
|
87
87
|
export { assertFsStorePath, createFsStore, getArtifactStore, loadStoreModule, resolveArtifactPath, setArtifactStore } from "./store.js";
|
|
88
88
|
export { collectActiveLifecycleBranches, scanActiveLifecycleBranches, type ActiveLifecycleScan } from "./lifecycle-branches.js";
|
|
89
89
|
export { WorkflowSnapshotValidationError } from "./workflow.js";
|
|
90
|
-
export { CoordinationError, bindPlanSession, mutatePlanCoordination, readCoordinatedArtifact, readPlanCoordination, readSessionEnvelope, replaceCoordinatedArtifact, resolvePlanScope, resolveProcessHarnessDir, } from "./coordination.js";
|
|
91
|
-
export type { BindPlanSessionInput, CoordinatedReplacement, CoordinationRequest, CoordinationResult, CoordinationRole, CoordinationSession, HandoffEvidence, PlanCoordinationOperation, PlanCoordinationView, PlanScopeInput, PrepareCoordinationRequest, ProgressCoordinationRequest, ResidualAddCoordinationRequest, ResidualCloseCoordinationRequest, ResidualInput, ResolvedPlanScope, VersionedArtifact, } from "./coordination.js";
|
|
90
|
+
export { CoordinationError, amendPrepareWorkflow, bindPlanSession, mutatePlanCoordination, readCoordinatedArtifact, readPlanCoordination, readSessionEnvelope, replaceCoordinatedArtifact, resolvePlanScope, resolveProcessHarnessDir, showPrepareWorkflow, } from "./coordination.js";
|
|
91
|
+
export type { BindPlanSessionInput, CoordinatedReplacement, CoordinationRequest, CoordinationResult, CoordinationRole, CoordinationSession, HandoffEvidence, PlanCoordinationOperation, PlanCoordinationView, PlanScopeInput, PrepareCoordinationRequest, PreparePlanAppend, PrepareWorkflowPatch, PrepareWorkflowResult, PrepareWorkflowView, ProgressCoordinationRequest, ResidualAddCoordinationRequest, ResidualCloseCoordinationRequest, ResidualInput, ResolvedPlanScope, VersionedArtifact, } from "./coordination.js";
|
package/dist/iteration.d.ts
CHANGED
|
@@ -120,7 +120,39 @@ export declare function evaluatePhaseGate(snapshotDoc: SnapshotDoc, compassDoc:
|
|
|
120
120
|
* `evaluatePhaseGate` / `PhaseGateResult` (Phase 2–5 exit codes stay
|
|
121
121
|
* intact). Stable machine codes: `PHASE6_NOT_TERMINAL`,
|
|
122
122
|
* `PHASE6_ROOT_ENTRY_PRESENT`, `PHASE6_DANGLING_LEASE`,
|
|
123
|
-
* `PHASE6_INVALID_SNAPSHOT`, `PHASE6_INVALID_ROOT
|
|
123
|
+
* `PHASE6_INVALID_SNAPSHOT`, `PHASE6_INVALID_ROOT`,
|
|
124
|
+
* `PHASE6_DELIVERY_KIND_UNREGISTERED`, `PHASE6_DELIVERY_EVIDENCE_INCOMPLETE`,
|
|
125
|
+
* `PHASE6_PLAN_ROW_NOT_DONE`.
|
|
126
|
+
*
|
|
127
|
+
* Plan-type delivery-kind consultation (seam S3, contract §6 S3 + §4g): a
|
|
128
|
+
* terminal `type: plan` snapshot also consults the delivery evidence recorded
|
|
129
|
+
* over the lifecycle — plan rows are the owned plan (no compass input) and
|
|
130
|
+
* remote merge verification stays excluded by contract (§4f is the PM's
|
|
131
|
+
* separate check). The consultation is the shared pure function
|
|
132
|
+
* `consultDeliveryEvidence` (workflow.ts), which `closeWorkflow` runs before
|
|
133
|
+
* writing a terminal snapshot — one implementation, so this read-only gate
|
|
134
|
+
* and the write path can never disagree. It runs for a `completed` close ONLY:
|
|
135
|
+
* `failed`/`stopped` closes are never demanded delivery evidence (§5 — failure
|
|
136
|
+
* closes through its explicit status with a recorded reason and is never
|
|
137
|
+
* treated as delivered), exactly as `closeWorkflow` preserves an
|
|
138
|
+
* already-terminal snapshot unchanged without consulting; the type-generic
|
|
139
|
+
* dangling-lease probe still covers every terminal status. The kind is never
|
|
140
|
+
* inferred (§1): a plan workflow without a registered `delivery_kind` has no
|
|
141
|
+
* close-verifiable delivery evidence — for a legacy terminal snapshot this is
|
|
142
|
+
* outside the gate's automated recovery, because the create-only register
|
|
143
|
+
* cannot backfill terminal bytes, so the remediation names the owner
|
|
144
|
+
* snapshot-amendment path (the audit-promotion grandfather population is
|
|
145
|
+
* disclosed there) instead of the register verb — and a registered kind with
|
|
146
|
+
* incomplete delivery evidence (`development` without its registered
|
|
147
|
+
* source/target branches, its compound disposition, its PR identity or the
|
|
148
|
+
* PM's verified-merge record; `verification/report-only` without the recorded
|
|
149
|
+
* completion policy or its fulfilment record) refuses the same way — missing
|
|
150
|
+
* fields are incomplete registration, not an exempt workflow. A `completed`
|
|
151
|
+
* close additionally requires every owned plan row `Done` (the post-write
|
|
152
|
+
* mirror of `closeWorkflow`'s all-rows-Done guard, §3 terminal stage);
|
|
153
|
+
* `failed`/`stopped` lifecycles keep their statuses and row states (§5 —
|
|
154
|
+
* never rewritten as successfully completed). Every refusal is read-only: the
|
|
155
|
+
* workflow stays registered/resumable.
|
|
124
156
|
*/
|
|
125
157
|
export declare function evaluatePostMergeClose(snapshotDoc: SnapshotDoc, rootDoc: unknown): GateResult;
|
|
126
158
|
/**
|
package/dist/migrate.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ProjectRegisterDoc } from "./project.js";
|
|
2
2
|
import { type StatusV2Doc } from "./status.js";
|
|
3
|
-
import { type WorkflowLifecycleStatus, type WorkflowLifecycleType, type WorkflowSnapshot } from "./workflow.js";
|
|
3
|
+
import { type WorkflowDeliveryKind, type WorkflowLifecycleStatus, type WorkflowLifecycleType, type WorkflowSnapshot } from "./workflow.js";
|
|
4
4
|
/** Root status file name inside `{HARNESS_DIR}` (v1 input / v2 output). */
|
|
5
5
|
export declare const MIGRATE_STATUS_FILE = "status.json";
|
|
6
6
|
/** Legacy v1 root copy written by migration (never deleted without it). */
|
|
@@ -62,6 +62,21 @@ export type MigrateOptions = {
|
|
|
62
62
|
dryRun?: boolean;
|
|
63
63
|
/** Project id for the register/roadmap home (default `_default`). */
|
|
64
64
|
projectId?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Delivery kind declared for the ACTIVE standalone plan snapshots this lift
|
|
67
|
+
* produces (contract §1/§4a). A v1 `plans[]` row becomes a `type: plan`
|
|
68
|
+
* lifecycle, so its delivery kind is declared at registration and never
|
|
69
|
+
* inferred: the CLI/API caller passes it explicitly, and a lift that would
|
|
70
|
+
* create an active kind-less plan snapshot without it is refused (see
|
|
71
|
+
* `MigratePlan.deliveryKindRequired`).
|
|
72
|
+
*/
|
|
73
|
+
deliveryKind?: WorkflowDeliveryKind;
|
|
74
|
+
/** Delivery source branch, recorded as `branch.source`. Required for `development`. */
|
|
75
|
+
branchSource?: string;
|
|
76
|
+
/** Delivery target branch, recorded as `branch.target`. Required for `development`. */
|
|
77
|
+
branchTarget?: string;
|
|
78
|
+
/** Completion policy for `verification/report-only` lifts. Required for that kind. */
|
|
79
|
+
completionPolicy?: string;
|
|
65
80
|
};
|
|
66
81
|
/** Full migration plan: every write is described; the executor applies it. */
|
|
67
82
|
export type MigratePlan = {
|
|
@@ -97,6 +112,30 @@ export type MigratePlan = {
|
|
|
97
112
|
/** Human message (no-op reason when `alreadyMigrated`). */
|
|
98
113
|
message: string;
|
|
99
114
|
snapshots: MigrateSnapshot[];
|
|
115
|
+
/**
|
|
116
|
+
* Ids of the ACTIVE (running/paused) standalone plan snapshots this lift
|
|
117
|
+
* would create WITHOUT a declared delivery kind — i.e. the v1 rows lifted
|
|
118
|
+
* before the operator passed `opts.deliveryKind`. Non-empty means the plan is
|
|
119
|
+
* NOT applicable: `applyMigratePlan` refuses it (a close path could never
|
|
120
|
+
* complete such a lifecycle), and the CLI reports the missing flag as usage
|
|
121
|
+
* (exit 2) before any write. Terminal (completed) lifted snapshots are exempt
|
|
122
|
+
* — a finished lifecycle declares nothing (§1; the legacy terminal dead end
|
|
123
|
+
* is documented, not amended here).
|
|
124
|
+
*/
|
|
125
|
+
deliveryKindRequired: string[];
|
|
126
|
+
/**
|
|
127
|
+
* Ids of the ACTIVE (running/paused) standalone plan snapshots the single
|
|
128
|
+
* `opts.deliveryKind` declaration would be stamped onto when MORE THAN ONE
|
|
129
|
+
* lift qualifies. The declaration is one (kind, anchors, policy) tuple — one
|
|
130
|
+
* delivery identity, and the kind is per-workflow registration evidence (§1)
|
|
131
|
+
* — so it cannot describe several lifecycles at once. Non-empty means the
|
|
132
|
+
* plan is NOT applicable: `applyMigratePlan` refuses it and the CLI reports
|
|
133
|
+
* the ambiguity as usage (exit 2) before any write, so the operator migrates
|
|
134
|
+
* the tree in batches of one declared plan instead of pinning one identity
|
|
135
|
+
* onto several. Empty when no declaration was given or exactly one lift
|
|
136
|
+
* qualifies; terminal lifts are exempt like `deliveryKindRequired`.
|
|
137
|
+
*/
|
|
138
|
+
deliveryKindAmbiguous: string[];
|
|
100
139
|
notesFiles: MigrateNotesFile[];
|
|
101
140
|
register: MigrateRegister | null;
|
|
102
141
|
roadmap: MigrateRoadmap | null;
|
package/dist/sdd.d.ts
CHANGED
|
@@ -253,7 +253,15 @@ export type SddActionKind = "source" | "artifact" | "launch";
|
|
|
253
253
|
* the context must then match the verified lease exactly. Without an
|
|
254
254
|
* active lease (no row, or a non-InProgress row without lease), the
|
|
255
255
|
* standalone branch policy applies (`assertBranchAlignment`) — an
|
|
256
|
-
* InProgress row without lease is the orphan refusal.
|
|
256
|
+
* InProgress row without lease is the orphan refusal. The one admission
|
|
257
|
+
* exception (lifecycle contract §4b/§6 S2): on a register-governed harness
|
|
258
|
+
* root (readable v2 `status.json` `workflows[]`), a plan with NO active
|
|
259
|
+
* registered row is an unregistered normal-route plan — refused with
|
|
260
|
+
* `sdd.context.plan-not-registered` and the register/recovery path; branch
|
|
261
|
+
* alignment never substitutes for registration, and a plan id retained only
|
|
262
|
+
* in a terminal snapshot is refused the same way (a retained row is history,
|
|
263
|
+
* not registration evidence — §4b). Roots without a v2 register keep the
|
|
264
|
+
* standalone policy byte-for-byte.
|
|
257
265
|
*
|
|
258
266
|
* Throws `SddScriptError` — exit 2 when the declared context itself is
|
|
259
267
|
* malformed (non-absolute path, identity/composition mismatch, missing plan
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type GateResult, type ValidationResult } from "./core.js";
|
|
2
2
|
import { type SnapshotCoordination } from "./coordination-write.js";
|
|
3
3
|
import { type IntegrationMergeLease } from "./lease.js";
|
|
4
4
|
import { type PlanRow } from "./status.js";
|
|
@@ -10,6 +10,58 @@ export declare const WORKFLOW_LIFECYCLE_STATUSES: readonly ["running", "paused",
|
|
|
10
10
|
export declare const WORKFLOW_TERMINAL_STATUSES: readonly ["completed", "failed", "stopped"];
|
|
11
11
|
/** Lifecycle type enum ( — id reuses the orchestration id). */
|
|
12
12
|
export declare const WORKFLOW_LIFECYCLE_TYPES: readonly ["plan", "iteration"];
|
|
13
|
+
/**
|
|
14
|
+
* Delivery kinds declared at registration (mstar-artifacts/references/plan-workflow-lifecycle-contract.md
|
|
15
|
+
* §1). The declared kind is recorded at registration and never inferred
|
|
16
|
+
* retroactively; `development` carries the full PR/merge delivery lifecycle,
|
|
17
|
+
* `verification/report-only` follows the explicit completion policy recorded
|
|
18
|
+
* alongside it.
|
|
19
|
+
*/
|
|
20
|
+
export declare const WORKFLOW_DELIVERY_KINDS: readonly ["development", "verification/report-only"];
|
|
21
|
+
export type WorkflowDeliveryKind = (typeof WORKFLOW_DELIVERY_KINDS)[number];
|
|
22
|
+
/**
|
|
23
|
+
* Compound disposition outcomes (contract §4c): `created` / `updated` /
|
|
24
|
+
* reasoned `skipped`. The disposition is recorded on the workflow before the
|
|
25
|
+
* PR head is finalized, so the delivery evidence names the compound outcome
|
|
26
|
+
* it was taken from.
|
|
27
|
+
*/
|
|
28
|
+
export declare const WORKFLOW_COMPOUND_OUTCOMES: readonly ["created", "updated", "skipped"];
|
|
29
|
+
export type WorkflowCompoundOutcome = (typeof WORKFLOW_COMPOUND_OUTCOMES)[number];
|
|
30
|
+
/**
|
|
31
|
+
* Delivery evidence recorded on the snapshot (contract §3 lifecycle stages,
|
|
32
|
+
* §4c/§4d/§4f, seam S3). Each member is recorded by its owner at its own
|
|
33
|
+
* stage through the authorized write seam (`recordWorkflowDelivery`), and the
|
|
34
|
+
* close consultation reads the block for the DECLARED delivery kind — never
|
|
35
|
+
* inferring a kind from which members happen to be present (§1):
|
|
36
|
+
*
|
|
37
|
+
* - `compound` — compound disposition (§4c), recorded before the PR head is
|
|
38
|
+
* finalized; `skipped` carries the mandatory reason;
|
|
39
|
+
* - `pr` — PR identity recorded at submission (§4d): repo/head/target. A
|
|
40
|
+
* local commit or a pre-existing unrelated PR does not satisfy it;
|
|
41
|
+
* - `merge` — the PM's verified-merge record (§4f): the provider evidence
|
|
42
|
+
* they checked. The engine NEVER verifies the remote merge itself;
|
|
43
|
+
* - `completion` — the fulfilment record of the `completion_policy` recorded
|
|
44
|
+
* at registration (§1) for `verification/report-only` workflows.
|
|
45
|
+
*/
|
|
46
|
+
export type WorkflowDeliveryEvidence = {
|
|
47
|
+
compound?: {
|
|
48
|
+
outcome: WorkflowCompoundOutcome;
|
|
49
|
+
reason?: string;
|
|
50
|
+
};
|
|
51
|
+
pr?: {
|
|
52
|
+
repo: string;
|
|
53
|
+
head: string;
|
|
54
|
+
target: string;
|
|
55
|
+
};
|
|
56
|
+
merge?: {
|
|
57
|
+
provider: string;
|
|
58
|
+
evidence: string;
|
|
59
|
+
};
|
|
60
|
+
completion?: {
|
|
61
|
+
policy: string;
|
|
62
|
+
evidence: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
13
65
|
export type WorkflowLifecycleStatus = (typeof WORKFLOW_LIFECYCLE_STATUSES)[number];
|
|
14
66
|
export type WorkflowLifecycleType = (typeof WORKFLOW_LIFECYCLE_TYPES)[number];
|
|
15
67
|
/**
|
|
@@ -24,7 +76,20 @@ export type WorkflowExecutionPolicy = {
|
|
|
24
76
|
};
|
|
25
77
|
/** Iteration branch anchors ( — from root metadata anchors). */
|
|
26
78
|
export type WorkflowBranchAnchors = {
|
|
79
|
+
/**
|
|
80
|
+
* Protected base anchor: the branch the lifecycle starts from (iteration
|
|
81
|
+
* `iteration_base_branch`). Cleanup Rule 2 never deletes it and L1 uses it
|
|
82
|
+
* as the explicit main-worktree residency fallback — it is NEVER a
|
|
83
|
+
* feature/working branch (`registerPlanWorkflow` records the plan's
|
|
84
|
+
* delivery branch under `source`).
|
|
85
|
+
*/
|
|
27
86
|
base?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Source branch of a standalone `type: plan` delivery, recorded at
|
|
89
|
+
* registration (`--branch-source`). Semantically a delivery branch, not a
|
|
90
|
+
* protected base anchor: cleanup/L1 consumers keep reading `base`.
|
|
91
|
+
*/
|
|
92
|
+
source?: string;
|
|
28
93
|
integration?: string;
|
|
29
94
|
target?: string;
|
|
30
95
|
};
|
|
@@ -72,6 +137,27 @@ export type WorkflowSnapshot = {
|
|
|
72
137
|
* changed by the locked coordination writer.
|
|
73
138
|
*/
|
|
74
139
|
coordination?: SnapshotCoordination;
|
|
140
|
+
/**
|
|
141
|
+
* Delivery kind declared at registration (mstar-artifacts/references/plan-workflow-lifecycle-contract.md
|
|
142
|
+
* §1). Recorded by the registration producer; never inferred from runtime
|
|
143
|
+
* behavior or from the presence/absence of other fields.
|
|
144
|
+
*/
|
|
145
|
+
delivery_kind?: WorkflowDeliveryKind;
|
|
146
|
+
/** Project register id recorded at registration (contract §3 register row). */
|
|
147
|
+
project?: string;
|
|
148
|
+
/**
|
|
149
|
+
* Explicit completion policy for `verification/report-only` workflows,
|
|
150
|
+
* recorded at registration (contract §1): names the evidence that completes
|
|
151
|
+
* the workflow (e.g. acceptance artifacts or the report location).
|
|
152
|
+
*/
|
|
153
|
+
completion_policy?: string;
|
|
154
|
+
/**
|
|
155
|
+
* Delivery evidence collected over the lifecycle (contract §3/§4c/§4d/§4f,
|
|
156
|
+
* seam S3). Optional at the schema level — it is populated stage by stage
|
|
157
|
+
* through `recordWorkflowDelivery` and consulted by the close path (and the
|
|
158
|
+
* read-only phase-6 gate) for the declared `delivery_kind`.
|
|
159
|
+
*/
|
|
160
|
+
delivery?: WorkflowDeliveryEvidence;
|
|
75
161
|
};
|
|
76
162
|
/** Stable JSON for change detection (sorted keys, recursive). */
|
|
77
163
|
export declare function stableJson(value: unknown): string;
|
|
@@ -168,6 +254,55 @@ export type WriteWorkflowSnapshotOptions = {
|
|
|
168
254
|
export declare function writeWorkflowSnapshot(snapshot: WorkflowSnapshot, dir: string, opts?: WriteWorkflowSnapshotOptions): Promise<void>;
|
|
169
255
|
/** Terminal enum predicate only; callers validate document shape separately. */
|
|
170
256
|
export declare function isTerminalSnapshot(doc: WorkflowSnapshot): boolean;
|
|
257
|
+
/** Delivery-registration inputs every producer declares (contract §1/§4a). */
|
|
258
|
+
export type DeliveryRegistrationEvidence = {
|
|
259
|
+
branchSource?: string;
|
|
260
|
+
branchTarget?: string;
|
|
261
|
+
completionPolicy?: string;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Per-kind registration-evidence coherence (contract §1) — the ONE rule shared
|
|
265
|
+
* by every producer that declares a delivery kind at registration time:
|
|
266
|
+
* `registerPlanWorkflow` (the normal-entry producer), `promoteAuditPlans`
|
|
267
|
+
* (audit promotion) and `migrateHarnessTree` (v1 lift), plus the one-time
|
|
268
|
+
* `declareWorkflowDeliveryKind` backfill for active kind-less snapshots.
|
|
269
|
+
* Lockstep here is the point: a `development` workflow declares BOTH delivery
|
|
270
|
+
* anchors and a `verification/report-only` workflow declares the completion
|
|
271
|
+
* policy that completes it — missing fields are incomplete registration, never
|
|
272
|
+
* an exemption, and a producer that drifted would otherwise mint an
|
|
273
|
+
* unclosable lifecycle. `what` prefixes the refusal (the caller's own name).
|
|
274
|
+
*/
|
|
275
|
+
export declare function assertDeliveryRegistrationCoherence(kind: WorkflowDeliveryKind, evidence: DeliveryRegistrationEvidence, what: string): void;
|
|
276
|
+
/**
|
|
277
|
+
* Delivery-kind evidence consultation (seam S3 — contract §4g + §6 S3): the
|
|
278
|
+
* ONE implementation behind both the read-only Phase-6 gate
|
|
279
|
+
* (`evaluatePostMergeClose`) and the close write path (`closeWorkflow`), so
|
|
280
|
+
* the gate's verdict and the close's refusal can never drift apart. Pure,
|
|
281
|
+
* read-only, no writes; the input snapshot is consumed as read.
|
|
282
|
+
*
|
|
283
|
+
* Only `type: plan` lifecycles consult (an iteration declares no delivery
|
|
284
|
+
* kind — §1); WHEN the consultation runs is the caller's rule, and both
|
|
285
|
+
* callers scope it to a delivered lifecycle: `closeWorkflow` consults the
|
|
286
|
+
* running snapshot it is about to complete, and the Phase-6 gate consults a
|
|
287
|
+
* `completed` terminal snapshot. A `failed`/`stopped` close is therefore never
|
|
288
|
+
* demanded delivery evidence (§5). The DECLARED kind decides the required
|
|
289
|
+
* evidence; nothing is inferred from which fields happen to be present, and a
|
|
290
|
+
* missing field is incomplete registration, never an exemption (§1):
|
|
291
|
+
*
|
|
292
|
+
* - no registered `delivery_kind` → `PHASE6_DELIVERY_KIND_UNREGISTERED` (a
|
|
293
|
+
* legacy terminal snapshot cannot be backfilled: the register producer is
|
|
294
|
+
* create-only and preserves the terminal bytes);
|
|
295
|
+
* - `development` → the registered `branch.source`/`branch.target` plus the
|
|
296
|
+
* collected `delivery` evidence: compound disposition (§4c), PR identity
|
|
297
|
+
* (§4d) and the PM's verified-merge record (§4f — the engine never verifies
|
|
298
|
+
* the remote merge itself);
|
|
299
|
+
* - `verification/report-only` → the recorded `completion_policy` plus its
|
|
300
|
+
* fulfilment record, which must name that same policy (§1).
|
|
301
|
+
*
|
|
302
|
+
* Everything missing is named in one refusal (`PHASE6_DELIVERY_EVIDENCE_INCOMPLETE`)
|
|
303
|
+
* whose fix hint points at the authorized recording seam.
|
|
304
|
+
*/
|
|
305
|
+
export declare function consultDeliveryEvidence(snapshot: WorkflowSnapshot): ValidationResult[];
|
|
171
306
|
export type CloseWorkflowOptions = {
|
|
172
307
|
endedAt: string;
|
|
173
308
|
/**
|
|
@@ -182,9 +317,196 @@ export type CloseWorkflowOptions = {
|
|
|
182
317
|
};
|
|
183
318
|
/**
|
|
184
319
|
* Complete the latest snapshot under its write lock. Never releases leases.
|
|
185
|
-
* A valid terminal snapshot is returned unchanged, including failed/stopped
|
|
320
|
+
* A valid terminal snapshot is returned unchanged, including failed/stopped
|
|
321
|
+
* (idempotent preservation — nothing is rewritten, not even the timestamp).
|
|
186
322
|
* A coordinated snapshot is closed only by its own bound coordinator
|
|
187
323
|
* (spec §C4) — the same envelope seam as `writeWorkflowSnapshot` — so a plan
|
|
188
324
|
* actor or a bare CLI call can never complete a lifecycle it does not own.
|
|
325
|
+
*
|
|
326
|
+
* Before the terminal write the close consults the registered delivery
|
|
327
|
+
* kind's evidence through `consultDeliveryEvidence` — the SAME pure function
|
|
328
|
+
* the read-only Phase-6 gate runs (contract §4g/§6 S3), so the gate's verdict
|
|
329
|
+
* and this refusal can never disagree. An incomplete delivery (a
|
|
330
|
+
* `development` workflow without its compound disposition / PR identity /
|
|
331
|
+
* verified-merge record, a `verification/report-only` workflow without the
|
|
332
|
+
* fulfilment of its recorded completion policy) throws with every missing
|
|
333
|
+
* item named and ZERO writes: the snapshot stays `running` and the root entry
|
|
334
|
+
* stays registered, so the workflow remains resumable. The local close never
|
|
335
|
+
* verifies a remote merge (§4f keeps that as the PM's separate check) and
|
|
336
|
+
* never releases leases.
|
|
189
337
|
*/
|
|
190
338
|
export declare function closeWorkflow(workflowId: string, dir: string, opts: CloseWorkflowOptions): Promise<WorkflowSnapshot>;
|
|
339
|
+
export type RecordWorkflowDeliveryOptions = {
|
|
340
|
+
/**
|
|
341
|
+
* Partial delivery-evidence patch: only the named members are merged into
|
|
342
|
+
* the stored block, so the compound disposition, the PR identity and the
|
|
343
|
+
* merge record can be recorded at their own lifecycle stages without
|
|
344
|
+
* rewriting each other. At least one member is required.
|
|
345
|
+
*/
|
|
346
|
+
evidence: WorkflowDeliveryEvidence;
|
|
347
|
+
/**
|
|
348
|
+
* Canonical coordinator session envelope path (spec §C4) — the same
|
|
349
|
+
* authority seam `closeWorkflow` uses: a coordinated snapshot is written
|
|
350
|
+
* only by its own bound coordinator. Non-coordinated snapshots have no
|
|
351
|
+
* coordinator to bind and ignore it.
|
|
352
|
+
*/
|
|
353
|
+
sessionPath?: string;
|
|
354
|
+
/** Recording timestamp (YYYY-MM-DD or RFC3339). Default: now. */
|
|
355
|
+
at?: string;
|
|
356
|
+
};
|
|
357
|
+
export type RecordWorkflowDeliveryResult = {
|
|
358
|
+
snapshot: WorkflowSnapshot;
|
|
359
|
+
/** `false` when the recorded evidence already matched disk — nothing was written. */
|
|
360
|
+
written: boolean;
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* Record (or extend) the delivery evidence on a `type: plan` workflow's
|
|
364
|
+
* snapshot, under the snapshot write lock: the close path's consultation is
|
|
365
|
+
* only as good as the evidence recorded here, so this is the seam that makes
|
|
366
|
+
* a `development` close possible at all.
|
|
367
|
+
*
|
|
368
|
+
* Refusals (before any write):
|
|
369
|
+
* - a terminal snapshot: delivery evidence is collected BEFORE the close, and
|
|
370
|
+
* a terminal lifecycle is never amended (§5 — no rewriting a closed
|
|
371
|
+
* lifecycle);
|
|
372
|
+
* - a lifecycle other than `type: plan`, or one without a registered
|
|
373
|
+
* `delivery_kind`: the evidence belongs to the declared kind (§1);
|
|
374
|
+
* - evidence the declared kind does not use (e.g. a completion record on a
|
|
375
|
+
* `development` workflow) — the declared kind is authoritative;
|
|
376
|
+
* - a rewrite of the recorded PR identity (§4d records it once at submission:
|
|
377
|
+
* an identical re-record is idempotent, a different pair is refused);
|
|
378
|
+
* - an empty patch or a malformed member: nothing is silently dropped.
|
|
379
|
+
*
|
|
380
|
+
* Idempotent and re-entrant: re-recording the exact stored evidence performs
|
|
381
|
+
* NO write and returns the snapshot as read (the timestamp is untouched), so
|
|
382
|
+
* a retried recording never produces a spurious revision. The write itself
|
|
383
|
+
* routes through the same protected-writer path as the close (the store's
|
|
384
|
+
* locked put inside the snapshot lock).
|
|
385
|
+
*/
|
|
386
|
+
export declare function recordWorkflowDelivery(workflowId: string, dir: string, opts: RecordWorkflowDeliveryOptions): Promise<RecordWorkflowDeliveryResult>;
|
|
387
|
+
export type DeclareWorkflowDeliveryKindOptions = {
|
|
388
|
+
/** The declared kind (contract §1). Required — never inferred. */
|
|
389
|
+
deliveryKind: WorkflowDeliveryKind;
|
|
390
|
+
/** Delivery source branch, recorded as `branch.source`. Required for `development`. */
|
|
391
|
+
branchSource?: string;
|
|
392
|
+
/** Delivery target branch, recorded as `branch.target`. Required for `development`. */
|
|
393
|
+
branchTarget?: string;
|
|
394
|
+
/** Completion policy naming the evidence that completes the workflow. Required for `verification/report-only`. */
|
|
395
|
+
completionPolicy?: string;
|
|
396
|
+
/**
|
|
397
|
+
* Canonical coordinator session envelope path (spec §C4) — the same
|
|
398
|
+
* authority seam `closeWorkflow` and `recordWorkflowDelivery` use: a
|
|
399
|
+
* coordinated snapshot is written only by its own bound coordinator. An
|
|
400
|
+
* uncoordinated snapshot has no coordinator binding to authenticate (the
|
|
401
|
+
* historical audit-promotion / migrate population is exactly that), so it
|
|
402
|
+
* keeps the harness-owner stance the close already applies.
|
|
403
|
+
*/
|
|
404
|
+
sessionPath?: string;
|
|
405
|
+
/** Declaration timestamp (YYYY-MM-DD or RFC3339). Default: now. */
|
|
406
|
+
at?: string;
|
|
407
|
+
};
|
|
408
|
+
/**
|
|
409
|
+
* Declare the delivery kind (and its per-kind registration evidence) of an
|
|
410
|
+
* ACTIVE `type: plan` snapshot whose producer declared none — the one-time
|
|
411
|
+
* upgrade seam for the historical population (contract §1/§4a). ONE-TIME by
|
|
412
|
+
* construction: the kind is registration evidence that is never inferred
|
|
413
|
+
* retroactively (§1), so a second declaration is refused even with the same
|
|
414
|
+
* value, and a terminal snapshot is refused outright (§5 — a closed lifecycle
|
|
415
|
+
* is never amended; the legacy terminal dead end keeps its documented
|
|
416
|
+
* owner-amendment path).
|
|
417
|
+
*
|
|
418
|
+
* The declaration carries the kind's own evidence through the shared
|
|
419
|
+
* `assertDeliveryRegistrationCoherence` rule, so it cannot mint an unclosable
|
|
420
|
+
* lifecycle (a `development` kind needs its delivery anchors, a
|
|
421
|
+
* `verification/report-only` kind its completion policy). A supplied delivery
|
|
422
|
+
* anchor either FILLS the missing one or restates the value the snapshot
|
|
423
|
+
* already registers; a contradicting value is refused, so the declaration can
|
|
424
|
+
* never re-point a lifecycle at another delivery. The write lands in the
|
|
425
|
+
* snapshot lock through the same protected writer as the close.
|
|
426
|
+
*/
|
|
427
|
+
export declare function declareWorkflowDeliveryKind(workflowId: string, dir: string, opts: DeclareWorkflowDeliveryKindOptions): Promise<WorkflowSnapshot>;
|
|
428
|
+
/** Options for `registerPlanWorkflow`. `harnessDir` is required — the
|
|
429
|
+
* snapshot and `status.json` live under the harness root. */
|
|
430
|
+
export type RegisterPlanWorkflowOptions = {
|
|
431
|
+
/** Absolute harness dir that contains `status.json` + `workflows/`. Required. */
|
|
432
|
+
harnessDir: string;
|
|
433
|
+
/** The owned plan (contract §2: one independently owned plan per workflow on the new normal route). */
|
|
434
|
+
plan: {
|
|
435
|
+
id: string;
|
|
436
|
+
title: string;
|
|
437
|
+
file: string;
|
|
438
|
+
};
|
|
439
|
+
/** Delivery kind declared at registration (contract §1). Required — never inferred. */
|
|
440
|
+
deliveryKind: WorkflowDeliveryKind;
|
|
441
|
+
/** Project register id recorded on the snapshot (contract §3 register row). */
|
|
442
|
+
project?: string;
|
|
443
|
+
/** Source branch of the delivery, recorded as `branch.source`. Required together with `branchTarget` for `development`. */
|
|
444
|
+
branchSource?: string;
|
|
445
|
+
/** Target branch. Required together with `branchSource` for `development`. */
|
|
446
|
+
branchTarget?: string;
|
|
447
|
+
/**
|
|
448
|
+
* Completion policy for `verification/report-only` workflows (contract §1):
|
|
449
|
+
* names the evidence that completes the workflow. Required for that kind.
|
|
450
|
+
*/
|
|
451
|
+
completionPolicy?: string;
|
|
452
|
+
/**
|
|
453
|
+
* Pre-existing coordinator binding recorded at registration. Optional —
|
|
454
|
+
* binding a NEW coordinator session stays on the authorized `bind` seam
|
|
455
|
+
* (`coordination.ts`); this only records an already-held binding.
|
|
456
|
+
*/
|
|
457
|
+
coordinator?: {
|
|
458
|
+
session_id: string;
|
|
459
|
+
session_file: string;
|
|
460
|
+
};
|
|
461
|
+
/** Registration timestamp (YYYY-MM-DD or RFC3339). Default: now. */
|
|
462
|
+
startedAt?: string;
|
|
463
|
+
};
|
|
464
|
+
export type RegisterPlanWorkflowResult = {
|
|
465
|
+
workflowId: string;
|
|
466
|
+
snapshotPath: string;
|
|
467
|
+
/**
|
|
468
|
+
* True when this call completed a registration whose snapshot already
|
|
469
|
+
* existed (crash between snapshot creation and root registration): the
|
|
470
|
+
* existing snapshot bytes — identity, timestamps, ownership — were kept
|
|
471
|
+
* and only the root entry was written (contract §4b recovery).
|
|
472
|
+
*/
|
|
473
|
+
recovered: boolean;
|
|
474
|
+
};
|
|
475
|
+
/**
|
|
476
|
+
* Register a standalone plan workflow (seam S1 — the generic normal-entry
|
|
477
|
+
* producer). Builds the create-only `type: plan` snapshot (workflow id, the
|
|
478
|
+
* owned plan as its single Todo row, project, delivery kind, source/target
|
|
479
|
+
* branches, optional coordinator) and the root `workflows[]` entry, then
|
|
480
|
+
* writes BOTH under one atomic section of the root `withStatusWriteLock`
|
|
481
|
+
* — the same serialization point `registerWorkflow` uses — mirroring
|
|
482
|
+
* `promoteAuditPlans`'s primitive sequence: create-only
|
|
483
|
+
* `writeWorkflowSnapshot` (its snapshot-dir lock nests inside the root lock,
|
|
484
|
+
* root → snapshot is the documented acquisition order) →
|
|
485
|
+
* `registerWorkflowEntryLocked`, with rollback that removes ONLY the exact
|
|
486
|
+
* snapshot version this call created (plus the now-empty workflow dir), so a
|
|
487
|
+
* failed register write is never treated as partial activation success.
|
|
488
|
+
*
|
|
489
|
+
* Refusals (fail-loud, no partial activation):
|
|
490
|
+
* - existing id: the workflow is already registered (snapshot + root entry) —
|
|
491
|
+
* registration is create-only, never a re-registration;
|
|
492
|
+
* - unreadable root: a malformed/v1 `status.json` refuses (the created
|
|
493
|
+
* snapshot is rolled back first);
|
|
494
|
+
* - missing required fields: id/plan/delivery-kind shape per the existing
|
|
495
|
+
* snapshot validators; `development` additionally requires source+target
|
|
496
|
+
* branches (contract §1 — a development workflow with missing branch
|
|
497
|
+
* fields is incomplete registration, not an exempt workflow) and
|
|
498
|
+
* `verification/report-only` requires the completion policy.
|
|
499
|
+
*
|
|
500
|
+
* Crash/retry recovery (contract §4b): a crash between snapshot creation and
|
|
501
|
+
* root registration leaves the snapshot orphaned (no root entry = no
|
|
502
|
+
* activation). Re-running this producer with the same registration identity
|
|
503
|
+
* completes the registration against the EXISTING snapshot bytes — identity,
|
|
504
|
+
* timestamps and ownership are preserved, never rewritten. An existing
|
|
505
|
+
* snapshot with a DIFFERENT registration identity refuses (it belongs to
|
|
506
|
+
* another registration).
|
|
507
|
+
*
|
|
508
|
+
* The caller must pin the artifact store to the harness root first
|
|
509
|
+
* (`setArtifactStore(createFsStore(harnessDir))`) when the active store's
|
|
510
|
+
* root could differ — the routed writers fail loud on a path mismatch.
|
|
511
|
+
*/
|
|
512
|
+
export declare function registerPlanWorkflow(workflowId: string, options: RegisterPlanWorkflowOptions): Promise<RegisterPlanWorkflowResult>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mstar-harness/engine",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.1",
|
|
4
4
|
"description": "Morning Star Harness Workflow Engine — deterministic workflow enforcement library (path, status, lease, dispatch, sdd, iteration, lint gates).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|