@mmnto/totem 1.122.0 → 1.124.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/dist/artifacts/legs.d.ts +430 -0
- package/dist/artifacts/legs.d.ts.map +1 -0
- package/dist/artifacts/legs.js +577 -0
- package/dist/artifacts/legs.js.map +1 -0
- package/dist/artifacts/legs.test.d.ts +19 -0
- package/dist/artifacts/legs.test.d.ts.map +1 -0
- package/dist/artifacts/legs.test.js +628 -0
- package/dist/artifacts/legs.test.js.map +1 -0
- package/dist/config-schema.d.ts +35 -0
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config-schema.js +28 -0
- package/dist/config-schema.js.map +1 -1
- package/dist/config-schema.test.js +73 -0
- package/dist/config-schema.test.js.map +1 -1
- package/dist/errors.d.ts +3 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/routing/legs-owed.d.ts +65 -0
- package/dist/routing/legs-owed.d.ts.map +1 -0
- package/dist/routing/legs-owed.js +72 -0
- package/dist/routing/legs-owed.js.map +1 -0
- package/dist/routing/legs-owed.test.d.ts +10 -0
- package/dist/routing/legs-owed.test.d.ts.map +1 -0
- package/dist/routing/legs-owed.test.js +119 -0
- package/dist/routing/legs-owed.test.js.map +1 -0
- package/dist/semantic-dedup.d.ts.map +1 -1
- package/dist/semantic-dedup.js +2 -5
- package/dist/semantic-dedup.js.map +1 -1
- package/dist/semantic-dedup.test.js +32 -1
- package/dist/semantic-dedup.test.js.map +1 -1
- package/dist/store/lance-store.test.js +23 -0
- package/dist/store/lance-store.test.js.map +1 -1
- package/dist/store/search-lessons.d.ts +18 -0
- package/dist/store/search-lessons.d.ts.map +1 -0
- package/dist/store/search-lessons.js +18 -0
- package/dist/store/search-lessons.js.map +1 -0
- package/dist/store/search-lessons.test.d.ts +2 -0
- package/dist/store/search-lessons.test.d.ts.map +1 -0
- package/dist/store/search-lessons.test.js +48 -0
- package/dist/store/search-lessons.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Leg-deposit contract — the machine-readable record a falsification leg
|
|
3
|
+
* leaves behind after it READ a diff (mmnto-ai/totem#2698, ruled 2026-09-03).
|
|
4
|
+
*
|
|
5
|
+
* The gate's question is deliberately narrow: *was THIS head read by a leg?*
|
|
6
|
+
* So the store is keyed by the READ sha — `<totemDir>/artifacts/legs/<diffSha>.json`
|
|
7
|
+
* — and NOT content-addressed like the verdict/admission/run families. Two
|
|
8
|
+
* legs that read the same head are the same answer to that question; a rerun
|
|
9
|
+
* on the same head supersedes by INTENT, which is why the writer is
|
|
10
|
+
* create-exclusive and a `replace` discloses the `readAt` it overwrote rather
|
|
11
|
+
* than silently deduping (the content-addressed stores' EEXIST-is-dedup rule
|
|
12
|
+
* would be a lie here — the second read is a different observation).
|
|
13
|
+
*
|
|
14
|
+
* Store mechanics still mirror the sibling families where the semantics agree:
|
|
15
|
+
* validate-on-write so a writer bug never poisons the store, a
|
|
16
|
+
* tolerant-within-major reader whose newer-major refusal is NAMED (an older
|
|
17
|
+
* CLI meeting a newer deposit reports "upgrade", never "corrupt"), unknown
|
|
18
|
+
* keys tolerated (forward-minor additive fields), and `0o600` bytes.
|
|
19
|
+
*
|
|
20
|
+
* Two properties are specific to this family:
|
|
21
|
+
*
|
|
22
|
+
* 1. **The loader never throws.** A deposit is a hand-editable JSON file that
|
|
23
|
+
* a pre-push hook reads on every push; one bad file must never take the
|
|
24
|
+
* gate down or hide a valid sibling. Every per-file failure — unreadable,
|
|
25
|
+
* non-JSON, schema-invalid, wrong major, or a filename that disagrees with
|
|
26
|
+
* the stored `diffSha` — becomes a one-line `corrupt` row the caller
|
|
27
|
+
* prints (Tenet 4: loud, never silent).
|
|
28
|
+
* 2. **Every stored string that reaches stdout is control-byte free at the
|
|
29
|
+
* SCHEMA boundary**, at write and at read alike. `verdict`, `claim`,
|
|
30
|
+
* `counterexample` and `file` land inside a hook's `[Totem] …` line; a
|
|
31
|
+
* newline in any of them would forge a second line, so the schema refuses
|
|
32
|
+
* C0 (0-31) and DEL/C1 (127-159) outright. "Single-line" needs no separate
|
|
33
|
+
* rule: LF and CR are inside that band.
|
|
34
|
+
*
|
|
35
|
+
* Core never shells out. Ancestry is supplied by the CLI through the injected
|
|
36
|
+
* {@link LegGitAdapter}, so every resolution rule here is unit-testable
|
|
37
|
+
* without a git fixture.
|
|
38
|
+
*/
|
|
39
|
+
import { z } from 'zod';
|
|
40
|
+
import { TotemError } from '../errors.js';
|
|
41
|
+
/** The leg-deposit schemaVersion WRITTEN by this code. Readers accept any 1.x. */
|
|
42
|
+
export declare const LEG_DEPOSIT_SCHEMA_VERSION = "1.0.0";
|
|
43
|
+
/** The major this reader understands; another major needs a migration entry. */
|
|
44
|
+
export declare const LEG_DEPOSIT_KNOWN_MAJOR = 1;
|
|
45
|
+
/**
|
|
46
|
+
* The leg's severity vocabulary. Deliberately NOT the verdict family's
|
|
47
|
+
* CRITICAL/WARN/INFO: a leg deposit answers "what did the leg find", and the
|
|
48
|
+
* doctrine spelling for that is BLOCKING (the fold must land) / MATERIAL (the
|
|
49
|
+
* seat rules) / MINOR (disclosed). Order here is documentation order; the
|
|
50
|
+
* value is data. One spelling — {@link LegFindingSeveritySchema} is built
|
|
51
|
+
* from this array, never a second literal list.
|
|
52
|
+
*/
|
|
53
|
+
export declare const LEG_FINDING_SEVERITIES: readonly ["BLOCKING", "MATERIAL", "MINOR"];
|
|
54
|
+
export type LegFindingSeverity = (typeof LEG_FINDING_SEVERITIES)[number];
|
|
55
|
+
export declare const LegFindingSeveritySchema: z.ZodEnum<["BLOCKING", "MATERIAL", "MINOR"]>;
|
|
56
|
+
/** The finding id — required, so `folded` can NAME a finding rather than index it. */
|
|
57
|
+
export declare const LegFindingIdSchema: z.ZodString;
|
|
58
|
+
/**
|
|
59
|
+
* One typed finding. `id` is required (mmnto-ai/totem#2698 OQ1, ruled): the
|
|
60
|
+
* contract JSON had none, and without one `folded` cannot reference a finding
|
|
61
|
+
* — positional indexes are fragile under reordering, and a bare count cannot
|
|
62
|
+
* be checked against anything.
|
|
63
|
+
*/
|
|
64
|
+
export declare const LegFindingSchema: z.ZodObject<{
|
|
65
|
+
/** Unique within the deposit; the referent of every `folded` entry. */
|
|
66
|
+
id: z.ZodString;
|
|
67
|
+
severity: z.ZodEnum<["BLOCKING", "MATERIAL", "MINOR"]>;
|
|
68
|
+
/** Repo-relative path the finding is about (free-form: core never resolves it). */
|
|
69
|
+
file: z.ZodEffects<z.ZodString, string, string>;
|
|
70
|
+
/** 0 means "the file, no particular line" — never a sentinel like -1. */
|
|
71
|
+
line: z.ZodNumber;
|
|
72
|
+
/** The falsifiable claim, one line. */
|
|
73
|
+
claim: z.ZodEffects<z.ZodString, string, string>;
|
|
74
|
+
/** The evidence. MAY be empty — a claim with no counterexample is still disclosed. */
|
|
75
|
+
counterexample: z.ZodEffects<z.ZodString, string, string>;
|
|
76
|
+
}, "strip", z.ZodTypeAny, {
|
|
77
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
78
|
+
line: number;
|
|
79
|
+
file: string;
|
|
80
|
+
id: string;
|
|
81
|
+
claim: string;
|
|
82
|
+
counterexample: string;
|
|
83
|
+
}, {
|
|
84
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
85
|
+
line: number;
|
|
86
|
+
file: string;
|
|
87
|
+
id: string;
|
|
88
|
+
claim: string;
|
|
89
|
+
counterexample: string;
|
|
90
|
+
}>;
|
|
91
|
+
export type LegFinding = z.infer<typeof LegFindingSchema>;
|
|
92
|
+
/**
|
|
93
|
+
* The deposit itself. Every field is required; the arrays may be empty (a leg
|
|
94
|
+
* that found nothing still deposits — that IS the evidence the gate wants).
|
|
95
|
+
*
|
|
96
|
+
* Unknown keys are TOLERATED, not refused (the run-artifact precedent): a
|
|
97
|
+
* forward-minor writer may add a field this reader strips, and a deposit is
|
|
98
|
+
* evidence a newer leg wrote, not a contract this reader gets to narrow.
|
|
99
|
+
*/
|
|
100
|
+
export declare const LegDepositSchema: z.ZodEffects<z.ZodObject<{
|
|
101
|
+
/** Writer version; readers tolerate any 1.x, refuse another major by name. */
|
|
102
|
+
schemaVersion: z.ZodString;
|
|
103
|
+
/** The head the leg READ — a full 40-hex commit, and the file's own name. */
|
|
104
|
+
diffSha: z.ZodString;
|
|
105
|
+
/** The leg's own instant, ISO-8601. Ties are broken on it, so it is contract. */
|
|
106
|
+
readAt: z.ZodString;
|
|
107
|
+
findings: z.ZodArray<z.ZodObject<{
|
|
108
|
+
/** Unique within the deposit; the referent of every `folded` entry. */
|
|
109
|
+
id: z.ZodString;
|
|
110
|
+
severity: z.ZodEnum<["BLOCKING", "MATERIAL", "MINOR"]>;
|
|
111
|
+
/** Repo-relative path the finding is about (free-form: core never resolves it). */
|
|
112
|
+
file: z.ZodEffects<z.ZodString, string, string>;
|
|
113
|
+
/** 0 means "the file, no particular line" — never a sentinel like -1. */
|
|
114
|
+
line: z.ZodNumber;
|
|
115
|
+
/** The falsifiable claim, one line. */
|
|
116
|
+
claim: z.ZodEffects<z.ZodString, string, string>;
|
|
117
|
+
/** The evidence. MAY be empty — a claim with no counterexample is still disclosed. */
|
|
118
|
+
counterexample: z.ZodEffects<z.ZodString, string, string>;
|
|
119
|
+
}, "strip", z.ZodTypeAny, {
|
|
120
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
121
|
+
line: number;
|
|
122
|
+
file: string;
|
|
123
|
+
id: string;
|
|
124
|
+
claim: string;
|
|
125
|
+
counterexample: string;
|
|
126
|
+
}, {
|
|
127
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
128
|
+
line: number;
|
|
129
|
+
file: string;
|
|
130
|
+
id: string;
|
|
131
|
+
claim: string;
|
|
132
|
+
counterexample: string;
|
|
133
|
+
}>, "many">;
|
|
134
|
+
/** Ids of findings the seat FOLDED — a subset of `findings[].id` (superRefine). */
|
|
135
|
+
folded: z.ZodArray<z.ZodString, "many">;
|
|
136
|
+
/** The leg's one-line disposition; echoed verbatim on the gate's evidence line. */
|
|
137
|
+
verdict: z.ZodEffects<z.ZodString, string, string>;
|
|
138
|
+
}, "strip", z.ZodTypeAny, {
|
|
139
|
+
schemaVersion: string;
|
|
140
|
+
findings: {
|
|
141
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
142
|
+
line: number;
|
|
143
|
+
file: string;
|
|
144
|
+
id: string;
|
|
145
|
+
claim: string;
|
|
146
|
+
counterexample: string;
|
|
147
|
+
}[];
|
|
148
|
+
verdict: string;
|
|
149
|
+
diffSha: string;
|
|
150
|
+
readAt: string;
|
|
151
|
+
folded: string[];
|
|
152
|
+
}, {
|
|
153
|
+
schemaVersion: string;
|
|
154
|
+
findings: {
|
|
155
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
156
|
+
line: number;
|
|
157
|
+
file: string;
|
|
158
|
+
id: string;
|
|
159
|
+
claim: string;
|
|
160
|
+
counterexample: string;
|
|
161
|
+
}[];
|
|
162
|
+
verdict: string;
|
|
163
|
+
diffSha: string;
|
|
164
|
+
readAt: string;
|
|
165
|
+
folded: string[];
|
|
166
|
+
}>, {
|
|
167
|
+
schemaVersion: string;
|
|
168
|
+
findings: {
|
|
169
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
170
|
+
line: number;
|
|
171
|
+
file: string;
|
|
172
|
+
id: string;
|
|
173
|
+
claim: string;
|
|
174
|
+
counterexample: string;
|
|
175
|
+
}[];
|
|
176
|
+
verdict: string;
|
|
177
|
+
diffSha: string;
|
|
178
|
+
readAt: string;
|
|
179
|
+
folded: string[];
|
|
180
|
+
}, {
|
|
181
|
+
schemaVersion: string;
|
|
182
|
+
findings: {
|
|
183
|
+
severity: "BLOCKING" | "MATERIAL" | "MINOR";
|
|
184
|
+
line: number;
|
|
185
|
+
file: string;
|
|
186
|
+
id: string;
|
|
187
|
+
claim: string;
|
|
188
|
+
counterexample: string;
|
|
189
|
+
}[];
|
|
190
|
+
verdict: string;
|
|
191
|
+
diffSha: string;
|
|
192
|
+
readAt: string;
|
|
193
|
+
folded: string[];
|
|
194
|
+
}>;
|
|
195
|
+
export type LegDeposit = z.infer<typeof LegDepositSchema>;
|
|
196
|
+
/** A loaded deposit paired with the address it was found at (the filename stem). */
|
|
197
|
+
export interface LegDepositWithAddress {
|
|
198
|
+
deposit: LegDeposit;
|
|
199
|
+
/** Absolute path of the stored deposit. */
|
|
200
|
+
path: string;
|
|
201
|
+
/** The verified address = the filename stem = `deposit.diffSha`. */
|
|
202
|
+
diffSha: string;
|
|
203
|
+
}
|
|
204
|
+
/** Absolute legs directory for a given absolute totem dir. */
|
|
205
|
+
export declare function legsDir(totemDirAbs: string): string;
|
|
206
|
+
/** Absolute path of the deposit for `diffSha` — the sha IS the filename stem. */
|
|
207
|
+
export declare function legDepositPath(totemDirAbs: string, diffSha: string): string;
|
|
208
|
+
/**
|
|
209
|
+
* Refusal to overwrite an existing deposit without `replace`. Typed so the
|
|
210
|
+
* CLI can print the incumbent's `readAt` and the one-flag cure rather than
|
|
211
|
+
* re-deriving either. `existingReadAt` is `undefined` when the incumbent
|
|
212
|
+
* itself is unreadable/corrupt — the refusal still stands (the seat decides
|
|
213
|
+
* whether to replace it), and the honest report is that its instant could not
|
|
214
|
+
* be read.
|
|
215
|
+
*/
|
|
216
|
+
export declare class LegDepositExistsError extends TotemError {
|
|
217
|
+
readonly diffSha: string;
|
|
218
|
+
readonly existingReadAt: string | undefined;
|
|
219
|
+
readonly depositPath: string;
|
|
220
|
+
constructor(diffSha: string, existingReadAt: string | undefined, depositPath: string);
|
|
221
|
+
}
|
|
222
|
+
export interface SaveLegDepositOptions {
|
|
223
|
+
/** Overwrite an existing deposit for this sha, reporting the `readAt` replaced. */
|
|
224
|
+
replace?: boolean;
|
|
225
|
+
}
|
|
226
|
+
export interface SaveLegDepositResult {
|
|
227
|
+
/** Absolute path of the stored deposit. */
|
|
228
|
+
path: string;
|
|
229
|
+
/**
|
|
230
|
+
* Present IFF an existing deposit was overwritten. `readAt` is the
|
|
231
|
+
* incumbent's instant, or `undefined` when the incumbent was corrupt enough
|
|
232
|
+
* that its instant could not be read.
|
|
233
|
+
*/
|
|
234
|
+
replaced?: {
|
|
235
|
+
readAt: string | undefined;
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Persist a deposit at `<legsDir>/<diffSha>.json`, create-exclusive by default.
|
|
240
|
+
*
|
|
241
|
+
* Ordering is contract: the deposit is VALIDATED before the filesystem is
|
|
242
|
+
* touched at all, and the occupancy check precedes the write — so a refused
|
|
243
|
+
* write (schema-invalid, or occupied without `replace`) leaves no file and no
|
|
244
|
+
* temp behind. The bytes go through the shared atomic helper (temp in the same
|
|
245
|
+
* directory, fsync), so a reader never observes a torn deposit.
|
|
246
|
+
*
|
|
247
|
+
* The PUBLISH is exclusive, not merely checked (Greptile P1 on PR
|
|
248
|
+
* mmnto-ai/totem#2745). `existsSync` then rename is check-then-act: two
|
|
249
|
+
* no-replace writers for one sha both see "absent" and the later rename wins
|
|
250
|
+
* silently, overwriting one leg's read with another's. Without `replace` the
|
|
251
|
+
* final name is therefore created by `fs.linkSync`, which is atomic and fails
|
|
252
|
+
* `EEXIST` if the name is taken — the loser refuses exactly as the pre-check
|
|
253
|
+
* does, and the incumbent's bytes are never touched. `replace: true` keeps the
|
|
254
|
+
* rename path, because overwriting is what it asks for.
|
|
255
|
+
*
|
|
256
|
+
* The file's name is DERIVED from `deposit.diffSha`, which is how the store's
|
|
257
|
+
* "the name is the read sha" invariant holds by construction; the loader
|
|
258
|
+
* re-checks it on the way back in, since the name comes off a filesystem a
|
|
259
|
+
* human can rename.
|
|
260
|
+
*/
|
|
261
|
+
export declare function saveLegDeposit(totemDirAbs: string, deposit: LegDeposit, options?: SaveLegDepositOptions): SaveLegDepositResult;
|
|
262
|
+
/** One disclosed unusable file: the name as it sits on disk, and why it is not a deposit. */
|
|
263
|
+
export interface LegDepositCorruptEntry {
|
|
264
|
+
/** The filename as read from the directory (not a path — the caller joins). */
|
|
265
|
+
file: string;
|
|
266
|
+
/** One line, control-byte free, safe to echo. */
|
|
267
|
+
reason: string;
|
|
268
|
+
}
|
|
269
|
+
export interface LoadLegDepositsResult {
|
|
270
|
+
deposits: LegDepositWithAddress[];
|
|
271
|
+
corrupt: LegDepositCorruptEntry[];
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Read every deposit in the store, TOLERANTLY.
|
|
275
|
+
*
|
|
276
|
+
* Never throws: a missing directory is an empty store, a non-`.json` entry is
|
|
277
|
+
* not a deposit at all (ignored silently — the directory is not the store's
|
|
278
|
+
* inventory), and every other per-file failure is a `corrupt` row carrying a
|
|
279
|
+
* one-line reason. The reading is JSON-AWARE through the schema, so a file
|
|
280
|
+
* that merely *mentions* `diffSha` or `findings` in some other shape — a
|
|
281
|
+
* review artifact copied in, say — is corrupt, never a deposit.
|
|
282
|
+
*
|
|
283
|
+
* The filename is re-checked against the stored `diffSha`: the name is the
|
|
284
|
+
* store's address, a human can rename a file, and a deposit resolved under
|
|
285
|
+
* someone else's sha would answer the gate's question about the wrong head.
|
|
286
|
+
*/
|
|
287
|
+
export declare function loadLegDeposits(totemDirAbs: string): LoadLegDepositsResult;
|
|
288
|
+
/**
|
|
289
|
+
* The git seam the resolver needs, INJECTED. Core never shells out — the CLI
|
|
290
|
+
* supplies an adapter over `git cat-file`/`merge-base --is-ancestor`/
|
|
291
|
+
* `rev-list --count`, and every rule below stays unit-testable with a fake.
|
|
292
|
+
*/
|
|
293
|
+
export interface LegGitAdapter {
|
|
294
|
+
/** Does this sha name a commit object in THIS repo? */
|
|
295
|
+
isCommit(sha: string): boolean;
|
|
296
|
+
/** Is `base` an ancestor of `head`? (Called only for shas `isCommit` accepted.) */
|
|
297
|
+
isAncestor(base: string, head: string): boolean;
|
|
298
|
+
/** Commits from `base` to `head` (`rev-list --count base..head`). */
|
|
299
|
+
distance(base: string, head: string): number;
|
|
300
|
+
/**
|
|
301
|
+
* Paths changed between `base` and `head` (`git diff --name-only base...head`,
|
|
302
|
+
* three-dot). This is what a leg reading at `head` COULD have seen, and it is
|
|
303
|
+
* the only input the coverage predicate needs. Called only for ancestor
|
|
304
|
+
* candidates, and only when a coverage query is supplied.
|
|
305
|
+
*/
|
|
306
|
+
changedFiles(base: string, head: string): readonly string[];
|
|
307
|
+
}
|
|
308
|
+
/** How a deposit reaches the head: it IS the head, or it is behind it. */
|
|
309
|
+
export type LegDepositRank = 'exact' | 'ancestor';
|
|
310
|
+
/** Why a deposit cannot answer for this head. */
|
|
311
|
+
export type LegDepositStaleReason = 'unknown-commit' | 'not-ancestor' | 'no-coverage';
|
|
312
|
+
/**
|
|
313
|
+
* How much of what this push OWES a leg the candidate could actually have read
|
|
314
|
+
* (mmnto-ai/totem#2698 fold 3, operator-ruled).
|
|
315
|
+
*
|
|
316
|
+
* Ancestry alone is not freshness. A deposit written against the branch's merge
|
|
317
|
+
* base satisfies ancestor-or-equal and reports a small `distance`, yet the leg
|
|
318
|
+
* that wrote it saw NONE of the diff the push proposes — the exhibit that
|
|
319
|
+
* produced this rule. Coverage is the second half of the question: of the owed
|
|
320
|
+
* paths, how many were inside the diff the candidate's own head contained?
|
|
321
|
+
*/
|
|
322
|
+
export interface LegDepositCoverage {
|
|
323
|
+
/** Owed paths the candidate's own branch diff contained. */
|
|
324
|
+
covered: number;
|
|
325
|
+
/** Owed paths in total — the deduplicated files in the basis. */
|
|
326
|
+
owed: number;
|
|
327
|
+
/** The owed paths the candidate could NOT have read, in basis order. */
|
|
328
|
+
missing: string[];
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* The inputs the coverage predicate needs, supplied by a caller that resolved a
|
|
332
|
+
* BRANCH scope. Omitted by callers that cannot (a staged or explicit-range
|
|
333
|
+
* scope has no branch base to measure a candidate's reach against), and the
|
|
334
|
+
* resolution then reports `coverage: undefined` so those callers disclose the
|
|
335
|
+
* limit rather than imply full coverage.
|
|
336
|
+
*/
|
|
337
|
+
export interface LegCoverageQuery {
|
|
338
|
+
/** The base ref the caller resolved for HEAD — the same one, or the measure lies. */
|
|
339
|
+
base: string;
|
|
340
|
+
/** The owed paths (the deduplicated files in the basis). */
|
|
341
|
+
owedFiles: readonly string[];
|
|
342
|
+
}
|
|
343
|
+
export interface LegDepositWinner extends LegDepositWithAddress {
|
|
344
|
+
rank: LegDepositRank;
|
|
345
|
+
/** Commits landed since the leg read: 0 for `exact`. */
|
|
346
|
+
distance: number;
|
|
347
|
+
/** Absent iff no coverage query was supplied. */
|
|
348
|
+
coverage?: LegDepositCoverage;
|
|
349
|
+
}
|
|
350
|
+
export interface LegDepositSuperseded {
|
|
351
|
+
diffSha: string;
|
|
352
|
+
readAt: string;
|
|
353
|
+
rank: LegDepositRank;
|
|
354
|
+
distance: number;
|
|
355
|
+
/** Absent iff no coverage query was supplied. */
|
|
356
|
+
coverage?: LegDepositCoverage;
|
|
357
|
+
}
|
|
358
|
+
export interface LegDepositStale {
|
|
359
|
+
diffSha: string;
|
|
360
|
+
readAt: string;
|
|
361
|
+
reason: LegDepositStaleReason;
|
|
362
|
+
}
|
|
363
|
+
export interface LegDepositResolution {
|
|
364
|
+
/** Absent when no deposit is ancestor-or-equal of the head. */
|
|
365
|
+
winner?: LegDepositWinner;
|
|
366
|
+
/** Valid candidates the winner outranked — disclosed, never silently dropped. */
|
|
367
|
+
superseded: LegDepositSuperseded[];
|
|
368
|
+
/** Deposits that name no commit here, that are not ancestors, or that cover nothing. */
|
|
369
|
+
stale: LegDepositStale[];
|
|
370
|
+
/** Files that are not deposits at all, with their reasons. */
|
|
371
|
+
corrupt: LegDepositCorruptEntry[];
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Resolve which deposit (if any) answers for `headSha`.
|
|
375
|
+
*
|
|
376
|
+
* A deposit read at X answers for every DESCENDANT of X — the contract's
|
|
377
|
+
* ancestor-or-equal rule — so the ranking is: `exact` first, then the NEAREST
|
|
378
|
+
* ancestor (fewest commits since the read), ties to the LATEST `readAt`. The
|
|
379
|
+
* winner carries its `distance` so the caller can print "+N commits since the
|
|
380
|
+
* leg read" rather than pass a stale read off as a fresh one.
|
|
381
|
+
*
|
|
382
|
+
* Since mmnto-ai/totem#2698 fold 3 ancestry is only HALF the question. When a
|
|
383
|
+
* `coverage` query is supplied, each ancestor candidate is also measured on
|
|
384
|
+
* what it could have READ — the branch diff up to its own head, intersected
|
|
385
|
+
* with the owed paths — and a candidate covering NONE of them is stale, not a
|
|
386
|
+
* winner: it satisfies ancestor-or-equal while its leg saw nothing this push
|
|
387
|
+
* proposes (the merge-base deposit that produced the ruling). An EXACT match
|
|
388
|
+
* covers everything by construction and costs no git call.
|
|
389
|
+
*
|
|
390
|
+
* Ranking is unchanged: along one lineage a nearer ancestor's diff is a
|
|
391
|
+
* superset of a farther one's, so nearest-first already orders by coverage.
|
|
392
|
+
*
|
|
393
|
+
* Nothing here decides POLICY beyond that floor: partial coverage still
|
|
394
|
+
* resolves, and a distance of 200 still resolves. Whether either is evidence
|
|
395
|
+
* enough is the gate's disclosure to make and doctrine's re-arm to rule.
|
|
396
|
+
*/
|
|
397
|
+
export declare function findLegDepositForHead(totemDirAbs: string, headSha: string, git: LegGitAdapter, coverage?: LegCoverageQuery): LegDepositResolution;
|
|
398
|
+
export interface LegFindingCounts {
|
|
399
|
+
blocking: number;
|
|
400
|
+
material: number;
|
|
401
|
+
minor: number;
|
|
402
|
+
/** `folded.length` — the ids the seat folded, which are STILL counted above. */
|
|
403
|
+
folded: number;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Count a deposit's findings by severity, plus how many were folded.
|
|
407
|
+
*
|
|
408
|
+
* A folded finding is still a finding: it is counted in its severity bucket
|
|
409
|
+
* AND in `folded`. The covariate prints both, so a reader can see "3 blocking,
|
|
410
|
+
* 3 folded" (all addressed) apart from "3 blocking, 0 folded" (none were).
|
|
411
|
+
*/
|
|
412
|
+
export declare function countLegFindings(deposit: LegDeposit): LegFindingCounts;
|
|
413
|
+
/**
|
|
414
|
+
* Render the covariate line's format-v1.2 `leg:` field — the ONE spelling of
|
|
415
|
+
* this text, exactly:
|
|
416
|
+
*
|
|
417
|
+
* `leg: <sha8> blocking=N material=N folded=N` (a deposit resolved)
|
|
418
|
+
* `leg: none` (none did)
|
|
419
|
+
*
|
|
420
|
+
* The field is COMPOSED BESIDE {@link renderCovariateLine} / `renderAdmissionLine`,
|
|
421
|
+
* never inside them: the v1 shapes stay byte-identical, and a consumer keeps
|
|
422
|
+
* discriminating on the second token. The text is contract — the pilot ledger
|
|
423
|
+
* greps this line — so it is spelled here and nowhere else.
|
|
424
|
+
*
|
|
425
|
+
* `minor` is deliberately absent from the field: the round rules on blocking
|
|
426
|
+
* and material, and `folded` is what says whether they were addressed. The
|
|
427
|
+
* full counts stay available via {@link countLegFindings}.
|
|
428
|
+
*/
|
|
429
|
+
export declare function renderLegField(deposit: LegDeposit | undefined): string;
|
|
430
|
+
//# sourceMappingURL=legs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legs.d.ts","sourceRoot":"","sources":["../../src/artifacts/legs.ts"],"names":[],"mappings":"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"}
|