@mstar-harness/engine 3.9.3 → 3.9.4
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 +8 -7
- package/dist/audit.js +908 -170
- package/dist/coordination-write.d.ts +170 -0
- package/dist/coordination.d.ts +284 -0
- package/dist/engine.js +3512 -469
- package/dist/index.d.ts +2 -0
- package/dist/lease.d.ts +13 -1
- package/dist/migrate.d.ts +8 -0
- package/dist/path.d.ts +15 -6
- package/dist/status.d.ts +21 -1
- package/dist/workflow.d.ts +52 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -87,3 +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";
|
package/dist/lease.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export type ClaimLeaseFields = {
|
|
|
42
42
|
export type LeaseTransition = {
|
|
43
43
|
ok: boolean;
|
|
44
44
|
row: PlanRow;
|
|
45
|
-
outcome?: "claimed" | "resumed" | "released";
|
|
45
|
+
outcome?: "claimed" | "resumed" | "released" | "transferred";
|
|
46
46
|
violations: ValidationResult[];
|
|
47
47
|
};
|
|
48
48
|
/**
|
|
@@ -103,6 +103,18 @@ export declare function claimLease(row: PlanRow, holder: string, fields: ClaimLe
|
|
|
103
103
|
* protocol); the caller enforces that ordering around the locked update.
|
|
104
104
|
*/
|
|
105
105
|
export declare function releaseLease(row: PlanRow, holder: string): LeaseTransition;
|
|
106
|
+
/**
|
|
107
|
+
* Holder transfer for the scoped coordination `accept` transition (spec §D):
|
|
108
|
+
* move an ACTIVE `execution_lease` to another holder verbatim — same
|
|
109
|
+
* `claimed_at`, `worktree_path`, `working_branch`, extra fields preserved;
|
|
110
|
+
* only `holder` changes. Deliberately NOT `claimLease`: there is no
|
|
111
|
+
* Todo/Blocked → InProgress transition and no steal path here. The locked
|
|
112
|
+
* coordination writer has already authenticated the receiving holder as the
|
|
113
|
+
* workflow's coordinator, so `from` must still match the stored holder — a
|
|
114
|
+
* mismatched `from` is `lease.transfer.other-holder` and leaves the row
|
|
115
|
+
* untouched.
|
|
116
|
+
*/
|
|
117
|
+
export declare function transferLease(row: PlanRow, from: string, to: string): LeaseTransition;
|
|
106
118
|
/**
|
|
107
119
|
* Same-holder resume check (status-and-residuals.md § Claim-before-`InProgress`
|
|
108
120
|
* #2): `true` iff the stored lease `holder` equals the session `holder`.
|
package/dist/migrate.d.ts
CHANGED
|
@@ -84,6 +84,14 @@ export type MigratePlan = {
|
|
|
84
84
|
*/
|
|
85
85
|
projectDir: string;
|
|
86
86
|
dryRun: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Byte version (`sha256:…`, or `"absent"`) of the source `status.json` this
|
|
89
|
+
* plan was derived from (spec §C3 source-version CAS). The executor
|
|
90
|
+
* re-reads the source under the root lock before its first write and
|
|
91
|
+
* refuses a root whose bytes moved after planning — a still-v1 document
|
|
92
|
+
* changed by another writer is never silently replaced.
|
|
93
|
+
*/
|
|
94
|
+
sourceVersion: string;
|
|
87
95
|
/** Root status.json already at `version: 2` -> nothing to plan/apply. */
|
|
88
96
|
alreadyMigrated: boolean;
|
|
89
97
|
/** Human message (no-op reason when `alreadyMigrated`). */
|
package/dist/path.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ValidationResult } from "./core.js";
|
|
2
2
|
/**
|
|
3
3
|
* Options for `resolveHarnessDir`.
|
|
4
4
|
*/
|
|
@@ -164,11 +164,20 @@ export declare function resolveScaffoldDirs(root: string): {
|
|
|
164
164
|
* `.mstarc`-declared `project_dir`) with a valid `roadmap.md` + empty
|
|
165
165
|
* `residuals.json` (plan-conventions § 初始化 Plan 目录;
|
|
166
166
|
* mstar-project-governance § `_default` 回退). Idempotent: an existing
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
|
|
171
|
-
|
|
167
|
+
* `roadmap.md` is never clobbered, and re-running on an initialized tree only
|
|
168
|
+
* creates missing pieces. Returns the absolute resolved harness dir.
|
|
169
|
+
*
|
|
170
|
+
* The two coordination documents (`status.json`, `_default/residuals.json`)
|
|
171
|
+
* are written create-only through the active `ArtifactStore` inside the
|
|
172
|
+
* private protected-write context, serialized on the target's
|
|
173
|
+
* `withStatusWriteLock` (spec §C4): a concurrent writer's bytes are never
|
|
174
|
+
* replaced, and an existing empty/malformed document fails validation instead
|
|
175
|
+
* of being silently reinitialized. Callers whose target root differs from the
|
|
176
|
+
* active store's root MUST `setArtifactStore(createFsStore(<harnessRoot>))`
|
|
177
|
+
* first (same contract as the other routed writers). No scoped session or
|
|
178
|
+
* coordination record is created here.
|
|
179
|
+
*/
|
|
180
|
+
export declare function scaffoldHarness(root: string): Promise<string>;
|
|
172
181
|
/**
|
|
173
182
|
* Harness kind for the gitignore fence — the canonical snippet is per
|
|
174
183
|
* harness layout (plan-conventions § Git 跟踪策略): `.mstar/` (default) and
|
package/dist/status.d.ts
CHANGED
|
@@ -63,6 +63,18 @@ export type PlanRow = {
|
|
|
63
63
|
execution_lease?: unknown;
|
|
64
64
|
[key: string]: unknown;
|
|
65
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Every plan id a `plans[]` row can be addressed by (status-and-residuals.md
|
|
68
|
+
* § Compatibility: read accepts `id` or the legacy `plan_id`; write prefers
|
|
69
|
+
* `id`). Both non-empty keys are reported, in canonical-first order: a row
|
|
70
|
+
* whose two keys disagree is ambiguous (`status.plan-row.dual-id`), and an
|
|
71
|
+
* ownership guard keyed on one of them would let the other escape protection.
|
|
72
|
+
* Empty strings never count; a non-object or a row carrying neither key has
|
|
73
|
+
* no address.
|
|
74
|
+
*/
|
|
75
|
+
export declare function rowPlanIds(row: unknown): string[];
|
|
76
|
+
/** The canonical single plan id of a row — `id`, else legacy `plan_id`. */
|
|
77
|
+
export declare function rowPlanId(row: unknown): string | undefined;
|
|
66
78
|
/**
|
|
67
79
|
* Normalize a residual `severity` value for reading/rolling up
|
|
68
80
|
* (status-and-residuals.md § severity 5 + rollup `norm_sev`):
|
|
@@ -156,6 +168,11 @@ export declare const validateStatus: typeof validateStatusV2;
|
|
|
156
168
|
* an invalid entry would fail `validateStatusV2` anyway, but the explicit
|
|
157
169
|
* gate keeps the pre-lock fail-fast contract of `registerWorkflow`).
|
|
158
170
|
*
|
|
171
|
+
* Replacing an existing entry additionally takes that entry's snapshot lock
|
|
172
|
+
* (spec §C3 root → snapshot order, `withRegisteredSnapshotLock`) and holds it
|
|
173
|
+
* across the root write; callers must therefore hold the root lock only, not
|
|
174
|
+
* a snapshot lock.
|
|
175
|
+
*
|
|
159
176
|
* Async-only (architect-locked 2026-08-27): the durable write goes through
|
|
160
177
|
* `getArtifactStore().put({ kind: "status", key: "root", ... })` inside the
|
|
161
178
|
* caller's lock — the store is the persist backend, never a second lock.
|
|
@@ -185,7 +202,10 @@ export declare function registerWorkflow(root: string, entry: WorkflowEntry): Pr
|
|
|
185
202
|
* `withStatusWriteLock`, bumping root `updated_at` only when an entry was
|
|
186
203
|
* actually removed. The final document is validated (removal-at-terminal
|
|
187
204
|
* invariant included) before the write — a v1 root is refused with the
|
|
188
|
-
* `mstar migrate` hint.
|
|
205
|
+
* `mstar migrate` hint. Removing a registered entry additionally takes that
|
|
206
|
+
* entry's snapshot lock (spec §C3 root → snapshot order) and holds it across
|
|
207
|
+
* the root write, so the coordination check cannot be raced by a concurrent
|
|
208
|
+
* bind.
|
|
189
209
|
*
|
|
190
210
|
* Fails loud when the active FsStore would resolve its
|
|
191
211
|
* `status.json` to a path other than the caller's root — the no-op branches
|
package/dist/workflow.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { GateResult, ValidationResult } from "./core.js";
|
|
2
|
+
import { type SnapshotCoordination } from "./coordination-write.js";
|
|
2
3
|
import { type IntegrationMergeLease } from "./lease.js";
|
|
3
4
|
import { type PlanRow } from "./status.js";
|
|
4
5
|
/** Snapshot file name inside `workflows/<id>/` ( — writer contract). */
|
|
@@ -63,7 +64,17 @@ export type WorkflowSnapshot = {
|
|
|
63
64
|
integration_worktree_path?: string;
|
|
64
65
|
legacy_metadata?: Record<string, unknown>;
|
|
65
66
|
compass_ref?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Snapshot-level coordination block ( — scoped plan-PM coordination).
|
|
69
|
+
* Present only on a coordinated lifecycle: it carries the workflow's
|
|
70
|
+
* coordinator binding (session id + canonical envelope path). The block
|
|
71
|
+
* is validated strictly (`validateSnapshotCoordination`) and may only be
|
|
72
|
+
* changed by the locked coordination writer.
|
|
73
|
+
*/
|
|
74
|
+
coordination?: SnapshotCoordination;
|
|
66
75
|
};
|
|
76
|
+
/** Stable JSON for change detection (sorted keys, recursive). */
|
|
77
|
+
export declare function stableJson(value: unknown): string;
|
|
67
78
|
/**
|
|
68
79
|
* Validate a v3 workflow snapshot document ( — final schema):
|
|
69
80
|
* enum/type/id checks, `schema_version: 1`, required timestamps, `plans[]`
|
|
@@ -114,8 +125,34 @@ export declare class WorkflowSnapshotValidationError extends Error {
|
|
|
114
125
|
}
|
|
115
126
|
export declare function readWorkflowSnapshot(dir: string): WorkflowSnapshotRead;
|
|
116
127
|
/**
|
|
117
|
-
*
|
|
118
|
-
*
|
|
128
|
+
* Writer contract (spec §C4). `expectedVersion` is the CAS token — the exact
|
|
129
|
+
* on-disk artifact version (`sha256:<64 hex>`), or `"absent"` for
|
|
130
|
+
* create-only. `createOnly` is the locked `absent` shorthand used by the
|
|
131
|
+
* scaffold/migrate/audit writers: an existing document (even an empty or
|
|
132
|
+
* malformed one) is never silently replaced.
|
|
133
|
+
*
|
|
134
|
+
* Omitting `expectedVersion` means create-only, NOT "replace whatever is
|
|
135
|
+
* there": there is no missing-version compatibility fallback, so an existing
|
|
136
|
+
* snapshot still refuses with `coordination.expected-version-required`.
|
|
137
|
+
*
|
|
138
|
+
* The delta allowed here is `phase` + `updated_at` and nothing else — a
|
|
139
|
+
* coordinator persists its phase projection through this writer without ever
|
|
140
|
+
* gaining a backdoor to row owners, leases, lifecycle scalars or branch
|
|
141
|
+
* anchors. Lifecycle terminal changes belong to `closeWorkflow` (spec §C4).
|
|
142
|
+
*/
|
|
143
|
+
export type WriteWorkflowSnapshotOptions = {
|
|
144
|
+
expectedVersion?: string;
|
|
145
|
+
createOnly?: boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Canonical coordinator session envelope path (spec §C4). Required when the
|
|
148
|
+
* stored snapshot is coordinated: only the snapshot's own bound coordinator
|
|
149
|
+
* may pass, and the `coordination` block itself is never part of the delta.
|
|
150
|
+
*/
|
|
151
|
+
sessionPath?: string;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Write a workflow snapshot as a field-scoped update of `dir/snapshot.json`
|
|
155
|
+
* under `withStatusWriteLock(snapshotPath)` ( — the `.status-write.lockdir`
|
|
119
156
|
* lands inside `workflows/<id>/`, dirname of the snapshot; no harness-root
|
|
120
157
|
* pollution). The snapshot is validated first — an invalid snapshot throws
|
|
121
158
|
* and nothing is written. `dir` is created recursively. The durable write
|
|
@@ -128,14 +165,26 @@ export declare function readWorkflowSnapshot(dir: string): WorkflowSnapshotRead;
|
|
|
128
165
|
* whose target root differs from the active store's root MUST
|
|
129
166
|
* `setArtifactStore(createFsStore(root))` first.
|
|
130
167
|
*/
|
|
131
|
-
export declare function writeWorkflowSnapshot(snapshot: WorkflowSnapshot, dir: string): Promise<void>;
|
|
168
|
+
export declare function writeWorkflowSnapshot(snapshot: WorkflowSnapshot, dir: string, opts?: WriteWorkflowSnapshotOptions): Promise<void>;
|
|
132
169
|
/** Terminal enum predicate only; callers validate document shape separately. */
|
|
133
170
|
export declare function isTerminalSnapshot(doc: WorkflowSnapshot): boolean;
|
|
134
171
|
export type CloseWorkflowOptions = {
|
|
135
172
|
endedAt: string;
|
|
173
|
+
/**
|
|
174
|
+
* Canonical coordinator session envelope path (spec §C4). Required when the
|
|
175
|
+
* stored snapshot is coordinated: the close writes the snapshot, so only the
|
|
176
|
+
* snapshot's own bound coordinator may pass. A missing/mismatched envelope
|
|
177
|
+
* refuses the close with `coordination.session-mismatch` before anything is
|
|
178
|
+
* written. Non-coordinated snapshots ignore it; an already-terminal snapshot
|
|
179
|
+
* is returned unchanged (no write, no authorization needed).
|
|
180
|
+
*/
|
|
181
|
+
sessionPath?: string;
|
|
136
182
|
};
|
|
137
183
|
/**
|
|
138
184
|
* Complete the latest snapshot under its write lock. Never releases leases.
|
|
139
185
|
* A valid terminal snapshot is returned unchanged, including failed/stopped.
|
|
186
|
+
* A coordinated snapshot is closed only by its own bound coordinator
|
|
187
|
+
* (spec §C4) — the same envelope seam as `writeWorkflowSnapshot` — so a plan
|
|
188
|
+
* actor or a bare CLI call can never complete a lifecycle it does not own.
|
|
140
189
|
*/
|
|
141
190
|
export declare function closeWorkflow(workflowId: string, dir: string, opts: CloseWorkflowOptions): Promise<WorkflowSnapshot>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mstar-harness/engine",
|
|
3
|
-
"version": "3.9.
|
|
3
|
+
"version": "3.9.4",
|
|
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": {
|