@cleocode/core 2026.10.12 → 2026.10.13
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/build-provenance.json +2 -2
- package/dist/cloud/nexus-auth.d.ts.map +1 -1
- package/dist/cloud/nexus-auth.js +11 -2
- package/dist/cloud/nexus-auth.js.map +1 -1
- package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
- package/dist/cloud/nexus-cloud-status.js +18 -5
- package/dist/cloud/nexus-cloud-status.js.map +1 -1
- package/dist/cloud/nexus-credentials.d.ts +3 -2
- package/dist/cloud/nexus-credentials.d.ts.map +1 -1
- package/dist/cloud/nexus-credentials.js +58 -14
- package/dist/cloud/nexus-credentials.js.map +1 -1
- package/dist/cloud/nexus-logout.d.ts.map +1 -1
- package/dist/cloud/nexus-logout.js +12 -2
- package/dist/cloud/nexus-logout.js.map +1 -1
- package/dist/cloud/nexus-vault-state.d.ts.map +1 -1
- package/dist/cloud/nexus-vault-state.js +6 -26
- package/dist/cloud/nexus-vault-state.js.map +1 -1
- package/dist/config/registry.d.ts +21 -0
- package/dist/config/registry.d.ts.map +1 -1
- package/dist/config/registry.js +41 -0
- package/dist/config/registry.js.map +1 -1
- package/dist/dispatch/mvi-projection.d.ts.map +1 -1
- package/dist/dispatch/mvi-projection.js +2 -0
- package/dist/dispatch/mvi-projection.js.map +1 -1
- package/dist/docs/docs-ops.d.ts +15 -14
- package/dist/docs/docs-ops.d.ts.map +1 -1
- package/dist/docs/docs-ops.js +32 -96
- package/dist/docs/docs-ops.js.map +1 -1
- package/dist/docs/docs-read-model.d.ts +19 -10
- package/dist/docs/docs-read-model.d.ts.map +1 -1
- package/dist/docs/docs-read-model.js +31 -47
- package/dist/docs/docs-read-model.js.map +1 -1
- package/dist/docs/docs-update.d.ts +51 -1
- package/dist/docs/docs-update.d.ts.map +1 -1
- package/dist/docs/docs-update.js +235 -13
- package/dist/docs/docs-update.js.map +1 -1
- package/dist/docs/doctor.d.ts +26 -4
- package/dist/docs/doctor.d.ts.map +1 -1
- package/dist/docs/doctor.js +260 -102
- package/dist/docs/doctor.js.map +1 -1
- package/dist/docs/fetch-result.d.ts +30 -10
- package/dist/docs/fetch-result.d.ts.map +1 -1
- package/dist/docs/fetch-result.js +100 -15
- package/dist/docs/fetch-result.js.map +1 -1
- package/dist/docs/index.d.ts +1 -0
- package/dist/docs/index.d.ts.map +1 -1
- package/dist/docs/index.js +1 -0
- package/dist/docs/index.js.map +1 -1
- package/dist/docs/legacy-doc-migration.d.ts +182 -0
- package/dist/docs/legacy-doc-migration.d.ts.map +1 -0
- package/dist/docs/legacy-doc-migration.js +480 -0
- package/dist/docs/legacy-doc-migration.js.map +1 -0
- package/dist/docs/publications-store.d.ts +67 -0
- package/dist/docs/publications-store.d.ts.map +1 -0
- package/dist/docs/publications-store.js +193 -0
- package/dist/docs/publications-store.js.map +1 -0
- package/dist/docs/publish-pr.d.ts.map +1 -1
- package/dist/docs/publish-pr.js +31 -18
- package/dist/docs/publish-pr.js.map +1 -1
- package/dist/docs/section-leases.d.ts +233 -0
- package/dist/docs/section-leases.d.ts.map +1 -0
- package/dist/docs/section-leases.js +344 -0
- package/dist/docs/section-leases.js.map +1 -0
- package/dist/docs/section-merge.d.ts +159 -0
- package/dist/docs/section-merge.d.ts.map +1 -0
- package/dist/docs/section-merge.js +215 -0
- package/dist/docs/section-merge.js.map +1 -0
- package/dist/docs/section-write-path.d.ts +191 -0
- package/dist/docs/section-write-path.d.ts.map +1 -0
- package/dist/docs/section-write-path.js +423 -0
- package/dist/docs/section-write-path.js.map +1 -0
- package/dist/docs/stats.d.ts +56 -0
- package/dist/docs/stats.d.ts.map +1 -0
- package/dist/docs/stats.js +119 -0
- package/dist/docs/stats.js.map +1 -0
- package/dist/gc/cleanup.d.ts +1 -1
- package/dist/gc/cleanup.d.ts.map +1 -1
- package/dist/gc/cleanup.js +10 -1
- package/dist/gc/cleanup.js.map +1 -1
- package/dist/gc/janitor.js +1 -1
- package/dist/gc/janitor.js.map +1 -1
- package/dist/internal.d.ts +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.d.ts +34 -0
- package/dist/memory/pipeline-manifest-sqlite.d.ts.map +1 -1
- package/dist/memory/pipeline-manifest-sqlite.js +114 -0
- package/dist/memory/pipeline-manifest-sqlite.js.map +1 -1
- package/dist/nexus/analyze-orchestrator.d.ts +5 -1
- package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
- package/dist/nexus/analyze-orchestrator.js +25 -13
- package/dist/nexus/analyze-orchestrator.js.map +1 -1
- package/dist/nexus/assessment-store.d.ts +8 -4
- package/dist/nexus/assessment-store.d.ts.map +1 -1
- package/dist/nexus/assessment-store.js +18 -27
- package/dist/nexus/assessment-store.js.map +1 -1
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +6 -0
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/lean-change.d.ts +104 -5
- package/dist/orchestration/lean-change.d.ts.map +1 -1
- package/dist/orchestration/lean-change.js +162 -6
- package/dist/orchestration/lean-change.js.map +1 -1
- package/dist/orchestration/spawn-prompt.d.ts +6 -1
- package/dist/orchestration/spawn-prompt.d.ts.map +1 -1
- package/dist/orchestration/spawn-prompt.js +3 -1
- package/dist/orchestration/spawn-prompt.js.map +1 -1
- package/dist/orchestration/spawn.d.ts.map +1 -1
- package/dist/orchestration/spawn.js +6 -0
- package/dist/orchestration/spawn.js.map +1 -1
- package/dist/release/open.d.ts.map +1 -1
- package/dist/release/open.js +6 -2
- package/dist/release/open.js.map +1 -1
- package/dist/release/plan.d.ts.map +1 -1
- package/dist/release/plan.js +33 -2
- package/dist/release/plan.js.map +1 -1
- package/dist/resources/admission-ledger.d.ts +5 -0
- package/dist/resources/admission-ledger.d.ts.map +1 -1
- package/dist/resources/admission-ledger.js +1 -1
- package/dist/resources/admission-ledger.js.map +1 -1
- package/dist/resources/run-admission.d.ts.map +1 -1
- package/dist/resources/run-admission.js +4 -1
- package/dist/resources/run-admission.js.map +1 -1
- package/dist/resources/run-governed.d.ts +29 -4
- package/dist/resources/run-governed.d.ts.map +1 -1
- package/dist/resources/run-governed.js +113 -73
- package/dist/resources/run-governed.js.map +1 -1
- package/dist/sentient/worktree-dispatch.d.ts +12 -1
- package/dist/sentient/worktree-dispatch.d.ts.map +1 -1
- package/dist/sentient/worktree-dispatch.js +19 -0
- package/dist/sentient/worktree-dispatch.js.map +1 -1
- package/dist/spawn/branch-lock.d.ts +11 -1
- package/dist/spawn/branch-lock.d.ts.map +1 -1
- package/dist/spawn/branch-lock.js +54 -4
- package/dist/spawn/branch-lock.js.map +1 -1
- package/dist/sticky/archive.d.ts +1 -0
- package/dist/sticky/archive.d.ts.map +1 -1
- package/dist/sticky/archive.js +13 -0
- package/dist/sticky/archive.js.map +1 -1
- package/dist/sticky/engine-ops.d.ts.map +1 -1
- package/dist/sticky/engine-ops.js +7 -0
- package/dist/sticky/engine-ops.js.map +1 -1
- package/dist/store/attachment-repair.d.ts +10 -4
- package/dist/store/attachment-repair.d.ts.map +1 -1
- package/dist/store/attachment-repair.js +52 -25
- package/dist/store/attachment-repair.js.map +1 -1
- package/dist/store/attachment-store.d.ts.map +1 -1
- package/dist/store/attachment-store.js +27 -18
- package/dist/store/attachment-store.js.map +1 -1
- package/dist/store/blob-keep.d.ts +83 -0
- package/dist/store/blob-keep.d.ts.map +1 -1
- package/dist/store/blob-keep.js +139 -0
- package/dist/store/blob-keep.js.map +1 -1
- package/dist/store/blob-ops.d.ts +24 -0
- package/dist/store/blob-ops.d.ts.map +1 -1
- package/dist/store/blob-ops.js +47 -0
- package/dist/store/blob-ops.js.map +1 -1
- package/dist/store/conduit-doc-history.d.ts +209 -0
- package/dist/store/conduit-doc-history.d.ts.map +1 -1
- package/dist/store/conduit-doc-history.js +315 -3
- package/dist/store/conduit-doc-history.js.map +1 -1
- package/dist/store/decision-adr-links.d.ts +11 -0
- package/dist/store/decision-adr-links.d.ts.map +1 -1
- package/dist/store/decision-adr-links.js +20 -1
- package/dist/store/decision-adr-links.js.map +1 -1
- package/dist/store/display-id-alias.d.ts +8 -2
- package/dist/store/display-id-alias.d.ts.map +1 -1
- package/dist/store/display-id-alias.js +8 -3
- package/dist/store/display-id-alias.js.map +1 -1
- package/dist/store/lock.d.ts +18 -0
- package/dist/store/lock.d.ts.map +1 -1
- package/dist/store/lock.js +41 -0
- package/dist/store/lock.js.map +1 -1
- package/dist/store/row-identity-registry.d.ts.map +1 -1
- package/dist/store/row-identity-registry.js +17 -0
- package/dist/store/row-identity-registry.js.map +1 -1
- package/dist/store/schema/cleo-project/conduit.d.ts +16 -0
- package/dist/store/schema/cleo-project/conduit.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/conduit.js +8 -0
- package/dist/store/schema/cleo-project/conduit.js.map +1 -1
- package/dist/store/schema/cleo-project/docs.d.ts +294 -0
- package/dist/store/schema/cleo-project/docs.d.ts.map +1 -1
- package/dist/store/schema/cleo-project/docs.js +82 -0
- package/dist/store/schema/cleo-project/docs.js.map +1 -1
- package/dist/store/sync/hlc.d.ts +9 -0
- package/dist/store/sync/hlc.d.ts.map +1 -1
- package/dist/store/sync/hlc.js +9 -0
- package/dist/store/sync/hlc.js.map +1 -1
- package/dist/store/sync/merge/engine.d.ts.map +1 -1
- package/dist/store/sync/merge/engine.js +4 -2
- package/dist/store/sync/merge/engine.js.map +1 -1
- package/dist/store/sync/merge/rules.d.ts +12 -1
- package/dist/store/sync/merge/rules.d.ts.map +1 -1
- package/dist/store/sync/merge/rules.js +76 -1
- package/dist/store/sync/merge/rules.js.map +1 -1
- package/dist/store/sync/replica-registry.d.ts +6 -2
- package/dist/store/sync/replica-registry.d.ts.map +1 -1
- package/dist/store/sync/replica-registry.js +21 -9
- package/dist/store/sync/replica-registry.js.map +1 -1
- package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
- package/dist/store/sync/timestamp-canon.js +6 -0
- package/dist/store/sync/timestamp-canon.js.map +1 -1
- package/dist/store/table-classification.d.ts +58 -0
- package/dist/store/table-classification.d.ts.map +1 -1
- package/dist/store/table-classification.js +72 -0
- package/dist/store/table-classification.js.map +1 -1
- package/dist/store/twin-collapse.d.ts.map +1 -1
- package/dist/store/twin-collapse.js +4 -1
- package/dist/store/twin-collapse.js.map +1 -1
- package/dist/store/vault-manifest.d.ts +10 -1
- package/dist/store/vault-manifest.d.ts.map +1 -1
- package/dist/store/vault-manifest.js +59 -1
- package/dist/store/vault-manifest.js.map +1 -1
- package/dist/tasks/affected-scope.d.ts +11 -0
- package/dist/tasks/affected-scope.d.ts.map +1 -1
- package/dist/tasks/affected-scope.js +30 -11
- package/dist/tasks/affected-scope.js.map +1 -1
- package/dist/tasks/cancel-ops.d.ts.map +1 -1
- package/dist/tasks/cancel-ops.js +7 -2
- package/dist/tasks/cancel-ops.js.map +1 -1
- package/dist/tasks/change-set.d.ts +22 -0
- package/dist/tasks/change-set.d.ts.map +1 -1
- package/dist/tasks/change-set.js +119 -2
- package/dist/tasks/change-set.js.map +1 -1
- package/dist/tasks/complete.d.ts.map +1 -1
- package/dist/tasks/complete.js +7 -0
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/done-plan.d.ts +5 -0
- package/dist/tasks/done-plan.d.ts.map +1 -1
- package/dist/tasks/done-plan.js +54 -19
- package/dist/tasks/done-plan.js.map +1 -1
- package/dist/tasks/engine-wrap.d.ts +4 -0
- package/dist/tasks/engine-wrap.d.ts.map +1 -1
- package/dist/tasks/engine-wrap.js +20 -4
- package/dist/tasks/engine-wrap.js.map +1 -1
- package/dist/tasks/evidence-paths.d.ts +11 -0
- package/dist/tasks/evidence-paths.d.ts.map +1 -1
- package/dist/tasks/evidence-paths.js +12 -0
- package/dist/tasks/evidence-paths.js.map +1 -1
- package/dist/tools/fs.d.ts +7 -3
- package/dist/tools/fs.d.ts.map +1 -1
- package/dist/tools/fs.js +23 -8
- package/dist/tools/fs.js.map +1 -1
- package/dist/worktree/list.d.ts.map +1 -1
- package/dist/worktree/list.js +9 -0
- package/dist/worktree/list.js.map +1 -1
- package/dist/worktree/prune.d.ts.map +1 -1
- package/dist/worktree/prune.js +52 -1
- package/dist/worktree/prune.js.map +1 -1
- package/migrations/drizzle-cleo-project/20261013000000_t13360-migrated-doc-import/migration.sql +61 -0
- package/migrations/drizzle-cleo-project/20261014000000_t13362-docs-publications-ledger/migration.sql +45 -0
- package/package.json +13 -13
- package/templates/CLEO-INJECTION.md +1 -1
- package/templates/CLEO-REFERENCE.md +2 -2
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section CRDT merge engine — the pure core of the CleoDocs re-architecture
|
|
3
|
+
* write path (T13355 · spec `cleodocs-rearch-design` §2 option b · D11165).
|
|
4
|
+
*
|
|
5
|
+
* Every document section is one Loro document (root `LoroText` named
|
|
6
|
+
* `content`), persisted as opaque snapshot bytes in the local-only
|
|
7
|
+
* `section_crdt_states` table. This module is the ONLY production importer of
|
|
8
|
+
* `llmtxt/crdt-primitives` (the llmtxt WASM-backed Loro primitives); the
|
|
9
|
+
* store orchestration in `section-write-path.ts` composes these functions
|
|
10
|
+
* with the canonical `conduit-doc-history.ts` accessors.
|
|
11
|
+
*
|
|
12
|
+
* Merge composition (spike finding, T13353): the WASM `crdt_merge_updates`
|
|
13
|
+
* is LOSSY in llmtxt@2026.5.15 — it returns an empty-doc snapshot for any
|
|
14
|
+
* input (kryptobaseddev/llmtxt#17, tracked in T13356). All merging here
|
|
15
|
+
* therefore composes updates via sequential {@link mergeSectionUpdates}
|
|
16
|
+
* (`crdt_apply_update`), which Loro makes idempotent and convergent:
|
|
17
|
+
* applying each peer's incremental update in turn yields every edit with an
|
|
18
|
+
* order-independent final text. `crdt_merge_updates` must NOT be used in the
|
|
19
|
+
* production path until the upstream fix lands.
|
|
20
|
+
*
|
|
21
|
+
* @module
|
|
22
|
+
* @task T13355
|
|
23
|
+
* @epic T13340
|
|
24
|
+
* @saga T13339
|
|
25
|
+
*/
|
|
26
|
+
import { crdt_apply_update, crdt_get_text, crdt_make_incremental_update, crdt_make_state, } from 'llmtxt/crdt-primitives';
|
|
27
|
+
/**
|
|
28
|
+
* Deterministic section id for a split index. Section ids are positional
|
|
29
|
+
* (`s0` is the H1 + preamble, `s1` the first `## ` block, …): stable across
|
|
30
|
+
* devices for the same document shape and independent of heading text.
|
|
31
|
+
* Positional ids are a known simplification — heading-anchored ids are the
|
|
32
|
+
* filed follow-up (T13584).
|
|
33
|
+
*
|
|
34
|
+
* @param index - The section's position in {@link splitDocIntoSections}.
|
|
35
|
+
* @returns The section id recorded in `sections_modified`.
|
|
36
|
+
*/
|
|
37
|
+
export function sectionId(index) {
|
|
38
|
+
return `s${index}`;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Split a markdown document into sections deterministically: the H1 +
|
|
42
|
+
* preamble (everything before the first `## ` heading) is section 0; each
|
|
43
|
+
* `## ` heading starts a new section that runs (with its nested `###`
|
|
44
|
+
* blocks) to the next `## ` or EOF. Concatenating the sections with
|
|
45
|
+
* {@link joinSections} reproduces the input byte-for-byte, so the split is
|
|
46
|
+
* lossless and order-stable.
|
|
47
|
+
*
|
|
48
|
+
* @param markdown - The full document text.
|
|
49
|
+
* @returns The sections in document order.
|
|
50
|
+
*/
|
|
51
|
+
export function splitDocIntoSections(markdown) {
|
|
52
|
+
const lines = markdown.split('\n');
|
|
53
|
+
const sections = [];
|
|
54
|
+
let current = [];
|
|
55
|
+
for (const line of lines) {
|
|
56
|
+
if (line.startsWith('## ') && current.length > 0) {
|
|
57
|
+
sections.push(current.join('\n'));
|
|
58
|
+
current = [];
|
|
59
|
+
}
|
|
60
|
+
current.push(line);
|
|
61
|
+
}
|
|
62
|
+
sections.push(current.join('\n'));
|
|
63
|
+
return sections;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The inverse of {@link splitDocIntoSections}.
|
|
67
|
+
*
|
|
68
|
+
* @param sections - Sections in document order.
|
|
69
|
+
* @returns The reassembled document text.
|
|
70
|
+
*/
|
|
71
|
+
export function joinSections(sections) {
|
|
72
|
+
return sections.join('\n');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Seed a section Loro state from full text (a new or re-based section).
|
|
76
|
+
*
|
|
77
|
+
* @param text - The section's full text.
|
|
78
|
+
* @returns A Loro snapshot encoding the section.
|
|
79
|
+
*/
|
|
80
|
+
export function seedSectionState(text) {
|
|
81
|
+
return crdt_make_state(text);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Express one local edit as an incremental Loro update against a base
|
|
85
|
+
* state. The bundled primitives are append-shaped: the edit is the text to
|
|
86
|
+
* append to the base section (callers compute it as the tail of the new
|
|
87
|
+
* text when the old text is a prefix of it).
|
|
88
|
+
*
|
|
89
|
+
* @param base - The base section snapshot the edit was authored against.
|
|
90
|
+
* @param appended - The text the edit appends to the base.
|
|
91
|
+
* @returns The incremental update (the delta only, not a full snapshot).
|
|
92
|
+
*/
|
|
93
|
+
export function makeSectionEditUpdate(base, appended) {
|
|
94
|
+
return crdt_make_incremental_update(base, appended);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Merge incremental section updates onto a base snapshot by sequential
|
|
98
|
+
* `crdt_apply_update`. This is the production merge composition: Loro import
|
|
99
|
+
* is idempotent and convergent, so the result carries every applied edit and
|
|
100
|
+
* is independent of update order. Do NOT replace this with
|
|
101
|
+
* `crdt_merge_updates` — that WASM export is lossy in llmtxt@2026.5.15
|
|
102
|
+
* (T13353 spike, T13356, kryptobaseddev/llmtxt#17).
|
|
103
|
+
*
|
|
104
|
+
* @param base - The base section snapshot.
|
|
105
|
+
* @param updates - Peer incremental updates, in any order.
|
|
106
|
+
* @returns The merged section snapshot.
|
|
107
|
+
*/
|
|
108
|
+
export function mergeSectionUpdates(base, updates) {
|
|
109
|
+
let state = base;
|
|
110
|
+
for (const update of updates) {
|
|
111
|
+
state = crdt_apply_update(state, update);
|
|
112
|
+
}
|
|
113
|
+
return state;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Extract the plain text of a section snapshot.
|
|
117
|
+
*
|
|
118
|
+
* @param state - A Loro snapshot from {@link seedSectionState} or {@link mergeSectionUpdates}.
|
|
119
|
+
* @returns The section's current text.
|
|
120
|
+
*/
|
|
121
|
+
export function sectionStateText(state) {
|
|
122
|
+
return crdt_get_text(state);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Apply one section's new text to its stored snapshot.
|
|
126
|
+
*
|
|
127
|
+
* `baseText` is the section text the incoming edit was AUTHORED AGAINST —
|
|
128
|
+
* the caller's concurrency reference (T13674). A base-less write passes the
|
|
129
|
+
* previous head's section text (single-writer assumption: the writer read
|
|
130
|
+
* the head and edited it). A write carrying a declared base passes the base
|
|
131
|
+
* version's section text, so a writer whose fetch predates a concurrent
|
|
132
|
+
* landing is recognized as stale instead of being mistaken for a
|
|
133
|
+
* single writer replacing the head.
|
|
134
|
+
*
|
|
135
|
+
* While the stored state equals the base text it holds no unlanded edit
|
|
136
|
+
* relative to what the writer saw, and any difference the writer authored
|
|
137
|
+
* is an ordinary edit — which the append-shaped primitives cannot express,
|
|
138
|
+
* so the section is re-seeded from the input and projects EXACTLY
|
|
139
|
+
* (mid-text replaces and deletions apply verbatim, never a fabricated
|
|
140
|
+
* concatenation — T13589). When the stored state differs from the base
|
|
141
|
+
* text, another writer's edit landed after the caller's fetch (T13674):
|
|
142
|
+
*
|
|
143
|
+
* - an incoming edit that is a pure APPEND relative to the common base
|
|
144
|
+
* (`nextText` extends `baseText`) composes onto the stored state, so
|
|
145
|
+
* both tails survive — this is never a fabrication;
|
|
146
|
+
* - any NON-append incoming edit (a replace or delete relative to the
|
|
147
|
+
* base) CANNOT be expressed with append-only primitives without
|
|
148
|
+
* inventing text, so the function reports `conflicted: true` and keeps
|
|
149
|
+
* the stored state untouched. The write path lands the incoming edit as
|
|
150
|
+
* its own append-only version row, keeps the stored projection as the
|
|
151
|
+
* head, and records the conflict on the head — both versions preserved,
|
|
152
|
+
* nothing fabricated.
|
|
153
|
+
*
|
|
154
|
+
* Semantics:
|
|
155
|
+
*
|
|
156
|
+
* - `stored === null` (first write of the section): seed a fresh state
|
|
157
|
+
* from the new text.
|
|
158
|
+
* - The stored text equals the new text: no-op (`changed: false`).
|
|
159
|
+
* - `baseText === null` (no base text available for this section — no
|
|
160
|
+
* head/base yet, or the reference version's blob is not resolvable
|
|
161
|
+
* locally): the single-writer assumption; re-seed from the new text
|
|
162
|
+
* (exact).
|
|
163
|
+
* - The stored text equals `baseText` (single writer against the
|
|
164
|
+
* reference): re-seed from the new text — the input projects exactly,
|
|
165
|
+
* deletions included.
|
|
166
|
+
* - The stored text differs from `baseText` and the incoming text equals
|
|
167
|
+
* `baseText`: the writer authored nothing new; no-op.
|
|
168
|
+
* - The stored text differs from `baseText` and the incoming text
|
|
169
|
+
* extends `baseText` (append): compose the incoming tail onto the
|
|
170
|
+
* stored state; both edits survive, `conflicted: false`.
|
|
171
|
+
* - The stored text differs from `baseText` and the incoming edit is a
|
|
172
|
+
* non-append relative to `baseText`: `conflicted: true`, stored state
|
|
173
|
+
* kept — the write path records the conflict and lands both versions.
|
|
174
|
+
*
|
|
175
|
+
* @param stored - The section's stored snapshot, or `null` when none exists.
|
|
176
|
+
* @param nextText - The section's new full text.
|
|
177
|
+
* @param baseText - The section's text in the version the incoming edit was
|
|
178
|
+
* authored against (previous head for base-less writes, declared base
|
|
179
|
+
* otherwise), or `null` when no reference text is available.
|
|
180
|
+
* @returns The resulting snapshot, whether it changed, and whether the edit
|
|
181
|
+
* is a non-append concurrent edit the caller must record as a conflict.
|
|
182
|
+
* @task T13674 (the baseText reference; T13589/T13595 for the merge shapes)
|
|
183
|
+
*/
|
|
184
|
+
export function applySectionTextEdit(stored, nextText, baseText) {
|
|
185
|
+
if (stored === null) {
|
|
186
|
+
return { snapshot: seedSectionState(nextText), changed: true, conflicted: false };
|
|
187
|
+
}
|
|
188
|
+
const current = sectionStateText(stored);
|
|
189
|
+
if (current === nextText) {
|
|
190
|
+
return { snapshot: stored, changed: false, conflicted: false };
|
|
191
|
+
}
|
|
192
|
+
if (baseText === null || current === baseText) {
|
|
193
|
+
// Single-writer edit: project the input EXACTLY. The primitives can only
|
|
194
|
+
// append, so a re-seed is the honest encoding of a replace/delete — it
|
|
195
|
+
// never fabricates a concatenation no writer authored (T13589).
|
|
196
|
+
return { snapshot: seedSectionState(nextText), changed: true, conflicted: false };
|
|
197
|
+
}
|
|
198
|
+
if (nextText === baseText) {
|
|
199
|
+
// The writer authored nothing beyond the base; the stored (concurrent)
|
|
200
|
+
// edit stands.
|
|
201
|
+
return { snapshot: stored, changed: false, conflicted: false };
|
|
202
|
+
}
|
|
203
|
+
if (nextText.startsWith(baseText)) {
|
|
204
|
+
// Concurrent append-append: compose the incoming tail onto the stored
|
|
205
|
+
// state. Both tails survive and nothing is fabricated (T13585).
|
|
206
|
+
const update = makeSectionEditUpdate(stored, nextText.slice(baseText.length));
|
|
207
|
+
return { snapshot: mergeSectionUpdates(stored, [update]), changed: true, conflicted: false };
|
|
208
|
+
}
|
|
209
|
+
// Non-append concurrent edit (replace/delete relative to the base): not
|
|
210
|
+
// expressible with append-only primitives without inventing text — keep
|
|
211
|
+
// the stored state and let the write path record the conflict, landing
|
|
212
|
+
// the incoming edit as its own version row (T13595).
|
|
213
|
+
return { snapshot: stored, changed: false, conflicted: true };
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=section-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section-merge.js","sourceRoot":"","sources":["../../src/docs/section-merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docs update write path through the section CRDT merge layer (T13355 ·
|
|
3
|
+
* spec `cleodocs-rearch-design` §2 option b · D11165).
|
|
4
|
+
*
|
|
5
|
+
* Every `cleo docs update` carrying new inline text is projected through
|
|
6
|
+
* this module after the legacy whole-row write lands (`docs-update.ts`):
|
|
7
|
+
*
|
|
8
|
+
* 1. Resolve the doc's immutable uid, adopting a legacy doc into the
|
|
9
|
+
* conduit family on first sight ({@link ensureConduitDoc}).
|
|
10
|
+
* 2. Split the new text into sections and resolve the previous head's
|
|
11
|
+
* section texts from its version blob — the single-writer vs.
|
|
12
|
+
* concurrent discriminator (T13589).
|
|
13
|
+
* 3. Apply each section's edit to its local Loro state
|
|
14
|
+
* (`section-merge.ts`): while the stored state equals the head's text
|
|
15
|
+
* the input projects EXACTLY (re-seed; replaces and deletions apply
|
|
16
|
+
* verbatim — the primitives can only append, so re-seeding is the
|
|
17
|
+
* honest encoding); a concurrent edit that is a pure append composes
|
|
18
|
+
* onto the stored state so both survive (T13585); a concurrent
|
|
19
|
+
* NON-append edit is never fabricated into a merge — it is landed as
|
|
20
|
+
* its own version row and recorded as a head conflict (T13595).
|
|
21
|
+
* 4. Read the MERGED text back out of the merged Loro states — never out
|
|
22
|
+
* of the input — and write its content-addressed blob so the version
|
|
23
|
+
* row's `storage_key` resolves.
|
|
24
|
+
* 5. Append the merged text as a DAG version row
|
|
25
|
+
* (`appendConduitAttachmentVersion`, parent = the previous head's
|
|
26
|
+
* version) — history is append-only.
|
|
27
|
+
* 6. Project the merged text into the current-version row via
|
|
28
|
+
* {@link upsertConduitDocHead}: the max-HLC head wins and a losing
|
|
29
|
+
* concurrent head is recorded as a conflict, never silently shadowed
|
|
30
|
+
* (typed rule `docs.head.max-hlc`).
|
|
31
|
+
* 7. Rebase the local section states onto the landed version and rebuild
|
|
32
|
+
* the derived contributors rollup.
|
|
33
|
+
*
|
|
34
|
+
* Steps 1–7 run inside ONE `BEGIN IMMEDIATE` transaction
|
|
35
|
+
* ({@link withConduitDocWriteTransaction}, T13583): a failure after the
|
|
36
|
+
* version append rolls everything back, so the next update cannot fork
|
|
37
|
+
* onto a half-landed projection. The body uses only sync-driver accessors
|
|
38
|
+
* and sync `node:fs` calls, so no real I/O yield can admit another writer
|
|
39
|
+
* on the connection mid-transaction (the documented constraint).
|
|
40
|
+
*
|
|
41
|
+
* Loro owns LOCAL-ONLY section state; the syncing rows are owned by the
|
|
42
|
+
* Stage C journal merge engine — one merge authority per table (§2).
|
|
43
|
+
*
|
|
44
|
+
* @module
|
|
45
|
+
* @task T13355
|
|
46
|
+
* @epic T13340
|
|
47
|
+
* @saga T13339
|
|
48
|
+
*/
|
|
49
|
+
import { type ConduitAttachmentVersionRow, type UpsertConduitDocHeadResult } from '../store/conduit-doc-history.js';
|
|
50
|
+
/**
|
|
51
|
+
* TTL granted by the write path's lease acquisitions (seconds). Inside
|
|
52
|
+
* llmtxt's 1–300 s range; long enough to cover an edit burst, short enough
|
|
53
|
+
* that a dead session's lease dies quickly (AC4: lease state never outlives
|
|
54
|
+
* its session without renew).
|
|
55
|
+
*/
|
|
56
|
+
export declare const SECTION_LEASE_TTL_SECONDS = 60;
|
|
57
|
+
/** Input for {@link projectDocUpdateThroughSections}. */
|
|
58
|
+
export interface ProjectDocUpdateInput {
|
|
59
|
+
/** The doc's live slug (or a known old slug). */
|
|
60
|
+
readonly slug: string;
|
|
61
|
+
/** Revision author agent id. */
|
|
62
|
+
readonly authorAgentId: string;
|
|
63
|
+
/** The full new document text. */
|
|
64
|
+
readonly content: string;
|
|
65
|
+
/**
|
|
66
|
+
* The session performing the edit. Callers that know their session (tests,
|
|
67
|
+
* sync apply) pass it explicitly; otherwise the projection resolves the
|
|
68
|
+
* caller's BOUND session ({@link resolveBoundSession}, gate 16 — never a
|
|
69
|
+
* bare `getActiveSession()`). With no session the edit proceeds
|
|
70
|
+
* UNCOORDINATED: leases are per-session state, so there is nothing to
|
|
71
|
+
* acquire or renew under.
|
|
72
|
+
*/
|
|
73
|
+
readonly sessionId?: string;
|
|
74
|
+
/**
|
|
75
|
+
* The candidate head's HLC (journal wire form). Omit to mint one locally:
|
|
76
|
+
* the mint ticks forward from this device's last issued HLC and never
|
|
77
|
+
* lands at or below the stored head, so a local write always advances the
|
|
78
|
+
* projection. Sync callers pass the remote HLC to exercise the max-HLC
|
|
79
|
+
* rule.
|
|
80
|
+
*/
|
|
81
|
+
readonly hlc?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Explicit DAG parent (sync apply). Omit to chain onto the current head's
|
|
84
|
+
* version; `null` forces a root version.
|
|
85
|
+
*/
|
|
86
|
+
readonly parentVersionUid?: string | null;
|
|
87
|
+
/**
|
|
88
|
+
* The section texts of the version this edit was AUTHORED AGAINST
|
|
89
|
+
* (T13674) — the write path's stale-base discriminator. Callers that
|
|
90
|
+
* fetched a head and declared it pass its section texts (resolved and
|
|
91
|
+
* validated before any write); every section is then merged relative to
|
|
92
|
+
* that base, so an edit authored against a superseded head composes onto
|
|
93
|
+
* the stored state (append) or records a conflict (non-append) instead of
|
|
94
|
+
* re-seeding over a concurrent writer's edit. Omit (or null) to assert
|
|
95
|
+
* single-writer semantics against the previous head — the pre-T13674
|
|
96
|
+
* behavior.
|
|
97
|
+
*/
|
|
98
|
+
readonly baseSections?: readonly string[] | null;
|
|
99
|
+
/** Optional change summary for the version row. */
|
|
100
|
+
readonly changeSummary?: string;
|
|
101
|
+
}
|
|
102
|
+
/** Outcome of {@link projectDocUpdateThroughSections}. */
|
|
103
|
+
export interface ProjectDocUpdateResult {
|
|
104
|
+
/** The doc's immutable uid (`conduit_attachments.uid`). */
|
|
105
|
+
readonly docUid: string;
|
|
106
|
+
/** Whether this call adopted the doc into the conduit family. */
|
|
107
|
+
readonly adopted: boolean;
|
|
108
|
+
/** The merged document text, extracted from the merged Loro states. */
|
|
109
|
+
readonly mergedText: string;
|
|
110
|
+
/** Section ids whose state changed in this projection. */
|
|
111
|
+
readonly sectionsModified: readonly string[];
|
|
112
|
+
/** The appended DAG version row. */
|
|
113
|
+
readonly version: ConduitAttachmentVersionRow;
|
|
114
|
+
/** The head upsert outcome (advanced vs. conflict recorded). */
|
|
115
|
+
readonly head: UpsertConduitDocHeadResult;
|
|
116
|
+
/**
|
|
117
|
+
* The head version uid this projection chained onto (`null` when the doc
|
|
118
|
+
* had no head yet). Callers that declared a base compare it against their
|
|
119
|
+
* base to detect a stale merge (T13674).
|
|
120
|
+
*/
|
|
121
|
+
readonly previousHeadVersionUid: string | null;
|
|
122
|
+
/**
|
|
123
|
+
* Non-append concurrent section edits recorded as conflicts (T13595): the
|
|
124
|
+
* incoming edit could not be composed without fabricating text, so it was
|
|
125
|
+
* landed as its own version row (append-only history preserves both) while
|
|
126
|
+
* the head keeps the stored projection.
|
|
127
|
+
*/
|
|
128
|
+
readonly conflicts: readonly SectionConflict[];
|
|
129
|
+
/**
|
|
130
|
+
* Advisory lease notices (T13356): sections this edit touched are leased
|
|
131
|
+
* by ANOTHER live session. The edit proceeded anyway — leases are
|
|
132
|
+
* advisory ("409 is a social signal, not a hard lock", llmtxt T285).
|
|
133
|
+
*/
|
|
134
|
+
readonly leaseNotices: readonly SectionLeaseNotice[];
|
|
135
|
+
}
|
|
136
|
+
/** One recorded non-append concurrent section edit (T13595). */
|
|
137
|
+
export interface SectionConflict {
|
|
138
|
+
/** The section that could not be merged. */
|
|
139
|
+
readonly sectionId: string;
|
|
140
|
+
/** The version row carrying the incoming (authored) edit — the loser. */
|
|
141
|
+
readonly incomingVersionUid: string;
|
|
142
|
+
/** The projection version row the head kept — the winner. */
|
|
143
|
+
readonly projectionVersionUid: string;
|
|
144
|
+
}
|
|
145
|
+
/** One advisory lease notice (T13356): the section is leased elsewhere. */
|
|
146
|
+
export interface SectionLeaseNotice {
|
|
147
|
+
/** The leased section the edit touched. */
|
|
148
|
+
readonly sectionId: string;
|
|
149
|
+
/** The current holder agent id. */
|
|
150
|
+
readonly holder: string;
|
|
151
|
+
/** The current holder's session id. */
|
|
152
|
+
readonly sessionId: string;
|
|
153
|
+
/** When the blocking lease expires without renew (ISO-8601). */
|
|
154
|
+
readonly expiresAt: string;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Project one docs update through the section CRDT merge layer.
|
|
158
|
+
*
|
|
159
|
+
* The whole projection — adopt, section-state writes, version append, head
|
|
160
|
+
* upsert, rebase, contributors rebuild — is one transaction
|
|
161
|
+
* ({@link withConduitDocWriteTransaction}); the merged text is read back
|
|
162
|
+
* from the merged Loro states, so concurrent same-base section edits both
|
|
163
|
+
* survive into the version row and the head projection.
|
|
164
|
+
*
|
|
165
|
+
* Lease coordination (T13356, ADVISORY): before the transaction, the
|
|
166
|
+
* projection resolves the caller's session (input, else the bound session,
|
|
167
|
+
* gate 16) and acquires/renews a lease for every section the edit touches.
|
|
168
|
+
* A section leased by another live session yields a {@link SectionLeaseNotice}
|
|
169
|
+
* — the 409 equivalent as data. The edit PROCEEDS regardless: "409 is a
|
|
170
|
+
* social signal, not a hard lock" (llmtxt T285); the CRDT layer guarantees
|
|
171
|
+
* nothing is lost when coordination fails. Leases acquired for a projection
|
|
172
|
+
* that then rolls back are released, so a failed edit leaves no stale claim.
|
|
173
|
+
*
|
|
174
|
+
* @param projectRoot - Absolute path to the CLEO project root.
|
|
175
|
+
* @param input - The update facts.
|
|
176
|
+
* @returns The merge outcome.
|
|
177
|
+
*/
|
|
178
|
+
export declare function projectDocUpdateThroughSections(projectRoot: string, input: ProjectDocUpdateInput): Promise<ProjectDocUpdateResult>;
|
|
179
|
+
/**
|
|
180
|
+
* Release every section lease this session holds for a doc — the "release
|
|
181
|
+
* on completion" path of T13356 AC2: a session calls this when it finishes
|
|
182
|
+
* editing the doc, so the sections are free for the next editor before the
|
|
183
|
+
* TTL would have expired them.
|
|
184
|
+
*
|
|
185
|
+
* @param projectRoot - Absolute path to the CLEO project root.
|
|
186
|
+
* @param slug - The doc's live slug (leases are keyed by it).
|
|
187
|
+
* @param sessionId - The finishing session (only its own leases are released).
|
|
188
|
+
* @returns The section ids released.
|
|
189
|
+
*/
|
|
190
|
+
export declare function releaseSectionLeases(projectRoot: string, slug: string, sessionId: string): Promise<string[]>;
|
|
191
|
+
//# sourceMappingURL=section-write-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section-write-path.d.ts","sourceRoot":"","sources":["../../src/docs/section-write-path.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAMH,OAAO,EAEL,KAAK,2BAA2B,EAShC,KAAK,0BAA0B,EAIhC,MAAM,iCAAiC,CAAC;AAgBzC;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAE5C,yDAAyD;AACzD,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;OAMG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;IACjD,mDAAmD;IACnD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,uEAAuE;IACvE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C,gEAAgE;IAChE,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/C;;;;;OAKG;IACH,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACtD;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,6DAA6D;IAC7D,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;CACvC;AAED,2EAA2E;AAC3E,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AA2GD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,sBAAsB,CAAC,CAoOjC;AAYD;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAUnB"}
|