@quantiya/codevibe-claude-plugin 2.0.13 → 2.0.15

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,273 @@
1
+ import { type AnchoredFsIdentity, type AnchoredCommittedFile, type AnchoredPathIdentity, type AnchoredWritePrecondition } from './anchored-fs';
2
+ import { type ProcessCleanupOwner } from './process-tree';
3
+ import { type ProcessIdentity } from './process-identity';
4
+ import { type MetadataBudget } from './bounded-directory';
5
+ import { type WorkspaceRootAuthority } from './workspace-authority';
6
+ import { type MaterializedFileMetadata } from './workspace-materializer';
7
+ import { type DurableDirectoryIdentity } from './durable-directory';
8
+ import { CasRecoveryAuthority, DisplacedShadowMarkerRecord, ExposureRetentionMarker, RetainedStateFileAuthority, ShadowDiffFile, ShadowEnv, ShadowPromoteState, ShadowStateFileV2, SnapshotIncarnationIndex, StructurallyBoundStateSnapshot, UnresolvedBundlePublicationRetention } from './shadow-protocol';
9
+ /** A recovered shadow state (read from the durable per-task marker). */
10
+ export interface RecoveredShadow {
11
+ taskId: string;
12
+ shadowDir: string;
13
+ workingDir: string;
14
+ shadowDirIdentity: AnchoredFsIdentity;
15
+ snapshotRootAuthority: WorkspaceRootAuthority;
16
+ workingDirIdentity: AnchoredFsIdentity;
17
+ workspaceRootAuthority: WorkspaceRootAuthority;
18
+ ownerProcessIdentity: ProcessIdentity;
19
+ physicalCopyBytes: number;
20
+ isGit: false;
21
+ promoteState: ShadowPromoteState;
22
+ createdAtMs: number;
23
+ /** The durable state dir for this task (for cleanup). */
24
+ stateDir: string;
25
+ /** Exact instance marker (sibling restarts use separate files). */
26
+ stateFile: string;
27
+ /** Exact durable state container and marker authorities from the scan. */
28
+ stateRootAuthority: WorkspaceRootAuthority;
29
+ stateDirAuthority: WorkspaceRootAuthority;
30
+ stateFileAuthority: AnchoredPathIdentity;
31
+ /** Scan-time bridge incarnation, when disposal/exposure recovery has one. */
32
+ exposureFileAuthority?: AnchoredPathIdentity;
33
+ /** Immutable tracked paths and pre-task hashes, including deleted/absent paths. */
34
+ baseline: Array<{
35
+ path: string;
36
+ hash: string | null;
37
+ mode?: number | null;
38
+ }>;
39
+ promotePostHashes?: Array<{
40
+ path: string;
41
+ hash: string | null;
42
+ mode?: number | null;
43
+ }>;
44
+ casRecovery?: CasRecoveryAuthority[];
45
+ disposalSnapshotAuthority?: WorkspaceRootAuthority;
46
+ disposalShadowIdentity?: AnchoredFsIdentity;
47
+ /** Exact reviewed artifact persisted before authorization could resolve. */
48
+ reviewedDiff?: ShadowDiffFile[];
49
+ cleanupBlocked?: boolean;
50
+ cleanupOwners?: ProcessCleanupOwner[];
51
+ unresolvedAuthorityRetention?: UnresolvedBundlePublicationRetention;
52
+ }
53
+ /**
54
+ * Read every durable per-task shadow marker under the state root. The reconnect/
55
+ * startup recovery (#PR-4) reads these to find an authorized-but-pending shadow
56
+ * to promote; the GC reaper (#GC-1) reads them to delete orphaned shadows.
57
+ */
58
+ interface ShadowMarkerScan {
59
+ recovered: RecoveredShadow[];
60
+ exposureRetentions: Array<{
61
+ marker: ExposureRetentionMarker;
62
+ stateDir: string;
63
+ stateFile: string;
64
+ stateFileAuthority: AnchoredPathIdentity;
65
+ }>;
66
+ /** Schema/placement-valid markers whose persisted snapshot incarnation moved. */
67
+ displacedSnapshots: DisplacedShadowMarkerRecord[];
68
+ /** Snapshot names protected by a syntactically instance-owned marker, valid or not. */
69
+ protectedDirNames: Set<string>;
70
+ /** Owned-looking authorities that were present but could not become operational. */
71
+ unresolved: Array<{
72
+ taskId: string;
73
+ path: string;
74
+ kind: 'state-directory' | 'state-marker' | 'exposure-marker';
75
+ detail: string;
76
+ }>;
77
+ }
78
+ export declare function scanShadowMarkers(env?: ShadowEnv): Promise<ShadowMarkerScan>;
79
+ export declare function reconcileExposureRetentions(retentions: ShadowMarkerScan['exposureRetentions'], recovered: readonly RecoveredShadow[], physicalCopyScope: string, env: ShadowEnv, retained: string[], snapshotIncarnations: SnapshotIncarnationIndex | null): Promise<void>;
80
+ export declare function reclaimDisplacedShadow(record: DisplacedShadowMarkerRecord, env: ShadowEnv, physicalCopyScope: string, opts: {
81
+ allowLiveOwner: boolean;
82
+ allowApplyingDisposal: boolean;
83
+ preserveStateDir: boolean;
84
+ expected?: {
85
+ shadowDir: string;
86
+ workingDir: string;
87
+ snapshotRootAuthority: WorkspaceRootAuthority;
88
+ ownerProcessIdentity: ProcessIdentity;
89
+ stateRootAuthority: WorkspaceRootAuthority;
90
+ stateDirAuthority: WorkspaceRootAuthority;
91
+ stateFileAuthority: RetainedStateFileAuthority;
92
+ exposureFileAuthority?: RetainedStateFileAuthority;
93
+ };
94
+ onStateFileAuthority?: (authority: RetainedStateFileAuthority) => void;
95
+ onExposureFileAuthority?: (authority: RetainedStateFileAuthority) => void;
96
+ snapshotIncarnations?: SnapshotIncarnationIndex | null;
97
+ }): Promise<'reaped' | 'retained'>;
98
+ export declare function reconcileDisplacedSnapshots(records: readonly DisplacedShadowMarkerRecord[], keepTaskIds: ReadonlySet<string>, ttlMs: number, now: number, physicalCopyScope: string, env: ShadowEnv, reaped: string[], retained: string[], snapshotIncarnations: SnapshotIncarnationIndex | null): Promise<void>;
99
+ export declare function listRecoverableShadows(env?: ShadowEnv): Promise<RecoveredShadow[]>;
100
+ /**
101
+ * Join or recover every known atomic writer owned by the supplied task ids
102
+ * before strict teardown inventory. This is a mutating reconciliation step,
103
+ * deliberately separate from `listShadowCleanupResidue`'s read-only audit.
104
+ */
105
+ export declare function reconcileShadowPublicationAuthority(taskIds: ReadonlySet<string>, env?: ShadowEnv): Promise<void>;
106
+ export interface ShadowCleanupResidue {
107
+ taskId: string;
108
+ path: string;
109
+ kind: 'recoverable-marker' | 'displaced-marker' | 'exposure-marker' | 'unresolved-authority' | 'state-directory' | 'snapshot-directory' | 'private-publication-authority';
110
+ detail?: string;
111
+ }
112
+ /**
113
+ * Exhaustive post-drain audit for exact task ids owned by one session. Unlike
114
+ * `listRecoverableShadows`, this intentionally reports non-operational and
115
+ * malformed authorities, empty owned state directories, snapshot/staging
116
+ * directories, and private publication records. Cleanup failures may be
117
+ * suppressed only when this inventory is empty.
118
+ */
119
+ export declare function listShadowCleanupResidue(taskIds: ReadonlySet<string>, env?: ShadowEnv): Promise<ShadowCleanupResidue[]>;
120
+ export declare function reapCrashedStateArtifacts(env: ShadowEnv): Promise<void>;
121
+ /**
122
+ * Create a Git-independent filesystem snapshot: walk `workingDir` excluding
123
+ * repository metadata, secrets, caches, and generated output. Source files and
124
+ * private dependency inputs use clone-or-bounded-copy materialization; only
125
+ * source files enter the promotable tracked set.
126
+ */
127
+ export declare function sealSnapshotTreeDurably(snapshotRoot: string, snapshotRootAuthority: WorkspaceRootAuthority, env: ShadowEnv): Promise<void>;
128
+ export declare function createCopyShadow(workingDir: string, shadowDir: string, sourceRootAuthority: WorkspaceRootAuthority, copyFile: (source: string, destination: string, maxLogicalBytes?: number) => Promise<MaterializedFileMetadata>, excludedRoots?: readonly string[]): Promise<{
129
+ tracked: Set<string>;
130
+ metadata: Map<string, MaterializedFileMetadata>;
131
+ }>;
132
+ /** List every regular file under the shadow (RELATIVE), excluding excluded dirs + build-env. */
133
+ export declare function listShadowRegularFiles(shadowDir: string, shadowRootAuthority: WorkspaceRootAuthority): Promise<string[]>;
134
+ type PathBudget = MetadataBudget;
135
+ export declare function createPathBudget(): PathBudget;
136
+ export declare function assertPathCollectionBounds(paths: readonly string[], label: string): void;
137
+ export declare function isWithinRoot(root: string, candidate: string): boolean;
138
+ export declare function assertSafeStateComponent(value: string): void;
139
+ export declare function stateFileNameForShadow(shadowDir: string): string;
140
+ export declare function exposureRetentionFileNameForShadow(shadowDir: string): string;
141
+ export declare function writeExposureRetentionMarker(stateFile: string, marker: ExposureRetentionMarker, expectedStateDir: WorkspaceRootAuthority, onCommitted?: (fileAuthority: RetainedStateFileAuthority, stateDirAuthority: WorkspaceRootAuthority) => void): Promise<void>;
142
+ /** Publish an exact, durable delete decision before recursive removal begins. */
143
+ export declare function publishExposureDeleteDisposition(stateFile: string, marker: ExposureRetentionMarker, authority: WorkspaceRootAuthority, expectedStateDir: WorkspaceRootAuthority, onCommitted?: (fileAuthority: RetainedStateFileAuthority, stateDirAuthority: WorkspaceRootAuthority) => void): Promise<ExposureRetentionMarker>;
144
+ /** Persist that the disposition completed and no physical bytes remain owned. */
145
+ export declare function publishExposureReclaimed(stateFile: string, marker: ExposureRetentionMarker, expectedStateDir: WorkspaceRootAuthority, onCommitted?: (fileAuthority: RetainedStateFileAuthority, stateDirAuthority: WorkspaceRootAuthority) => void): Promise<ExposureRetentionMarker>;
146
+ /** Retire a negative bridge only when its generated public name is absent. */
147
+ export declare function removeExposureRetentionMarkerIfPublicAbsent(stateFile: string, publicShadowDir: string, expected: ExposureRetentionMarker, shadowRoot: string, physicalCopyScope: string, expectedStateDir?: WorkspaceRootAuthority, expectedFileAuthority?: RetainedStateFileAuthority): Promise<boolean>;
148
+ export interface ExposureRetentionSnapshot {
149
+ marker: ExposureRetentionMarker;
150
+ stateFileIdentity: AnchoredPathIdentity;
151
+ stateDirAuthority: WorkspaceRootAuthority;
152
+ }
153
+ export declare function readExposureRetentionMarkerSnapshot(stateFile: string, taskId: string, shadowRoot: string, physicalCopyScope: string, expectedStateDir?: WorkspaceRootAuthority): Promise<ExposureRetentionSnapshot>;
154
+ export declare function shadowLifecycleLockPath(shadowRoot: string, snapshotPath: string): string;
155
+ export declare function buildCasRecoveryAuthority(root: WorkspaceRootAuthority, baseline: readonly {
156
+ path: string;
157
+ hash: string | null;
158
+ mode?: number | null;
159
+ }[], postImages: readonly {
160
+ path: string;
161
+ hash: string | null;
162
+ mode?: number | null;
163
+ }[]): CasRecoveryAuthority[];
164
+ export declare function markerPostHashes(marker: ShadowStateFileV2 | null): Map<string, string | null> | undefined;
165
+ export declare function markerPostModes(marker: ShadowStateFileV2 | null): Map<string, number | null> | undefined;
166
+ export declare function assertExactApplyingAuthority(marker: ShadowStateFileV2, postHashes: ReadonlyMap<string, string | null>, postModes: ReadonlyMap<string, number | null>): void;
167
+ export declare function validateReviewedDiff(files: readonly ShadowDiffFile[], baseline: ReadonlyMap<string, string | null>): void;
168
+ export declare function resolveStateMarkerByteLimit(env: ShadowEnv): number;
169
+ export declare function serializeStateMarker(marker: ShadowStateFileV2, maxBytes: number): string;
170
+ /**
171
+ * A PENDING marker is accepted only when the same reviewed authority can later
172
+ * publish its largest ordinary lifecycle shape. Otherwise a byte-valid review
173
+ * at the limit could become permanently non-disposable merely by adding the
174
+ * APPLYING post-hash set and DISPOSING inode proof.
175
+ */
176
+ export declare function assertStateMarkerLifecycleCapacity(marker: ShadowStateFileV2, maxBytes: number): void;
177
+ /** Retire only the exact marker bytes authenticated during failed creation. */
178
+ export declare function retireFailedCreateStateMarker(stateFile: string, taskId: string, stateRootAuthority: WorkspaceRootAuthority, maxBytes: number): Promise<void>;
179
+ export declare function validateMarkerShape(value: unknown, expectedTaskId: string): ShadowStateFileV2;
180
+ export declare function workspaceAuthorityOptions(env: ShadowEnv, target: string, boundary: string): {
181
+ helperTimeoutMs?: number;
182
+ testHangStage?: 'realpath' | 'lstat' | 'open' | 'stat' | 'close';
183
+ };
184
+ /** Fresh, bounded cleanup-only read used by live disposal and restart GC. */
185
+ export declare function readStructurallyBoundStateMarker(record: DisplacedShadowMarkerRecord, env: ShadowEnv): Promise<StructurallyBoundStateSnapshot | null>;
186
+ export declare function validateRecoveredPaths(marker: ShadowStateFileV2, stateFile: string, stateDir: string, requestedShadowRoot: string, requestedStateRoot?: string, env?: ShadowEnv, expectedStateAuthorities?: {
187
+ stateRootAuthority: WorkspaceRootAuthority;
188
+ stateDirAuthority: WorkspaceRootAuthority;
189
+ stateFileAuthority: RetainedStateFileAuthority;
190
+ }): Promise<WorkspaceRootAuthority>;
191
+ /**
192
+ * Validate an immutable DISPOSING marker after its snapshot inode has already
193
+ * been removed. Every still-existing authority path remains realpath/inode
194
+ * checked; the absent snapshot is accepted only by its exact owned lexical name.
195
+ */
196
+ export declare function validateDisposedMarkerPaths(marker: ShadowStateFileV2, stateFile: string, stateDir: string, requestedShadowRoot: string, requestedStateRoot?: string, env?: ShadowEnv): Promise<void>;
197
+ export declare function durableDirectoryAnchor(dir: string): string;
198
+ export declare function ensurePrivateDirectory(dir: string, opts?: {
199
+ anchorPath?: string;
200
+ failDirectorySyncStage?: 'target-child' | 'target-parent';
201
+ }): Promise<DurableDirectoryIdentity>;
202
+ export declare function atomicWriteFile(filePath: string, content: string, expected: AnchoredWritePrecondition, beforeCommit?: () => Promise<void> | void, afterValidation?: () => Promise<void> | void, serializeInProcess?: boolean, expectedParent?: AnchoredFsIdentity, maxTargetBytes?: number, failDirectorySync?: boolean, publicationOwnerKey?: string): Promise<AnchoredCommittedFile>;
203
+ export declare function isAnchoredWritePreconditionError(err: unknown): boolean;
204
+ export declare function assertMarkerTransition(from: ShadowPromoteState | null, to: ShadowPromoteState, opts: {
205
+ allowApplyingDisposal: boolean;
206
+ cleanupState: 'preserve' | 'set' | 'clear';
207
+ }): void;
208
+ export declare function sameFsIdentity(a: AnchoredFsIdentity | null | undefined, b: AnchoredFsIdentity | null | undefined): boolean;
209
+ export declare function sameWorkspaceIncarnation(left: WorkspaceRootAuthority, right: WorkspaceRootAuthority): boolean;
210
+ /** One bounded root walk shared by every displaced record in a GC sweep. */
211
+ export declare function buildSnapshotIncarnationIndex(shadowRootAuthority: WorkspaceRootAuthority, env?: ShadowEnv): Promise<SnapshotIncarnationIndex>;
212
+ /** Locate one renamed original snapshot without ever adopting its current name. */
213
+ export declare function findSnapshotIncarnation(shadowRootAuthority: WorkspaceRootAuthority, expected: WorkspaceRootAuthority, snapshotIncarnations?: SnapshotIncarnationIndex, env?: ShadowEnv): Promise<WorkspaceRootAuthority | null>;
214
+ export declare function hasCleanupBlockAnchor(shadowDir: string): Promise<boolean>;
215
+ interface SnapshotOwnerAnchor {
216
+ version: 1 | 2;
217
+ shadowDirIdentity: AnchoredFsIdentity;
218
+ /** Present only on v2; v1 is retained but never authorizes deletion. */
219
+ snapshotRootAuthority?: WorkspaceRootAuthority;
220
+ ownerProcessIdentity: ProcessIdentity;
221
+ physicalCopyScopeHash: string;
222
+ physicalCopyBytes: number;
223
+ }
224
+ export declare function physicalCopyScopeHash(scopeId: string): string;
225
+ /**
226
+ * Resolve every atomic-publication transaction whose target parent is about
227
+ * to be recursively removed. Once the parent inode is gone, a crash record can
228
+ * no longer authenticate its prepared target/temp state, so deletion must
229
+ * never outrun this reconciliation boundary.
230
+ */
231
+ export declare function reconcileSnapshotPublicationAuthorityBeforeRemoval(snapshotRootAuthority: WorkspaceRootAuthority): Promise<void>;
232
+ /**
233
+ * Stable, bounded ownership key for every private publication transaction
234
+ * created on behalf of one task-state namespace. The private publication store
235
+ * hashes this value again before encoding its prefix; neither user paths nor
236
+ * task ids are disclosed in private record names.
237
+ */
238
+ export declare function workspacePublicationAuthorityOwnerKey(stateRootCanonicalPath: string, taskId: string): string;
239
+ export declare function writeSnapshotOwnerAnchor(ownerFile: string, snapshotRootAuthority: WorkspaceRootAuthority, ownerProcessIdentity: ProcessIdentity, physicalCopyScope: string, physicalCopyBytes: number, publicationOwnerKey: string): Promise<void>;
240
+ export declare function readSnapshotOwnerAnchor(shadowDir: string): Promise<SnapshotOwnerAnchor | null>;
241
+ /**
242
+ * Sum durable reservations under the cross-process quota fence. Invalid owner
243
+ * authority consumes the whole limit, so cloning can continue but a physical
244
+ * fallback cannot allocate unknown additional disk.
245
+ */
246
+ export declare function scanPersistedPhysicalCopyBytes(shadowRoots: readonly RegisteredShadowRoot[], physicalCopyScope: string, limit: number): Promise<number>;
247
+ interface RegisteredShadowRoot extends AnchoredFsIdentity {
248
+ path: string;
249
+ version?: 1;
250
+ canonicalPath?: string;
251
+ birthtimeNs?: string;
252
+ }
253
+ /**
254
+ * Durable quota-scope registry. Every process sharing `stateRoot` registers its
255
+ * physical shadow root before copying, so the aggregate scan cannot be split by
256
+ * different temp-root configuration.
257
+ */
258
+ export declare function registerAndListQuotaShadowRoots(stateRoot: string, stateRootIdentity: WorkspaceRootAuthority, currentShadowRoot: string, currentShadowRootIdentity: WorkspaceRootAuthority, publicationOwnerKey: string, maxStateMarkerBytes: number, afterQuotaReferenceTaskEntry?: (stateDir: string) => Promise<void> | void, afterQuotaReferenceMarkerEntry?: (filePath: string) => Promise<void> | void, afterQuotaReferenceMarkerStat?: (filePath: string) => Promise<void> | void, failDirectorySync?: boolean): Promise<RegisteredShadowRoot[]>;
259
+ interface CleanupBlockAnchorRead {
260
+ present: boolean;
261
+ cleanupOwners: ProcessCleanupOwner[];
262
+ unresolvedAuthorityRetention?: UnresolvedBundlePublicationRetention;
263
+ /** Exact validated marker incarnation, carried directly to retirement. */
264
+ fileIdentity?: AnchoredPathIdentity;
265
+ }
266
+ export declare function readCleanupBlockAnchor(shadowDir: string, expected: {
267
+ taskId: string;
268
+ shadowDir: string;
269
+ shadowDirIdentity: AnchoredFsIdentity;
270
+ snapshotRootAuthority: WorkspaceRootAuthority;
271
+ }): Promise<CleanupBlockAnchorRead>;
272
+ export declare function dedupeCleanupOwners(owners: readonly ProcessCleanupOwner[]): ProcessCleanupOwner[];
273
+ export {};
@@ -1,172 +1,14 @@
1
- import { type AnchoredFsIdentity, type AnchoredPathIdentity } from './anchored-fs';
2
1
  import type { PromoteManifestInput } from './durable-store';
