@mstar-harness/engine 3.9.2 → 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 +3558 -469
- package/dist/index.d.ts +6 -3
- package/dist/iteration.d.ts +1 -2
- package/dist/lease.d.ts +13 -1
- package/dist/lint.d.ts +50 -2
- package/dist/migrate.d.ts +8 -0
- package/dist/path.d.ts +17 -8
- package/dist/project.d.ts +2 -2
- package/dist/status.d.ts +21 -1
- package/dist/workflow.d.ts +52 -3
- package/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { ValidationResult } from "./core.js";
|
|
2
|
+
/** Stable refusal codes of the scoped coordination surface (spec §C4). */
|
|
3
|
+
export declare const COORDINATION_ERROR_CODES: readonly ["coordination.harness-not-found", "coordination.workflow-not-found", "coordination.plan-not-found", "coordination.scope-mismatch", "coordination.path-mismatch", "coordination.assignment-invalid", "coordination.assignment-stale", "coordination.not-prepared", "coordination.duplicate-holder", "coordination.session-mismatch", "coordination.session-not-found", "coordination.session-role", "coordination.version-conflict", "coordination.expected-version-required", "coordination.invalid-transition", "coordination.invalid-input", "coordination.forbidden-field", "coordination.not-in-git", "coordination.git-unavailable", "coordination.git-proof", "coordination.evidence-stale", "coordination.integration-unresolved", "coordination.integration-diverged", "coordination.local-store-required", "coordination.direct-write-refused", "coordination.scoped-writer-required", "coordination.unknown-operation", "coordination.not-implemented", "coordination.lock", "coordination.store"];
|
|
4
|
+
export type CoordinationErrorCode = (typeof COORDINATION_ERROR_CODES)[number];
|
|
5
|
+
/**
|
|
6
|
+
* Stable exception of the coordination surface: `code` is the consumer
|
|
7
|
+
* contract, `details` carries the machine-readable context (path, expected,
|
|
8
|
+
* actual, holder, …). Exported publicly from `coordination.ts`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class CoordinationError extends Error {
|
|
11
|
+
readonly code: CoordinationErrorCode;
|
|
12
|
+
readonly details: Record<string, unknown>;
|
|
13
|
+
constructor(code: CoordinationErrorCode, message: string, details?: Record<string, unknown>);
|
|
14
|
+
}
|
|
15
|
+
export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
|
|
16
|
+
/** Non-empty trimmed string predicate. */
|
|
17
|
+
export declare function isNonEmptyString(value: unknown): value is string;
|
|
18
|
+
/** `sha256:<64 lowercase hex>` of the exact bytes handed in. */
|
|
19
|
+
export declare function artifactVersion(bytes: Buffer | string): string;
|
|
20
|
+
/** SHA-256 (bare lowercase hex) of the exact bytes handed in. */
|
|
21
|
+
export declare function sha256Bytes(bytes: Buffer | string): string;
|
|
22
|
+
/** Artifact bytes read once: payload + byte version from that same read. */
|
|
23
|
+
export type ArtifactBytes = {
|
|
24
|
+
payload: unknown;
|
|
25
|
+
version: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Read an artifact once and derive both payload and version from the same
|
|
29
|
+
* bytes. Missing file → `undefined` (the caller reports `absent`).
|
|
30
|
+
* Malformed JSON throws (never a silent empty document).
|
|
31
|
+
*/
|
|
32
|
+
export declare function readArtifactBytes(filePath: string): ArtifactBytes | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Canonicalize a target: realpath when it exists (symlinks resolved), else the
|
|
35
|
+
* realpath of its nearest existing ancestor with the missing tail re-attached.
|
|
36
|
+
* Aliases therefore collapse onto the real protected file whether or not the
|
|
37
|
+
* leaf has been created yet, so a `json`/symlink ref can never dodge the
|
|
38
|
+
* boundary. A lexical fallback would do exactly that: a symlinked parent stays
|
|
39
|
+
* unresolved, the alias classifies as unprotected, and `put` creates the
|
|
40
|
+
* protected document through it.
|
|
41
|
+
*
|
|
42
|
+
* The same rule as `path.ts#canonicalizeNearestExisting`, restated here because
|
|
43
|
+
* `path.ts` imports this module (importing back would close an ESM cycle).
|
|
44
|
+
*/
|
|
45
|
+
export declare function canonicalTarget(target: string): string;
|
|
46
|
+
/** Protected document class, decided by the caller's resolved path table. */
|
|
47
|
+
export type ProtectedWriteKind = "root" | "snapshot" | "register";
|
|
48
|
+
/**
|
|
49
|
+
* Run `fn` inside the private authorization context for `target`. Only the
|
|
50
|
+
* locked coordination/writer implementation calls this; the context records
|
|
51
|
+
* canonical target + operation, never a caller-supplied boolean, and nested
|
|
52
|
+
* authorizations stack (a residual write authorizes both the snapshot and
|
|
53
|
+
* the register it touches).
|
|
54
|
+
*/
|
|
55
|
+
export declare function withProtectedWrite<T>(target: string, operation: "put" | "delete", fn: () => T | Promise<T>): Promise<T>;
|
|
56
|
+
/** `true` when the current async context authorized exactly this target+operation. */
|
|
57
|
+
export declare function isWriteAuthorized(target: string, operation: "put" | "delete"): boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Refuse an un-authorized write to a protected target (spec §C4). The
|
|
60
|
+
* target's class is decided by the store's resolved path table (never by
|
|
61
|
+
* document content, which a caller could shape); the authorization is the
|
|
62
|
+
* private context alone.
|
|
63
|
+
*/
|
|
64
|
+
export declare function assertProtectedWriteAuthorized(target: string, operation: "put" | "delete", kind: ProtectedWriteKind): void;
|
|
65
|
+
/** Exact-key contract: unknown keys anywhere are rejected before mutation. */
|
|
66
|
+
export declare function assertExactKeys(value: Record<string, unknown>, allowed: readonly string[], what: string): void;
|
|
67
|
+
/** Row/progress status a plan session may report (`progress` op). */
|
|
68
|
+
export type PlanProgressStatus = "InProgress" | "InReview" | "Blocked";
|
|
69
|
+
/** Progress payload a plan session reports on its own row. */
|
|
70
|
+
export type PlanProgress = {
|
|
71
|
+
status: PlanProgressStatus;
|
|
72
|
+
summary: string;
|
|
73
|
+
/** Canonical absolute artifacts inside the plan's own plan/SDD area. */
|
|
74
|
+
evidence_paths: string[];
|
|
75
|
+
/** L2 track branches reported for this plan (never main/integration). */
|
|
76
|
+
track_branches?: string[];
|
|
77
|
+
};
|
|
78
|
+
/** Hash-pinned reference to a submitted evidence file. */
|
|
79
|
+
export type EvidenceRef = {
|
|
80
|
+
path: string;
|
|
81
|
+
sha256: string;
|
|
82
|
+
};
|
|
83
|
+
/** Handoff lifecycle state (`PlanHandoff.state`). */
|
|
84
|
+
export type HandoffState = "submitted" | "accepted" | "returned" | "integrating" | "merged" | "completed";
|
|
85
|
+
/** QC review outcome recorded on a handoff. */
|
|
86
|
+
export type HandoffQc = {
|
|
87
|
+
decision: string;
|
|
88
|
+
reports: EvidenceRef[];
|
|
89
|
+
consolidated: EvidenceRef;
|
|
90
|
+
};
|
|
91
|
+
/** QA verification outcome recorded on a handoff. */
|
|
92
|
+
export type HandoffQa = {
|
|
93
|
+
gate: string;
|
|
94
|
+
decision: string;
|
|
95
|
+
report: EvidenceRef;
|
|
96
|
+
};
|
|
97
|
+
/** The single integration attempt recorded on a handoff. */
|
|
98
|
+
export type HandoffIntegration = {
|
|
99
|
+
target_branch: string;
|
|
100
|
+
worktree_path: string;
|
|
101
|
+
base_sha: string;
|
|
102
|
+
started_at: string;
|
|
103
|
+
result_sha?: string;
|
|
104
|
+
verified_at?: string;
|
|
105
|
+
};
|
|
106
|
+
/** The durable review package of one plan (spec §B `PlanHandoff`). */
|
|
107
|
+
export type PlanHandoff = {
|
|
108
|
+
id: string;
|
|
109
|
+
attempt: number;
|
|
110
|
+
state: HandoffState;
|
|
111
|
+
submitted_by: string;
|
|
112
|
+
submitted_at: string;
|
|
113
|
+
source_branch: string;
|
|
114
|
+
source_sha: string;
|
|
115
|
+
worktree_path: string;
|
|
116
|
+
review_base: string;
|
|
117
|
+
review_head: string;
|
|
118
|
+
qc: HandoffQc;
|
|
119
|
+
qa: HandoffQa;
|
|
120
|
+
accepted_by?: string;
|
|
121
|
+
accepted_at?: string;
|
|
122
|
+
returned_at?: string;
|
|
123
|
+
return_reason?: string;
|
|
124
|
+
integration?: HandoffIntegration;
|
|
125
|
+
completed_at?: string;
|
|
126
|
+
};
|
|
127
|
+
/** Coordinator-recorded preparation of one plan (spec §D `prepare`). */
|
|
128
|
+
export type PreparedCoordination = {
|
|
129
|
+
assignment_path: string;
|
|
130
|
+
assignment_sha256: string;
|
|
131
|
+
plan_sha256: string;
|
|
132
|
+
qa_gate: string;
|
|
133
|
+
findings_cleanup: string;
|
|
134
|
+
prepared_by: string;
|
|
135
|
+
prepared_at: string;
|
|
136
|
+
};
|
|
137
|
+
/** A bound session: identity + the canonical envelope that proves it. */
|
|
138
|
+
export type CoordinatorBinding = {
|
|
139
|
+
session_id: string;
|
|
140
|
+
session_file: string;
|
|
141
|
+
bound_at: string;
|
|
142
|
+
};
|
|
143
|
+
/** Snapshot-level coordination block (the workflow's coordinator). */
|
|
144
|
+
export type SnapshotCoordination = {
|
|
145
|
+
coordinator: CoordinatorBinding;
|
|
146
|
+
};
|
|
147
|
+
/** Row-level coordination block (one plan). */
|
|
148
|
+
export type RowCoordination = {
|
|
149
|
+
revision: number;
|
|
150
|
+
prepared?: PreparedCoordination;
|
|
151
|
+
session?: CoordinatorBinding;
|
|
152
|
+
progress?: PlanProgress;
|
|
153
|
+
handoff?: PlanHandoff;
|
|
154
|
+
};
|
|
155
|
+
export declare const HANDOFF_STATES: readonly HandoffState[];
|
|
156
|
+
export declare const PLAN_PROGRESS_STATUSES: readonly PlanProgressStatus[];
|
|
157
|
+
/** Validate a stored `PlanProgress` (`status`, `summary`, `evidence_paths`, `track_branches`). */
|
|
158
|
+
export declare function validatePlanProgress(value: unknown, what?: string): ValidationResult[];
|
|
159
|
+
/** Validate a stored `PlanHandoff`, including its state/field coherence. */
|
|
160
|
+
export declare function validatePlanHandoff(value: unknown, what?: string): ValidationResult[];
|
|
161
|
+
/** Validate a stored `PreparedCoordination`. */
|
|
162
|
+
export declare function validatePreparedCoordination(value: unknown, what?: string): ValidationResult[];
|
|
163
|
+
/** Validate one plan row's `coordination` object (spec §C2). */
|
|
164
|
+
export declare function validateRowCoordination(value: unknown, what?: string): ValidationResult[];
|
|
165
|
+
/** Validate a snapshot's top `coordination` block (spec §C2). */
|
|
166
|
+
export declare function validateSnapshotCoordination(value: unknown, what?: string): ValidationResult[];
|
|
167
|
+
/** Hash-pinned evidence reference for an absolute path, read from disk. */
|
|
168
|
+
export declare function evidenceRefOf(filePath: string): EvidenceRef;
|
|
169
|
+
/** Whether `value` is a well-formed `sha256:<64 hex>` artifact version. */
|
|
170
|
+
export declare function isArtifactVersion(value: unknown): value is string;
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { CoordinationError, type PlanProgress, type PreparedCoordination } from "./coordination-write.js";
|
|
2
|
+
import { type PlanRow } from "./status.js";
|
|
3
|
+
import { type ArtifactRef } from "./store.js";
|
|
4
|
+
/**
|
|
5
|
+
* Re-exported from the storage layer because this module is the public entry
|
|
6
|
+
* point for the scoped writers: callers catch `CoordinationError` and branch
|
|
7
|
+
* on its `code` without importing the storage layer directly.
|
|
8
|
+
*/
|
|
9
|
+
export { CoordinationError };
|
|
10
|
+
/** Bind roles: one coordinator per lifecycle, one plan session per plan. */
|
|
11
|
+
export type CoordinationRole = "plan-pm" | "coordinator";
|
|
12
|
+
/**
|
|
13
|
+
* Scope address, both forms required by spec §B: from a pinned Assignment
|
|
14
|
+
* path, or from a workflow/plan pair resolved through that row's `prepared`
|
|
15
|
+
* block. Both forms resolve to the same `ResolvedPlanScope`.
|
|
16
|
+
*/
|
|
17
|
+
export type PlanScopeInput = {
|
|
18
|
+
assignmentPath: string;
|
|
19
|
+
} | {
|
|
20
|
+
workflowId: string;
|
|
21
|
+
planId: string;
|
|
22
|
+
harnessDir?: string;
|
|
23
|
+
};
|
|
24
|
+
/** The fully pinned plan scope (spec §B `ResolvedPlanScope`). */
|
|
25
|
+
export type ResolvedPlanScope = {
|
|
26
|
+
harnessRoot: string;
|
|
27
|
+
workflowId: string;
|
|
28
|
+
planId: string;
|
|
29
|
+
/** `{WORKFLOW_DIR}/<workflow-id>/snapshot.json`. */
|
|
30
|
+
snapshotPath: string;
|
|
31
|
+
/** The plan markdown pinned by the Assignment `Plan Path`. */
|
|
32
|
+
planPath: string;
|
|
33
|
+
assignmentPath: string;
|
|
34
|
+
worktreePath: string;
|
|
35
|
+
workingBranch: string;
|
|
36
|
+
projectId: string;
|
|
37
|
+
sddDir: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Session envelope persisted at
|
|
41
|
+
* `{WORKFLOW_DIR}/<workflow-id>/sessions/<session-id>.json` (mode `0600`).
|
|
42
|
+
* The envelope is the durable proof of who holds the session: the snapshot
|
|
43
|
+
* stores its canonical path and every later call must present the same file.
|
|
44
|
+
*/
|
|
45
|
+
export type CoordinationSession = {
|
|
46
|
+
schema_version: 1;
|
|
47
|
+
role: CoordinationRole;
|
|
48
|
+
session_id: string;
|
|
49
|
+
workflow_id: string;
|
|
50
|
+
plan_id?: string;
|
|
51
|
+
harness_root: string;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Bind addressing (spec §B). A fresh bind never supplies a session path: the
|
|
55
|
+
* engine generates the session UUID and creates
|
|
56
|
+
* `<workflow-dir>/<workflow-id>/sessions/<session-id>.json` itself. An existing
|
|
57
|
+
* session is reached only through its explicit `resumePath`, which resumes
|
|
58
|
+
* read-only and never writes.
|
|
59
|
+
*/
|
|
60
|
+
export type BindPlanSessionInput = {
|
|
61
|
+
scope: PlanScopeInput;
|
|
62
|
+
cwd: string;
|
|
63
|
+
} | {
|
|
64
|
+
coordinator: true;
|
|
65
|
+
workflowId: string;
|
|
66
|
+
harnessDir?: string;
|
|
67
|
+
cwd: string;
|
|
68
|
+
} | {
|
|
69
|
+
resumePath: string;
|
|
70
|
+
cwd: string;
|
|
71
|
+
};
|
|
72
|
+
/** One artifact read: payload plus the byte version it was read at. */
|
|
73
|
+
export type VersionedArtifact = {
|
|
74
|
+
payload: unknown;
|
|
75
|
+
version: string;
|
|
76
|
+
};
|
|
77
|
+
/** Everything `mstar plan show` needs, in one read. */
|
|
78
|
+
export type PlanCoordinationView = {
|
|
79
|
+
/** Row `coordination.revision` (`0` when the row is not yet coordinated). */
|
|
80
|
+
revision: number;
|
|
81
|
+
/** `sha256:…` of the snapshot bytes, or `"absent"`. */
|
|
82
|
+
snapshot_version: string;
|
|
83
|
+
/** `sha256:…` of this plan's project register bytes, or `"absent"`. */
|
|
84
|
+
register_version: string;
|
|
85
|
+
/** `null` while the row carries no `prepared` block. */
|
|
86
|
+
scope: ResolvedPlanScope | null;
|
|
87
|
+
row: PlanRow;
|
|
88
|
+
prepared?: PreparedCoordination;
|
|
89
|
+
session: CoordinationSession;
|
|
90
|
+
session_file: string;
|
|
91
|
+
/** Operations this session may run now — implemented operations only. */
|
|
92
|
+
allowed_operations: string[];
|
|
93
|
+
};
|
|
94
|
+
/** Success shape of a coordination call. */
|
|
95
|
+
export type CoordinationResult = {
|
|
96
|
+
ok: true;
|
|
97
|
+
operation: string;
|
|
98
|
+
session: CoordinationSession;
|
|
99
|
+
session_file: string;
|
|
100
|
+
/** `claimed` / `resumed` / `prepared` / `progressed` / `residual-added` / `residual-closed`. */
|
|
101
|
+
outcome?: string;
|
|
102
|
+
view?: PlanCoordinationView;
|
|
103
|
+
};
|
|
104
|
+
/** One residual being registered: the nine v1 fields (+ optional `detail_doc`). */
|
|
105
|
+
export type ResidualInput = {
|
|
106
|
+
id: string;
|
|
107
|
+
title: string;
|
|
108
|
+
severity: string;
|
|
109
|
+
source: string;
|
|
110
|
+
scope: string;
|
|
111
|
+
decision: string;
|
|
112
|
+
owner: string;
|
|
113
|
+
target: string;
|
|
114
|
+
tracking: string;
|
|
115
|
+
detail_doc?: string;
|
|
116
|
+
};
|
|
117
|
+
export type PrepareCoordinationRequest = {
|
|
118
|
+
kind: "prepare";
|
|
119
|
+
/** The plan's pinned Assignment (absolute). */
|
|
120
|
+
assignmentPath: string;
|
|
121
|
+
expectedRevision: number;
|
|
122
|
+
};
|
|
123
|
+
export type ProgressCoordinationRequest = {
|
|
124
|
+
kind: "progress";
|
|
125
|
+
progress: PlanProgress;
|
|
126
|
+
expectedRevision: number;
|
|
127
|
+
};
|
|
128
|
+
export type ResidualAddCoordinationRequest = {
|
|
129
|
+
kind: "residual-add";
|
|
130
|
+
entries: ResidualInput[];
|
|
131
|
+
expectedRegisterVersion: string;
|
|
132
|
+
/** Optional extra guard: the row revision must still match. */
|
|
133
|
+
expectedRevision?: number;
|
|
134
|
+
};
|
|
135
|
+
export type ResidualCloseCoordinationRequest = {
|
|
136
|
+
kind: "residual-close";
|
|
137
|
+
entryId: string;
|
|
138
|
+
note: string;
|
|
139
|
+
expectedRegisterVersion: string;
|
|
140
|
+
expectedRevision?: number;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Handoff evidence (spec §D). Slice A types it so the union is stable; the
|
|
144
|
+
* operations that consume it arrive with the handoff slice.
|
|
145
|
+
*/
|
|
146
|
+
export type HandoffEvidence = {
|
|
147
|
+
source_sha: string;
|
|
148
|
+
review_base: string;
|
|
149
|
+
review_head: string;
|
|
150
|
+
qc: {
|
|
151
|
+
decision: "Approve" | "Approve with residuals";
|
|
152
|
+
reports: string[];
|
|
153
|
+
consolidated: string;
|
|
154
|
+
};
|
|
155
|
+
qa: {
|
|
156
|
+
gate: "mandatory" | "pm-acceptance";
|
|
157
|
+
decision: "pass";
|
|
158
|
+
report: string;
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* The operation surface (spec §B): every kind is implemented and typed, so an
|
|
163
|
+
* unknown shape is refused as `coordination.invalid-input` rather than
|
|
164
|
+
* silently accepted.
|
|
165
|
+
*/
|
|
166
|
+
export type PlanCoordinationOperation = {
|
|
167
|
+
kind: "prepare";
|
|
168
|
+
assignmentPath: string;
|
|
169
|
+
} | {
|
|
170
|
+
kind: "progress";
|
|
171
|
+
progress: PlanProgress;
|
|
172
|
+
} | {
|
|
173
|
+
kind: "residual-add";
|
|
174
|
+
entries: ResidualInput[];
|
|
175
|
+
expectedRegisterVersion: string;
|
|
176
|
+
} | {
|
|
177
|
+
kind: "residual-close";
|
|
178
|
+
entryId: string;
|
|
179
|
+
note: string;
|
|
180
|
+
expectedRegisterVersion: string;
|
|
181
|
+
} | {
|
|
182
|
+
kind: "handoff";
|
|
183
|
+
evidence: HandoffEvidence;
|
|
184
|
+
} | {
|
|
185
|
+
kind: "accept";
|
|
186
|
+
handoffId: string;
|
|
187
|
+
} | {
|
|
188
|
+
kind: "return";
|
|
189
|
+
handoffId: string;
|
|
190
|
+
reason: string;
|
|
191
|
+
} | {
|
|
192
|
+
kind: "integration-start";
|
|
193
|
+
handoffId: string;
|
|
194
|
+
} | {
|
|
195
|
+
kind: "integration-accept";
|
|
196
|
+
handoffId: string;
|
|
197
|
+
} | {
|
|
198
|
+
kind: "complete";
|
|
199
|
+
handoffId: string;
|
|
200
|
+
} | {
|
|
201
|
+
kind: "reconcile";
|
|
202
|
+
handoffId: string;
|
|
203
|
+
};
|
|
204
|
+
/** One whole coordination request: one session, one operation, one precondition. */
|
|
205
|
+
export type CoordinationRequest = {
|
|
206
|
+
sessionPath: string;
|
|
207
|
+
/** Required for a coordinator session; never another plan for a plan session. */
|
|
208
|
+
planId?: string;
|
|
209
|
+
/** The selected row's `coordination.revision` from `show` (absent row = 0). */
|
|
210
|
+
expectedRevision: number;
|
|
211
|
+
operation: PlanCoordinationOperation;
|
|
212
|
+
};
|
|
213
|
+
/** Coordinator replacement of a coordinated artifact (spec §B). */
|
|
214
|
+
export type CoordinatedReplacement = {
|
|
215
|
+
harnessRoot: string;
|
|
216
|
+
ref: ArtifactRef;
|
|
217
|
+
payload: unknown;
|
|
218
|
+
/** Byte version the writer expects (`sha256:…`, or `absent` to create). */
|
|
219
|
+
expectedVersion: string;
|
|
220
|
+
/** Required for snapshot replacement (the coordinator session envelope). */
|
|
221
|
+
sessionPath?: string;
|
|
222
|
+
};
|
|
223
|
+
/**
|
|
224
|
+
* The process-wide harness root (spec §C1): resolved from the **main**
|
|
225
|
+
* worktree's root, never from the checkout the process happens to sit in.
|
|
226
|
+
* This is the fix for the process-root bug — a process inside a linked
|
|
227
|
+
* worktree must not resolve the worktree's own `.mstar`.
|
|
228
|
+
*
|
|
229
|
+
* Returns `null` when no harness root is resolvable (the unscoped CLI keeps
|
|
230
|
+
* its existing non-Git fallback). Throws `coordination.not-in-git` when the
|
|
231
|
+
* cwd is provably a linked checkout (a `.git` **file**) whose main worktree
|
|
232
|
+
* cannot be read — falling back to local artifacts there is exactly the bug.
|
|
233
|
+
*/
|
|
234
|
+
export declare function resolveProcessHarnessDir(cwd?: string, harnessDir?: string): string | null;
|
|
235
|
+
/**
|
|
236
|
+
* Resolve the plan scope (spec §B). Form A pins the scope from the Assignment
|
|
237
|
+
* itself; form B starts from `{workflowId, planId}` and reads the pinned
|
|
238
|
+
* Assignment path out of that row's `prepared` block — never "the first
|
|
239
|
+
* unfinished row".
|
|
240
|
+
*/
|
|
241
|
+
export declare function resolvePlanScope(input: PlanScopeInput, cwd?: string): Promise<ResolvedPlanScope>;
|
|
242
|
+
/** Read and validate a session envelope (throws `coordination.session-*`). */
|
|
243
|
+
export declare function readSessionEnvelope(sessionPath: string): CoordinationSession;
|
|
244
|
+
/**
|
|
245
|
+
* Read this session's plan coordination view (spec §B). A coordinator session
|
|
246
|
+
* must select a plan; a plan session reads only its own row. A row that is not
|
|
247
|
+
* yet prepared yields `scope: null` and the raw row.
|
|
248
|
+
*/
|
|
249
|
+
export declare function readPlanCoordination(sessionPath: string, planId?: string, cwd?: string): Promise<PlanCoordinationView>;
|
|
250
|
+
/**
|
|
251
|
+
* Read one coordinated artifact plus its byte version, from a **single** byte
|
|
252
|
+
* read. `payload` is `undefined` and `version` is `"absent"` when the document
|
|
253
|
+
* does not exist. Snapshot payloads are validated before they are handed out.
|
|
254
|
+
*/
|
|
255
|
+
export declare function readCoordinatedArtifact(harnessRoot: string, ref: ArtifactRef): Promise<VersionedArtifact>;
|
|
256
|
+
/**
|
|
257
|
+
* Bind a session (spec §C2). A fresh bind creates the envelope, claims the L1
|
|
258
|
+
* lease and records the binding in the same snapshot commit; an existing
|
|
259
|
+
* envelope is a **read-only** resume that only re-verifies the binding.
|
|
260
|
+
*/
|
|
261
|
+
/**
|
|
262
|
+
* Bind a session (spec §B, §C2). Fresh addressing never supplies a session
|
|
263
|
+
* path: the engine generates the UUID and creates the envelope. `resumePath`
|
|
264
|
+
* names an existing envelope and resumes read-only.
|
|
265
|
+
*/
|
|
266
|
+
export declare function bindPlanSession(input: BindPlanSessionInput): Promise<CoordinationResult>;
|
|
267
|
+
/**
|
|
268
|
+
* Run one coordinated mutation (spec §B/§D). Every call re-authenticates the
|
|
269
|
+
* session from its envelope, re-checks the Assignment hash, enforces the
|
|
270
|
+
* revision/register precondition under the lock, and writes through
|
|
271
|
+
* `withProtectedWrite`. The operation surface is a closed discriminated union:
|
|
272
|
+
* an unknown key anywhere is rejected before any state is touched.
|
|
273
|
+
*/
|
|
274
|
+
export declare function mutatePlanCoordination(request: CoordinationRequest): Promise<CoordinationResult>;
|
|
275
|
+
/**
|
|
276
|
+
* Replace a coordinated artifact with an exact-version precondition (spec §B,
|
|
277
|
+
* §C4 line 156). Snapshot replacement goes through the canonical snapshot
|
|
278
|
+
* writer (coordinator session, phase-only delta, locked CAS); the root status
|
|
279
|
+
* and a project register are written with the same byte-version CAS under
|
|
280
|
+
* root → snapshot → destination locks, refusing any document that carries
|
|
281
|
+
* coordinated ownership. `review`/`json` are not coordinated artifacts, so
|
|
282
|
+
* they refuse explicitly instead of silently no-opping.
|
|
283
|
+
*/
|
|
284
|
+
export declare function replaceCoordinatedArtifact(input: CoordinatedReplacement): Promise<VersionedArtifact>;
|