@lmzhen/dsh-evolution-merge 0.47.0 → 0.49.0
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/lib/index.js +224 -775
- package/lib/types/adapters/engine-screen.d.ts +0 -3
- package/lib/types/authoring-flow.d.ts +5 -0
- package/lib/types/authoring-flow.js +17 -10
- package/lib/types/commit-execute.js +1 -22
- package/lib/types/contracts.d.ts +0 -1
- package/lib/types/contracts.js +0 -1
- package/lib/types/doctor.d.ts +0 -1
- package/lib/types/doctor.js +2 -31
- package/lib/types/domain/consistency.d.ts +0 -1
- package/lib/types/domain/consistency.js +2 -11
- package/lib/types/domain/merge-limits.d.ts +0 -10
- package/lib/types/domain/merge-limits.js +0 -3
- package/lib/types/domain/merge-snapshot.js +4 -6
- package/lib/types/domain/pair-ledger.d.ts +0 -1
- package/lib/types/domain/row-v3.d.ts +0 -45
- package/lib/types/domain/row-v3.js +0 -68
- package/lib/types/domain/row.d.ts +2 -84
- package/lib/types/domain/row.js +1 -110
- package/lib/types/domain/run-coordinator.d.ts +0 -24
- package/lib/types/domain/run-coordinator.js +0 -1
- package/lib/types/domain/stage-aggregate.d.ts +0 -42
- package/lib/types/domain/stage-aggregate.js +1 -116
- package/lib/types/domain/state-migrate.d.ts +27 -0
- package/lib/types/domain/state-migrate.js +29 -0
- package/lib/types/domain/state.d.ts +1 -53
- package/lib/types/domain/state.js +0 -55
- package/lib/types/domain/undo-journal.d.ts +4 -4
- package/lib/types/domain/undo-journal.js +5 -7
- package/lib/types/index.d.ts +0 -1
- package/lib/types/index.js +8 -14
- package/lib/types/new-child-authoring.js +4 -10
- package/lib/types/prompts.d.ts +0 -1
- package/lib/types/prompts.js +0 -1
- package/lib/types/read-commands.d.ts +0 -1
- package/lib/types/read-commands.js +0 -4
- package/lib/types/recovery-projection.js +0 -3
- package/lib/types/round2-outcome.js +15 -37
- package/lib/types/scan-run.js +0 -3
- package/lib/types/skipped.d.ts +1 -2
- package/lib/types/skipped.js +0 -8
- package/lib/types/staging.d.ts +0 -2
- package/lib/types/staging.js +0 -9
- package/lib/types/state.d.ts +0 -2
- package/lib/types/state.js +0 -13
- package/lib/types/surface/merge-view.d.ts +1 -2
- package/lib/types/surface/merge-view.js +0 -1
- package/lib/types/undo-operation.js +0 -9
- package/lib/types/unit-protocol.d.ts +6 -0
- package/lib/types/unit-protocol.js +72 -102
- package/package.json +10 -4
- package/scripts/merge-backup.mjs +31 -0
- package/scripts/merge-migrate.mjs +163 -0
- package/scripts/merge-restore.mjs +36 -0
- package/lib/types/commit-recovery.d.ts +0 -14
- package/lib/types/commit-recovery.js +0 -96
- package/lib/types/coordinator.d.ts +0 -77
- package/lib/types/coordinator.js +0 -137
- package/lib/types/domain/commit-journal-store.d.ts +0 -6
- package/lib/types/domain/commit-journal-store.js +0 -26
- package/lib/types/domain/commit-journal.d.ts +0 -16
- package/lib/types/domain/commit-journal.js +0 -26
- package/lib/types/domain/indexes.d.ts +0 -21
- package/lib/types/domain/indexes.js +0 -15
- package/lib/types/domain/merge-report.d.ts +0 -41
- package/lib/types/domain/merge-report.js +0 -2
- package/lib/types/domain/pair-index-store.d.ts +0 -6
- package/lib/types/domain/pair-index-store.js +0 -25
- package/lib/types/domain/pair-index.d.ts +0 -9
- package/lib/types/domain/pair-index.js +0 -28
- package/lib/types/domain/resolve-pair.d.ts +0 -4
- package/lib/types/domain/resolve-pair.js +0 -4
- package/lib/types/domain/row-tx.d.ts +0 -27
- package/lib/types/domain/row-tx.js +0 -31
- package/lib/types/domain/run-record.d.ts +0 -45
- package/lib/types/domain/run-record.js +0 -24
- package/lib/types/domain/state-v3.d.ts +0 -4
- package/lib/types/domain/state-v3.js +0 -4
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const NEXT = {
|
|
2
|
-
prepared: ['committed', 'target-written', 'failed'],
|
|
3
|
-
'target-written': ['sources-archived', 'rolled-back', 'failed'],
|
|
4
|
-
'sources-archived': ['committed', 'rolled-back', 'failed'],
|
|
5
|
-
committed: [],
|
|
6
|
-
'rolled-back': [],
|
|
7
|
-
failed: [],
|
|
8
|
-
};
|
|
9
|
-
export function advanceJournal(journal, phase, at) {
|
|
10
|
-
if (!NEXT[journal.phase].includes(phase))
|
|
11
|
-
throw new Error('invalid journal transition: ' + journal.phase + ' -> ' + phase);
|
|
12
|
-
return { ...journal, phase, updatedAt: at };
|
|
13
|
-
}
|
|
14
|
-
/** What a restart may do with the last durable phase. */
|
|
15
|
-
export function recoveryFor(journal) {
|
|
16
|
-
switch (journal.phase) {
|
|
17
|
-
case 'prepared': return 'retry-commit';
|
|
18
|
-
case 'target-written': return 'rollback-target';
|
|
19
|
-
case 'sources-archived': return 'rollback-sources';
|
|
20
|
-
case 'committed':
|
|
21
|
-
case 'rolled-back':
|
|
22
|
-
case 'failed': return 'none';
|
|
23
|
-
default: return 'refuse';
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=commit-journal.js.map
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/** Pure pairKey result index and archived-history projection. No IO. */
|
|
2
|
-
export interface PairIndexEntryV2 {
|
|
3
|
-
readonly pairKey: string;
|
|
4
|
-
readonly runId: string;
|
|
5
|
-
readonly result: 'merged' | 'kept' | 'failed' | 'cancelled' | 'undone';
|
|
6
|
-
readonly target?: string;
|
|
7
|
-
readonly reportRef?: string;
|
|
8
|
-
}
|
|
9
|
-
export type HistoryKind = 'merged' | 'deleted' | 'split' | 'other';
|
|
10
|
-
export interface HistoryRecord {
|
|
11
|
-
readonly name: string;
|
|
12
|
-
readonly kind: HistoryKind;
|
|
13
|
-
readonly reason: string;
|
|
14
|
-
readonly lastVersion: number;
|
|
15
|
-
readonly archivedAt: string;
|
|
16
|
-
readonly sourceRunId?: string;
|
|
17
|
-
}
|
|
18
|
-
export declare function putPair(index: ReadonlyMap<string, PairIndexEntryV2>, entry: PairIndexEntryV2): Map<string, PairIndexEntryV2>;
|
|
19
|
-
export declare function historyRecord(input: HistoryRecord): HistoryRecord;
|
|
20
|
-
export declare function summarizeHistory(records: readonly HistoryRecord[]): Record<HistoryKind, number>;
|
|
21
|
-
//# sourceMappingURL=indexes.d.ts.map
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export function putPair(index, entry) {
|
|
2
|
-
const next = new Map(index);
|
|
3
|
-
next.set(entry.pairKey, entry);
|
|
4
|
-
return next;
|
|
5
|
-
}
|
|
6
|
-
export function historyRecord(input) {
|
|
7
|
-
return { ...input, lastVersion: Math.max(1, Math.trunc(input.lastVersion)) };
|
|
8
|
-
}
|
|
9
|
-
export function summarizeHistory(records) {
|
|
10
|
-
const counts = { merged: 0, deleted: 0, split: 0, other: 0 };
|
|
11
|
-
for (const record of records)
|
|
12
|
-
counts[record.kind] += 1;
|
|
13
|
-
return counts;
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=indexes.js.map
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/** 1b-1 additive report schema; values are filled by later batches. */
|
|
2
|
-
export interface MergeReportLimits {
|
|
3
|
-
readonly maxSkillFileBytes?: number;
|
|
4
|
-
readonly maxTokenBytes?: number;
|
|
5
|
-
readonly pairTimeoutMinutes?: number;
|
|
6
|
-
}
|
|
7
|
-
export interface MergeReportValidation {
|
|
8
|
-
readonly ok: boolean;
|
|
9
|
-
readonly errors: readonly string[];
|
|
10
|
-
}
|
|
11
|
-
export interface MergeReport {
|
|
12
|
-
readonly schemaVersion: 2;
|
|
13
|
-
readonly reportId: string;
|
|
14
|
-
readonly runId: string;
|
|
15
|
-
readonly pairKey: string;
|
|
16
|
-
readonly target: string;
|
|
17
|
-
readonly sourceRevisions?: Readonly<Record<string, string>>;
|
|
18
|
-
readonly targetRevision?: string;
|
|
19
|
-
readonly validation: MergeReportValidation;
|
|
20
|
-
readonly limits: MergeReportLimits;
|
|
21
|
-
readonly q09?: {
|
|
22
|
-
readonly forwardRefs: readonly string[];
|
|
23
|
-
readonly reverseRefs: readonly string[];
|
|
24
|
-
readonly orphanFiles: readonly string[];
|
|
25
|
-
};
|
|
26
|
-
readonly threat?: {
|
|
27
|
-
readonly body: string;
|
|
28
|
-
readonly source: string;
|
|
29
|
-
};
|
|
30
|
-
readonly createdAt: string;
|
|
31
|
-
}
|
|
32
|
-
export interface MergeReportRef {
|
|
33
|
-
readonly path: string;
|
|
34
|
-
readonly digest: string;
|
|
35
|
-
readonly writtenAt: string;
|
|
36
|
-
}
|
|
37
|
-
export interface MergeReportWriter {
|
|
38
|
-
write(report: MergeReport): Promise<MergeReportRef>;
|
|
39
|
-
read(runId: string): Promise<MergeReport | null>;
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=merge-report.d.ts.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import type { EvolutionIoLike } from '@lmzhen/dsh-evolution-core';
|
|
2
|
-
import type { PairIndexEntryV2 } from './indexes.ts';
|
|
3
|
-
export declare function pairIndexPath(home: string): string;
|
|
4
|
-
export declare function loadPairIndex(io: EvolutionIoLike, home: string): Promise<Map<string, PairIndexEntryV2>>;
|
|
5
|
-
export declare function recordPair(io: EvolutionIoLike, home: string, entry: PairIndexEntryV2): Promise<void>;
|
|
6
|
-
//# sourceMappingURL=pair-index-store.d.ts.map
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/** Durable pairKey index at <home>/merge/pair-index.json. */
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { transactIo } from '@lmzhen/dsh-evolution-core';
|
|
4
|
-
import { parsePairIndex, serializePairIndex } from "./pair-index.js";
|
|
5
|
-
export function pairIndexPath(home) {
|
|
6
|
-
return join(home, 'merge', 'pair-index.json');
|
|
7
|
-
}
|
|
8
|
-
export async function loadPairIndex(io, home) {
|
|
9
|
-
let raw = null;
|
|
10
|
-
try {
|
|
11
|
-
raw = await io.readText(pairIndexPath(home));
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return new Map();
|
|
15
|
-
}
|
|
16
|
-
return parsePairIndex(raw);
|
|
17
|
-
}
|
|
18
|
-
export async function recordPair(io, home, entry) {
|
|
19
|
-
await transactIo(io, pairIndexPath(home), (current) => {
|
|
20
|
-
const index = parsePairIndex(current);
|
|
21
|
-
index.set(entry.pairKey, entry);
|
|
22
|
-
return serializePairIndex(index);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
//# sourceMappingURL=pair-index-store.js.map
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/** Pure pairKey index serialization. No IO. */
|
|
2
|
-
import type { PairIndexEntryV2 } from './indexes.ts';
|
|
3
|
-
export interface PairIndexFile {
|
|
4
|
-
readonly schemaVersion: 1;
|
|
5
|
-
readonly entries: readonly PairIndexEntryV2[];
|
|
6
|
-
}
|
|
7
|
-
export declare function parsePairIndex(raw: string | null): Map<string, PairIndexEntryV2>;
|
|
8
|
-
export declare function serializePairIndex(index: ReadonlyMap<string, PairIndexEntryV2>): string;
|
|
9
|
-
//# sourceMappingURL=pair-index.d.ts.map
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
export function parsePairIndex(raw) {
|
|
2
|
-
const index = new Map();
|
|
3
|
-
if (raw === null)
|
|
4
|
-
return index;
|
|
5
|
-
let parsed;
|
|
6
|
-
try {
|
|
7
|
-
parsed = JSON.parse(raw);
|
|
8
|
-
}
|
|
9
|
-
catch {
|
|
10
|
-
return index;
|
|
11
|
-
}
|
|
12
|
-
const body = parsed;
|
|
13
|
-
if (!Array.isArray(body.entries))
|
|
14
|
-
return index;
|
|
15
|
-
for (const value of body.entries) {
|
|
16
|
-
const entry = value;
|
|
17
|
-
if (typeof entry.pairKey !== 'string' || typeof entry.runId !== 'string' || typeof entry.result !== 'string')
|
|
18
|
-
continue;
|
|
19
|
-
if (!['merged', 'kept', 'failed', 'cancelled', 'undone'].includes(entry.result))
|
|
20
|
-
continue;
|
|
21
|
-
index.set(entry.pairKey, entry);
|
|
22
|
-
}
|
|
23
|
-
return index;
|
|
24
|
-
}
|
|
25
|
-
export function serializePairIndex(index) {
|
|
26
|
-
return JSON.stringify({ schemaVersion: 1, entries: [...index.values()] }, null, 2);
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=pair-index.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
/** Pure pair-index lookup. No run-record merge fields. */
|
|
2
|
-
import type { PairIndexEntryV2 } from './indexes.ts';
|
|
3
|
-
export declare function findPairRun(pairs: readonly PairIndexEntryV2[], pairKey: string): PairIndexEntryV2 | undefined;
|
|
4
|
-
//# sourceMappingURL=resolve-pair.d.ts.map
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/** G3-5 RowTx pure write API: only createVerify/createSkipped/transition. */
|
|
2
|
-
import { type SkippedRowV3, type V3Event, type V3Row, type VerifyRowV3 } from './row-v3.ts';
|
|
3
|
-
export type RowWrite = {
|
|
4
|
-
readonly kind: 'createVerify';
|
|
5
|
-
readonly row: VerifyRowV3;
|
|
6
|
-
} | {
|
|
7
|
-
readonly kind: 'createSkipped';
|
|
8
|
-
readonly row: SkippedRowV3;
|
|
9
|
-
} | {
|
|
10
|
-
readonly kind: 'transition';
|
|
11
|
-
readonly id: string;
|
|
12
|
-
readonly event: V3Event;
|
|
13
|
-
readonly expectedVersion: number;
|
|
14
|
-
};
|
|
15
|
-
type RowWriteErrorCode = 'row-invalid' | 'row-duplicate' | 'row-not-found' | 'version-conflict' | 'illegal-transition';
|
|
16
|
-
export type RowWriteResult = {
|
|
17
|
-
readonly ok: true;
|
|
18
|
-
readonly rows: readonly V3Row[];
|
|
19
|
-
readonly row: V3Row | null;
|
|
20
|
-
} | {
|
|
21
|
-
readonly ok: false;
|
|
22
|
-
readonly code: RowWriteErrorCode;
|
|
23
|
-
readonly message: string;
|
|
24
|
-
};
|
|
25
|
-
export declare function applyRowWrite(rows: readonly V3Row[], write: RowWrite, at: string): RowWriteResult;
|
|
26
|
-
export {};
|
|
27
|
-
//# sourceMappingURL=row-tx.d.ts.map
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/** G3-5 RowTx pure write API: only createVerify/createSkipped/transition. */
|
|
2
|
-
import { isV3Row, transitionV3 } from "./row-v3.js";
|
|
3
|
-
function bad(code, message) { return { ok: false, code, message }; }
|
|
4
|
-
export function applyRowWrite(rows, write, at) {
|
|
5
|
-
if (write.kind === 'transition') {
|
|
6
|
-
const index = rows.findIndex(row => row.id === write.id);
|
|
7
|
-
if (index < 0)
|
|
8
|
-
return bad('row-not-found', 'row not found: ' + write.id);
|
|
9
|
-
const current = rows[index];
|
|
10
|
-
const moved = transitionV3(current, write.event, write.expectedVersion, at);
|
|
11
|
-
if (!moved.ok)
|
|
12
|
-
return bad(moved.code, moved.message);
|
|
13
|
-
if (moved.row === null)
|
|
14
|
-
return { ok: true, rows: rows.filter((_, atIndex) => atIndex !== index), row: null };
|
|
15
|
-
const next = [...rows];
|
|
16
|
-
next[index] = moved.row;
|
|
17
|
-
return { ok: true, rows: next, row: moved.row };
|
|
18
|
-
}
|
|
19
|
-
if (write.row.version !== 0)
|
|
20
|
-
return bad('row-invalid', 'create requires version 0');
|
|
21
|
-
if (write.kind === 'createVerify' && (write.row.state !== 'verify' || write.row.verifySubState !== 'unverified'))
|
|
22
|
-
return bad('row-invalid', 'createVerify requires verify/unverified');
|
|
23
|
-
if (write.kind === 'createSkipped' && write.row.state !== 'skipped')
|
|
24
|
-
return bad('row-invalid', 'createSkipped requires skipped');
|
|
25
|
-
if (!isV3Row(write.row))
|
|
26
|
-
return bad('row-invalid', 'created row is invalid');
|
|
27
|
-
if (rows.some(row => row.id === write.row.id))
|
|
28
|
-
return bad('row-duplicate', 'duplicate row id: ' + write.row.id);
|
|
29
|
-
return { ok: true, rows: [...rows, write.row], row: write.row };
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=row-tx.js.map
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/** Pure RunRecord v2 types and derived 9-state projection. No IO. */
|
|
2
|
-
export type RunStatus = 'running' | 'succeeded' | 'failed' | 'cancelled' | 'interrupted' | 'orphan';
|
|
3
|
-
export type MergeStatus = 'running' | 'succeeded' | 'failed' | 'cancelled' | 'awaiting-approval' | 'undone' | 'superseded' | 'interrupted' | 'orphan';
|
|
4
|
-
export type PairResult = 'pending' | 'merged' | 'kept' | 'failed' | 'cancelled' | 'undone';
|
|
5
|
-
export interface PairRecord {
|
|
6
|
-
readonly pairKey: string;
|
|
7
|
-
readonly a: string;
|
|
8
|
-
readonly b: string;
|
|
9
|
-
readonly result: PairResult;
|
|
10
|
-
readonly target?: {
|
|
11
|
-
readonly requested: string;
|
|
12
|
-
readonly actual?: string;
|
|
13
|
-
readonly created?: boolean;
|
|
14
|
-
};
|
|
15
|
-
readonly stagingRef?: string;
|
|
16
|
-
readonly committed?: boolean;
|
|
17
|
-
}
|
|
18
|
-
export interface PairIndexEntry {
|
|
19
|
-
readonly pairKey: string;
|
|
20
|
-
readonly runId: string;
|
|
21
|
-
readonly result: PairResult;
|
|
22
|
-
readonly target?: string;
|
|
23
|
-
readonly reportRef?: string;
|
|
24
|
-
}
|
|
25
|
-
export interface RunRecordV2 {
|
|
26
|
-
readonly id: string;
|
|
27
|
-
readonly kind: 'merge';
|
|
28
|
-
readonly status: RunStatus;
|
|
29
|
-
readonly stage?: 'screening' | 'decide' | 'author' | 'commit' | 'settle';
|
|
30
|
-
readonly approval?: 'on' | 'off';
|
|
31
|
-
readonly parentRunId?: string;
|
|
32
|
-
readonly pairKey?: string;
|
|
33
|
-
readonly plane?: 'local' | 'foreign';
|
|
34
|
-
readonly startedAt: number;
|
|
35
|
-
readonly updatedAt: number;
|
|
36
|
-
readonly endedAt?: number;
|
|
37
|
-
readonly resultRef?: string;
|
|
38
|
-
readonly failure?: string;
|
|
39
|
-
readonly stagingRef?: string;
|
|
40
|
-
readonly pairs: readonly PairRecord[];
|
|
41
|
-
readonly supersededAt?: number;
|
|
42
|
-
}
|
|
43
|
-
export declare function deriveMergeStatus(record: RunRecordV2): MergeStatus;
|
|
44
|
-
export declare function allCommittedUndone(record: RunRecordV2): boolean;
|
|
45
|
-
//# sourceMappingURL=run-record.d.ts.map
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export function deriveMergeStatus(record) {
|
|
2
|
-
if (record.supersededAt !== undefined)
|
|
3
|
-
return 'superseded';
|
|
4
|
-
if (record.status === 'interrupted')
|
|
5
|
-
return 'interrupted';
|
|
6
|
-
if (record.status === 'orphan')
|
|
7
|
-
return 'orphan';
|
|
8
|
-
if (record.status === 'failed' || record.status === 'cancelled')
|
|
9
|
-
return record.status;
|
|
10
|
-
if (record.status === 'running') {
|
|
11
|
-
return record.approval === 'on' && record.pairs.some(pair => pair.result === 'pending')
|
|
12
|
-
? 'awaiting-approval'
|
|
13
|
-
: 'running';
|
|
14
|
-
}
|
|
15
|
-
const committed = record.pairs.filter(pair => pair.committed === true);
|
|
16
|
-
if (committed.length > 0 && committed.every(pair => pair.result === 'undone'))
|
|
17
|
-
return 'undone';
|
|
18
|
-
return 'succeeded';
|
|
19
|
-
}
|
|
20
|
-
export function allCommittedUndone(record) {
|
|
21
|
-
const committed = record.pairs.filter(pair => pair.committed === true);
|
|
22
|
-
return committed.length > 0 && committed.every(pair => pair.result === 'undone');
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=run-record.js.map
|