3
2
  import { type ProcessCleanupOwner } from './process-tree';
4
- import { type ProcessIdentity } from './process-identity';
5
3
  import { type WorkspaceRootAuthority } from './workspace-authority';
6
- import { type MaterializationHangStage } from './workspace-materializer';
7
- export declare const MAX_TRACKED_FILE_LOGICAL_BYTES: number;
8
- export declare const MAX_TRACKED_WORKSPACE_LOGICAL_BYTES: number;
9
- /** Metadata is bounded independently of content bytes (zero-byte files still cost memory/inodes). */
10
- export declare const MAX_TRACKED_FILE_COUNT = 100000;
11
- export declare const MAX_TRACKED_PATH_BYTES: number;
12
- /** Reviewed text is intentionally bounded before any whole-file decode/read. */
13
- export declare const MAX_REVIEW_FILE_BYTES: number;
14
- export declare const MAX_PROMOTION_PREIMAGE_AGGREGATE_BYTES: number;
15
- /** Exact UTF-8 ceiling shared by every durable state-marker writer and reader. */
16
- export declare const MAX_STATE_MARKER_BYTES: number;
17
- /** Default TTL after which an orphaned shadow is GC-eligible (#GC-1). */
18
- export declare const DEFAULT_SHADOW_TTL_MS: number;
19
- /** `change_kind` values mirroring the pinned engine `ExecuteFirstFile` contract. */
20
- export type ShadowChangeKind = 'created' | 'modified' | 'deleted';
21
- /** One captured changed file in the shadow-vs-real diff (§D3). */
22
- export interface ShadowDiffFile {
23
- /** Path RELATIVE to the workspace root (matches the engine contract). */
24
- path: string;
25
- change_kind: ShadowChangeKind;
26
- /** The captured content (created/modified) or empty for deleted. */
27
- content: string;
28
- /** POSIX permission bits for the reviewed post-image (omitted by legacy records). */
29
- mode?: number;
30
- }
31
- /** A reviewed change plus the exact real-tree pre-image expected at promotion. */
32
- export interface ReviewedShadowDiffFile extends ShadowDiffFile {
33
- /** SHA-256 of the pre-task file, or null when the path was absent. */
34
- base_hash: string | null;
35
- /** POSIX permission bits of the pre-task file, or null when absent. */
36
- base_mode?: number | null;
37
- }
38
- /** Persisted promote-state marker (#PR-4). */
39
- type ShadowPromoteState = 'pending' | 'applying' | 'promoted' | 'disposing';
40
- export type CasHelperCrashStage = 'post-link' | 'post-displacement' | 'post-publication' | 'post-fsync' | 'post-close';
41
- export interface UnresolvedBundlePublicationRetention {
42
- taskGroupId: string;
43
- trackIndex: number;
44
- }
45
- interface CasRecoveryAuthority {
46
- path: string;
47
- operation: 'replace' | 'delete';
48
- /** Deterministic from the persisted root/pre/post authority. */
49
- recoveryName: string;
50
- /** Deterministic public-entry quarantine used instead of check-then-unlink. */
51
- quarantineName: string;
52
- /** Deterministic prepared-byte name for replace/create operations. */
53
- tempName?: string;
54
- expectedHash: string | null;
55
- expectedMode: number | null;
56
- postHash: string | null;
57
- postMode: number | null;
58
- }
59
- /** Injected for deterministic tests; production uses the real filesystem. */
60
- export interface ShadowEnv {
61
- /** @deprecated Compatibility-only; filesystem snapshots do not use Git retries. */
62
- sleep?: (ms: number) => Promise<void>;
63
- /** Override the per-task state dir root (default `~/.codevibe/shadow-state`). */
64
- stateRootDir?: string;
65
- /** Override the shadow temp-dir root (default `os.tmpdir()`). */
66
- shadowRootDir?: string;
67
- /** @internal lower deterministic limit for serialized-marker boundary tests. */
68
- maxStateMarkerBytes?: number;
69
- /** TTL for the GC reaper. */
70
- ttlMs?: number;
71
- /** @internal lower deterministic workspace-authority helper deadline. */
72
- workspaceAuthorityHelperTimeoutMs?: number;
73
- /** @internal deterministic root/recovery authority stall seam. */
74
- testHangWorkspaceAuthorityStage?: (target: string, boundary: string) => 'realpath' | 'lstat' | 'open' | 'stat' | 'close' | undefined;
75
- /** Hook to terminate task-spawned children rooted in the shadow before teardown. */
76
- killChildrenInShadow?: (shadowDir: string) => Promise<void>;
77
- /** @internal lower deterministic aggregate quota for tests. */
78
- maxSessionPhysicalCopyBytes?: number;
79
- /** @internal lower deterministic aggregate pre-image quota for tests. */
80
- maxPromotionPreImageAggregateBytes?: number;
81
- /** Test seam after the stable source handle is opened but before physical streaming. */
82
- beforePhysicalCopy?: (source: string) => Promise<void>;
83
- /** @internal force the production helper's bounded physical-copy branch. */
84
- forcePhysicalMaterialization?: boolean;
85
- /** @internal lower deterministic materialization-helper deadline for tests. */
86
- materializationHelperTimeoutMs?: number;
87
- /** @internal deterministic live-workspace helper stall seam. */
88
- testHangMaterializationHelperStage?: (source: string) => MaterializationHangStage | undefined;
89
- /** Test seam after a tracked hash handle opens and before its bounded read. */
90
- beforeTrackedHashRead?: (filePath: string) => Promise<void>;
91
- /** Test seam after materialization and before hashing/marker persistence. */
92
- afterShadowMaterialized?: (shadowDir: string) => Promise<void>;
93
- /** Test seam immediately before each recovery-byte/directory durability sync. */
94
- beforeSnapshotDurabilitySync?: (kind: 'file' | 'directory' | 'parent', target: string) => Promise<void> | void;
95
- /** Test seam after copy and before the final durability seal + atomic exposure. */
96
- beforeSnapshotExpose?: (stagingDir: string, finalDir: string) => Promise<void> | void;
97
- /** @internal race seam after rename while the lifecycle fence is still held. */
98
- afterSnapshotExposeRename?: (finalDir: string) => Promise<void> | void;
99
- /** Test seam while the lifecycle fence is held, immediately before owner publication. */
100
- beforeSnapshotOwnerPublish?: (stagingDir: string) => Promise<void> | void;
101
- /** @internal failure seam after inode capture but before external authority commits. */
102
- beforeExposureRetentionPublish?: (stagingDir: string, retentionFile: string) => Promise<void> | void;
103
- /** Test seam after merge planning and before an integration snapshot is created. */
104
- beforePromotionWrite?: (path: string) => Promise<void>;
105
- /** Test seam before COMMIT; no live-workspace mutation has occurred yet. */
106
- beforePromotionCommit?: (path: string) => Promise<void>;
107
- /** Test seam after a promote temp file is fsynced, immediately before final CAS checks. */
108
- afterPromotionPrepared?: (path: string) => Promise<void>;
109
- /** Test seam after final live-parent validation; helper operations stay fd-anchored. */
110
- afterPromotionParentValidation?: (path: string) => Promise<void>;
111
- /** @internal lower deterministic CAS-helper deadline for tests. */
112
- promotionHelperTimeoutMs?: number;
113
- /** @internal deterministic CAS-helper target-filesystem stall seam. */
114
- testHangPromotionHelperStage?: (path: string) => 'root' | 'parent' | 'target' | undefined;
115
- /** @internal deterministic helper-death seam after COMMIT/mutation. */
116
- testCrashPromotionHelperStage?: (path: string) => CasHelperCrashStage | undefined;
117
- /** Test seam after the exact target is displaced but before replacement/deletion. */
118
- afterPromotionTargetDisplaced?: (path: string, recoveryName: string) => Promise<void>;
119
- /** Test seam immediately before the public target is atomically quarantined. */
120
- beforePromotionTargetQuarantine?: (path: string, quarantineName: string) => Promise<void>;
121
- /** Test seam immediately before identity-conditioned promotion quarantine unlink. */
122
- beforePromotionFinalUnlink?: (path: string, quarantineName: string) => Promise<void>;
123
- /** Test seam before rollback verifies/reverses a just-promoted path. */
124
- beforePromotionRollback?: (path: string) => Promise<void>;
125
- /** Test seam after an anchored marker parent is validated but before commit. */
126
- beforeMarkerWriteCommit?: (filePath: string) => Promise<void>;
127
- /** Test seam after marker CAS validation while the cross-process lock is held. */
128
- afterMarkerWriteValidation?: (filePath: string) => Promise<void>;
129
- /** @internal inject a post-publication directory-sync failure for a marker write. */
130
- failMarkerDirectorySync?: (filePath: string) => boolean;
131
- /** @internal inject a post-publication directory-sync failure for the quota registry. */
132
- failQuotaRegistryDirectorySync?: boolean;
133
- /** @internal pause after quota-lock acquisition and before strict state enumeration. */
134
- beforeQuotaFenceScan?: () => Promise<void>;
135
- /** @internal fail initial/retry shadow-root durability before acknowledgement. */
136
- failShadowRootDirectorySyncStage?: 'target-child' | 'target-parent';
137
- /** @internal fail initial/retry state-root durability before acknowledgement. */
138
- failStateRootDirectorySyncStage?: 'target-child' | 'target-parent';
139
- /** Test seam after disposal reads semantic state but before its CAS transition. */
140
- afterDisposalStateRead?: (state: ShadowPromoteState) => Promise<void>;
141
- /** Test-only: exercise the cross-process lock without the parent-process queue. */
142
- disableMarkerWriteProcessLock?: boolean;
143
- /** Test seam after an anchored snapshot parent is validated but before deletion. */
144
- beforeShadowDeleteCommit?: (shadowDir: string) => Promise<void>;
145
- /** Test seam after the owned snapshot was renamed and inode-verified. */
146
- afterShadowTombstoneRename?: (shadowDir: string, tombstoneDir: string) => Promise<void>;
147
- /** @internal exact lifecycle-lock release seam after snapshot cleanup. */
148
- beforeShadowLifecycleFinalRemove?: (artifactPath: string) => Promise<void> | void;
149
- /** Test seam after snapshot removal but before DISPOSING marker retirement. */
150
- afterShadowRemovedBeforeMarkerCleanup?: (shadowDir: string) => Promise<void>;
151
- /** @internal deterministic state-directory replacement before residue cleanup. */
152
- beforeCrashedStateArtifactCleanup?: (stateDir: string) => Promise<void> | void;
153
- /** @internal deterministic cleanup-block replacement before exact retirement. */
154
- beforeCleanupBlockFinalRemove?: (artifactPath: string) => Promise<void> | void;
155
- }
156
- /**
157
- * Legacy migration contract from the branch-tip implementation. New creates
158
- * ignore this option and always use a Git-independent snapshot. Historically it made a worktree a
159
- * PERSISTENT track branch instead of a detached HEAD, so the merge-train can
160
- * merge the track's committed tip. `baseSha` is the ONE group base pinned BEFORE
161
- * the first track shadow is created (so every track roots at the same base — a
162
- * deterministic merge-train input).
163
- */
164
- export interface TrackBranchSpec {
165
- /** The persistent branch name, e.g. `codevibe/track/<groupId>/<trackIndex>`. */
166
- name: string;
167
- /** The pinned group base commit the branch is created at. */
168
- baseSha: string;
169
- }
4
+ import { ReviewedShadowDiffFile, ShadowDiffFile, ShadowEnv, ShadowPromoteState, TrackBranchSpec, UnresolvedBundlePublicationRetention } from './shadow-protocol';
5
+ import { RecoveredShadow } from './shadow-recovery';
6
+ export { MAX_TRACKED_FILE_LOGICAL_BYTES, MAX_TRACKED_WORKSPACE_LOGICAL_BYTES, MAX_TRACKED_FILE_COUNT, MAX_TRACKED_PATH_BYTES, MAX_REVIEW_FILE_BYTES, MAX_PROMOTION_PREIMAGE_AGGREGATE_BYTES, MAX_STATE_MARKER_BYTES, DEFAULT_SHADOW_TTL_MS, } from './shadow-protocol';
7
+ export type { ShadowChangeKind, ShadowDiffFile, ReviewedShadowDiffFile, CasHelperCrashStage, UnresolvedBundlePublicationRetention, ShadowEnv, TrackBranchSpec, } from './shadow-protocol';
8
+ export { listRecoverableShadows, reconcileShadowPublicationAuthority, listShadowCleanupResidue, assertPathCollectionBounds, } from './shadow-recovery';
9
+ export type { RecoveredShadow, ShadowCleanupResidue } from './shadow-recovery';
10
+ export { replaceWorkspaceFileIfMatches, removeWorkspaceFileIfMatches, } from './anchored-cas';
11
+ export type { AcceptedAlternateImage } from './anchored-cas';
170
12
  /**
171
13
  * The desktop's per-task shadow workspace. ONE instance per active task; the
172
14
  * QuorumLoop creates it before the round-0 spawn, points the implementor cwd at
@@ -441,71 +283,6 @@ export declare class WorkspaceShadow {
441
283
  */
442
284
  static fromRecovered(recovered: RecoveredShadow, env?: ShadowEnv): Promise<WorkspaceShadow>;
443
285
  }
444
- /** A recovered shadow state (read from the durable per-task marker). */
445
- export interface RecoveredShadow {
446
- taskId: string;
447
- shadowDir: string;
448
- workingDir: string;
449
- shadowDirIdentity: AnchoredFsIdentity;
450
- snapshotRootAuthority: WorkspaceRootAuthority;
451
- workingDirIdentity: AnchoredFsIdentity;
452
- workspaceRootAuthority: WorkspaceRootAuthority;
453
- ownerProcessIdentity: ProcessIdentity;
454
- physicalCopyBytes: number;
455
- isGit: false;
456
- promoteState: ShadowPromoteState;
457
- createdAtMs: number;
458
- /** The durable state dir for this task (for cleanup). */
459
- stateDir: string;
460
- /** Exact instance marker (sibling restarts use separate files). */
461
- stateFile: string;
462
- /** Exact durable state container and marker authorities from the scan. */
463
- stateRootAuthority: WorkspaceRootAuthority;
464
- stateDirAuthority: WorkspaceRootAuthority;
465
- stateFileAuthority: AnchoredPathIdentity;
466
- /** Scan-time bridge incarnation, when disposal/exposure recovery has one. */
467
- exposureFileAuthority?: AnchoredPathIdentity;
468
- /** Immutable tracked paths and pre-task hashes, including deleted/absent paths. */
469
- baseline: Array<{
470
- path: string;
471
- hash: string | null;
472
- mode?: number | null;
473
- }>;
474
- promotePostHashes?: Array<{
475
- path: string;
476
- hash: string | null;
477
- mode?: number | null;
478
- }>;
479
- casRecovery?: CasRecoveryAuthority[];
480
- disposalSnapshotAuthority?: WorkspaceRootAuthority;
481
- disposalShadowIdentity?: AnchoredFsIdentity;
482
- /** Exact reviewed artifact persisted before authorization could resolve. */
483
- reviewedDiff?: ShadowDiffFile[];
484
- cleanupBlocked?: boolean;
485
- cleanupOwners?: ProcessCleanupOwner[];
486
- unresolvedAuthorityRetention?: UnresolvedBundlePublicationRetention;
487
- }
488
- export declare function listRecoverableShadows(env?: ShadowEnv): Promise<RecoveredShadow[]>;
489
- /**
490
- * Join or recover every known atomic writer owned by the supplied task ids
491
- * before strict teardown inventory. This is a mutating reconciliation step,
492
- * deliberately separate from `listShadowCleanupResidue`'s read-only audit.
493
- */
494
- export declare function reconcileShadowPublicationAuthority(taskIds: ReadonlySet<string>, env?: ShadowEnv): Promise<void>;
495
- export interface ShadowCleanupResidue {
496
- taskId: string;
497
- path: string;
498
- kind: 'recoverable-marker' | 'displaced-marker' | 'exposure-marker' | 'unresolved-authority' | 'state-directory' | 'snapshot-directory' | 'private-publication-authority';
499
- detail?: string;
500
- }
501
- /**
502
- * Exhaustive post-drain audit for exact task ids owned by one session. Unlike
503
- * `listRecoverableShadows`, this intentionally reports non-operational and
504
- * malformed authorities, empty owned state directories, snapshot/staging
505
- * directories, and private publication records. Cleanup failures may be
506
- * suppressed only when this inventory is empty.
507
- */
508
- export declare function listShadowCleanupResidue(taskIds: ReadonlySet<string>, env?: ShadowEnv): Promise<ShadowCleanupResidue[]>;
509
286
  /**
510
287
  * Reconstruct from a validated instance marker so recovery can re-run
511
288
  * promote/discard against an already-created filesystem snapshot.
@@ -526,67 +303,3 @@ export declare function reapOrphanShadows(keepTaskIds: ReadonlySet<string>, env?
526
303
  reaped: string[];
527
304
  retained: string[];
528
305
  }>;
529
- export declare function assertPathCollectionBounds(paths: readonly string[], label: string): void;
530
- export interface AcceptedAlternateImage {
531
- hash: string | null;
532
- mode: number | null;
533
- }
534
- /** Hardened reverse-apply surface shared by promotion and durable revert. */
535
- export declare function replaceWorkspaceFileIfMatches(args: {
536
- workingDir: string;
537
- workspaceRootAuthority: WorkspaceRootAuthority;
538
- path: string;
539
- content: string;
540
- mode: number;
541
- expectedHash: string | null;
542
- expectedMode: number | null;
543
- /** @internal deterministic last-commit race seam. */
544
- beforeCommit?: () => Promise<void> | undefined;
545
- /** @internal deterministic post-validation parent-swap seam. */
546
- afterValidation?: () => Promise<void> | undefined;
547
- /** @internal deterministic post-displacement recreation seam. */
548
- afterDisplacement?: (recoveryName: string) => Promise<void> | undefined;
549
- /** @internal deterministic public-target quarantine race seam. */
550
- beforeTargetQuarantine?: (quarantineName: string) => Promise<void> | undefined;
551
- /** @internal deterministic artifact-retirement race seam. */
552
- beforeFinalUnlink?: (recoveryName: string) => Promise<void> | undefined;
553
- /** @internal lower deterministic CAS-helper deadline for tests. */
554
- helperTimeoutMs?: number;
555
- /** @internal deterministic CAS-helper target-filesystem stall seam. */
556
- testHangHelperStage?: 'root' | 'parent' | 'target';
557
- /** @internal deterministic helper death after COMMIT/mutation. */
558
- testCrashHelperStage?: CasHelperCrashStage;
559
- /** Re-drive deterministic recovery names owned by an existing durable journal. */
560
- allowPostImageRecovery?: boolean;
561
- /** Exact terminal image that authorizes cleanup-only replay for same-path chains. */
562
- acceptedAlternate?: AcceptedAlternateImage;
563
- }): Promise<boolean>;
564
- /** Hardened reverse-delete surface shared by promotion and durable revert. */
565
- export declare function removeWorkspaceFileIfMatches(args: {
566
- workingDir: string;
567
- workspaceRootAuthority: WorkspaceRootAuthority;
568
- path: string;
569
- expectedHash: string | null;
570
- expectedMode: number | null;
571
- /** @internal deterministic last-commit race seam. */
572
- beforeCommit?: () => Promise<void> | undefined;
573
- /** @internal deterministic post-validation parent-swap seam. */
574
- afterValidation?: () => Promise<void> | undefined;
575
- /** @internal deterministic post-displacement recreation seam. */
576
- afterDisplacement?: (recoveryName: string) => Promise<void> | undefined;
577
- /** @internal deterministic public-target quarantine race seam. */
578
- beforeTargetQuarantine?: (quarantineName: string) => Promise<void> | undefined;
579
- /** @internal deterministic artifact-retirement race seam. */
580
- beforeFinalUnlink?: (recoveryName: string) => Promise<void> | undefined;
581
- /** @internal lower deterministic CAS-helper deadline for tests. */
582
- helperTimeoutMs?: number;
583
- /** @internal deterministic CAS-helper target-filesystem stall seam. */
584
- testHangHelperStage?: 'root' | 'parent' | 'target';
585
- /** @internal deterministic helper death after COMMIT/mutation. */
586
- testCrashHelperStage?: CasHelperCrashStage;
587
- /** Re-drive deterministic recovery names owned by an existing durable journal. */
588
- allowPostImageRecovery?: boolean;
589
- /** Exact terminal image that authorizes cleanup-only replay for same-path chains. */
590
- acceptedAlternate?: AcceptedAlternateImage;
591
- }): Promise<boolean>;
592
- export {};