@geonosis/ledger 1.0.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/LICENSE +202 -0
- package/README.md +387 -0
- package/bin/geonosis-ledger.mjs +4 -0
- package/dist/chunk-WI3N5B3J.js +1538 -0
- package/dist/index.d.ts +469 -0
- package/dist/index.js +110 -0
- package/dist/ledger-cli.js +339 -0
- package/package.json +43 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
type Args = {
|
|
2
|
+
flags: Record<string, string>;
|
|
3
|
+
positional: string[];
|
|
4
|
+
switches: Set<string>;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* `--flag value` and bare `--switch`, told apart by a declared set rather than by guessing from the
|
|
8
|
+
* next token — `--note --plan 3` would otherwise silently eat the next flag as a note.
|
|
9
|
+
*/
|
|
10
|
+
declare const parseArgs: (argv: string[], valued: Set<string>) => Args;
|
|
11
|
+
/** The value of a flag the command cannot run without, refused by name when it is not there. */
|
|
12
|
+
declare const required: (args: Args, flag: string) => string;
|
|
13
|
+
|
|
14
|
+
/** A file kind test, spelled as two regex lists: a file counts when it matches one and no other. */
|
|
15
|
+
type RuntimePatterns = {
|
|
16
|
+
exclude: string[];
|
|
17
|
+
include: string[];
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The four shapes a plan is checked for. Every one is a regex an adopting repo may set, because a
|
|
21
|
+
* heading name is a repo's vocabulary — during.day writes `## Done criteria` and geonosis writes
|
|
22
|
+
* `## Acceptance criteria`, and a kit that hard-codes either has hard-coded a repo (law 6).
|
|
23
|
+
*/
|
|
24
|
+
type PlanPatterns = {
|
|
25
|
+
criteria: string;
|
|
26
|
+
criteriaHeading: string;
|
|
27
|
+
statusHeader: string;
|
|
28
|
+
verificationHeading: string;
|
|
29
|
+
};
|
|
30
|
+
type LedgerConfig = {
|
|
31
|
+
/** Where `sync --target agents-md` writes the law's projection for every other agent. */
|
|
32
|
+
agents: string;
|
|
33
|
+
architecture: string;
|
|
34
|
+
commitMessageLines: number;
|
|
35
|
+
decisions: string;
|
|
36
|
+
handoff: string;
|
|
37
|
+
journal: string;
|
|
38
|
+
/** The law itself — the file `lawLineCount` counts and `sync` projects. */
|
|
39
|
+
law: string;
|
|
40
|
+
/** The heading in it whose section IS the rules, as a regular expression. */
|
|
41
|
+
lawSection: string;
|
|
42
|
+
maxLines: number;
|
|
43
|
+
plan: PlanPatterns;
|
|
44
|
+
plans: string;
|
|
45
|
+
progress: string;
|
|
46
|
+
proofs: string;
|
|
47
|
+
/** The glob-scoped rule files, which `sync --target cursor` translates. */
|
|
48
|
+
rules: string;
|
|
49
|
+
runtime: RuntimePatterns;
|
|
50
|
+
/** The skills directory, read for the one-line summaries AGENTS.md carries. */
|
|
51
|
+
skills: string;
|
|
52
|
+
};
|
|
53
|
+
declare const LEDGER_DEFAULT: LedgerConfig;
|
|
54
|
+
/** The `ledger` block of `geonosis.json`, every key optional, every default a contract. */
|
|
55
|
+
declare const loadLedgerConfig: (root: string) => LedgerConfig;
|
|
56
|
+
/** G0, as a predicate: the file is of a runtime kind and is excluded by nothing. */
|
|
57
|
+
declare const matchesRuntime: (file: string, runtime: RuntimePatterns) => boolean;
|
|
58
|
+
|
|
59
|
+
/** A markdown heading, by line index and depth, so a section can be bounded by the next peer. */
|
|
60
|
+
type Heading = {
|
|
61
|
+
depth: number;
|
|
62
|
+
index: number;
|
|
63
|
+
text: string;
|
|
64
|
+
};
|
|
65
|
+
declare const headingsOf: (lines: string[]) => Heading[];
|
|
66
|
+
/**
|
|
67
|
+
* The lines under a heading, up to the next heading of the same depth or shallower. A criterion
|
|
68
|
+
* that sits under some other heading is not this heading's criterion, and a check that greps the
|
|
69
|
+
* whole file cannot tell the difference.
|
|
70
|
+
*/
|
|
71
|
+
declare const sectionUnder: (lines: string[], pattern: string) => string[] | undefined;
|
|
72
|
+
type Table = {
|
|
73
|
+
align: string;
|
|
74
|
+
header: string[];
|
|
75
|
+
headerIndex: number;
|
|
76
|
+
rows: number[];
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* The first pipe table in the file: its header cells, the divider verbatim (so a rewrite keeps the
|
|
80
|
+
* register's own column padding), and the indices of its body rows.
|
|
81
|
+
*/
|
|
82
|
+
declare const firstTable: (lines: string[]) => Table | undefined;
|
|
83
|
+
declare const rowCells: (line: string) => string[];
|
|
84
|
+
/** A cell's content, with a leading `**` emphasis and surrounding backticks taken off. */
|
|
85
|
+
declare const plainCell: (cell: string) => string;
|
|
86
|
+
declare const renderRow: (cells: string[]) => string;
|
|
87
|
+
|
|
88
|
+
type PlanReport = {
|
|
89
|
+
checked: number;
|
|
90
|
+
legacy: string[];
|
|
91
|
+
violations: string[];
|
|
92
|
+
};
|
|
93
|
+
type CheckPlansInput = {
|
|
94
|
+
config: LedgerConfig;
|
|
95
|
+
root: string;
|
|
96
|
+
since?: number;
|
|
97
|
+
target?: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Every violation of every plan, named by file. `--since` exempts the plans a repo wrote before it
|
|
101
|
+
* adopted the contract: they are reported as `legacy` and hold nothing up, because a gate that
|
|
102
|
+
* refuses the whole back catalogue on the day it is installed is a gate that gets uninstalled.
|
|
103
|
+
*/
|
|
104
|
+
declare const checkPlans: ({ config, root, since, target }: CheckPlansInput) => PlanReport;
|
|
105
|
+
type PlanStatus = {
|
|
106
|
+
file: string;
|
|
107
|
+
status: string;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Every plan and the status word it declares. The word is capture group 1 of `plan.statusHeader`,
|
|
111
|
+
* so a repo whose plans say `## Status` followed by a table can name its own — and a pattern with
|
|
112
|
+
* no group leaves the status unnamed rather than making one up.
|
|
113
|
+
*/
|
|
114
|
+
declare const planStatuses: ({ config, root, }: {
|
|
115
|
+
config: LedgerConfig;
|
|
116
|
+
root: string;
|
|
117
|
+
}) => PlanStatus[];
|
|
118
|
+
/** The number after the highest on disk — never the count, which reuses a number after a delete. */
|
|
119
|
+
declare const nextNumber: (dir: string) => string;
|
|
120
|
+
/**
|
|
121
|
+
* The skeleton, and nothing else. Its one criterion is a placeholder that `plan check` REFUSES, so
|
|
122
|
+
* the file cannot be ticked until a person has written the sentence — the ledger authors a shape,
|
|
123
|
+
* never a specification (challenge C9: 2,100 lines of spec for 600 of code).
|
|
124
|
+
*/
|
|
125
|
+
declare const newPlan: ({ config, root, slug, }: {
|
|
126
|
+
config: LedgerConfig;
|
|
127
|
+
root: string;
|
|
128
|
+
slug: string;
|
|
129
|
+
}) => string;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The four ways an agent delivers something that is not the thing. No kit in the 2026 survey asked
|
|
133
|
+
* an agent to record where it stubbed, which is why a stub reads as done in every report after it.
|
|
134
|
+
*/
|
|
135
|
+
declare const FALLBACK_KINDS: readonly ["stub", "mock", "guess", "skip"];
|
|
136
|
+
type FallbackKind = (typeof FALLBACK_KINDS)[number];
|
|
137
|
+
declare const JOURNAL_HEADER: string[];
|
|
138
|
+
type FallbackInput = {
|
|
139
|
+
config: LedgerConfig;
|
|
140
|
+
kind: string;
|
|
141
|
+
now: Date;
|
|
142
|
+
root: string;
|
|
143
|
+
where: string;
|
|
144
|
+
why: string;
|
|
145
|
+
};
|
|
146
|
+
/** Appends one dated row. Refuses a kind it does not know, a where without a line, an empty why. */
|
|
147
|
+
declare const appendFallback: ({ config, kind, now, root, where, why }: FallbackInput) => string;
|
|
148
|
+
|
|
149
|
+
type ProofInput = {
|
|
150
|
+
command: string;
|
|
151
|
+
config: LedgerConfig;
|
|
152
|
+
root: string;
|
|
153
|
+
slug: string;
|
|
154
|
+
url?: string;
|
|
155
|
+
};
|
|
156
|
+
type ProofOutcome = {
|
|
157
|
+
exitCode: number;
|
|
158
|
+
file: string;
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Runs the command and writes what happened. The returned exit code is the COMMAND's, so a failing
|
|
162
|
+
* proof is recorded and still fails — a capture that swallowed the red would be the gate reporting
|
|
163
|
+
* green over a run it had just watched break.
|
|
164
|
+
*/
|
|
165
|
+
declare const captureProof: ({ command, config, root, slug, url }: ProofInput) => ProofOutcome;
|
|
166
|
+
|
|
167
|
+
/** ISO date, no clock: a ledger row is a day, and a time zone in it is a diff nobody asked for. */
|
|
168
|
+
declare const isoDate: (now: Date) => string;
|
|
169
|
+
/**
|
|
170
|
+
* Append one row, creating the file and its header when it is not there. Append, never rewrite: a
|
|
171
|
+
* ledger that can rewrite its own past rows is a diary, and every earlier row is then a claim.
|
|
172
|
+
*/
|
|
173
|
+
declare const appendRow: (file: string, root: string, header: string[], cells: string[]) => string;
|
|
174
|
+
|
|
175
|
+
declare const PROGRESS_HEADER: string[];
|
|
176
|
+
type TickInput = {
|
|
177
|
+
commit: string;
|
|
178
|
+
config: LedgerConfig;
|
|
179
|
+
note?: string;
|
|
180
|
+
now: Date;
|
|
181
|
+
plan: string;
|
|
182
|
+
proof: string;
|
|
183
|
+
root: string;
|
|
184
|
+
};
|
|
185
|
+
type TickOutcome = {
|
|
186
|
+
number?: number;
|
|
187
|
+
refusal?: string;
|
|
188
|
+
row?: string;
|
|
189
|
+
};
|
|
190
|
+
/**
|
|
191
|
+
* The tick gate. Four refusals, checked in this order, each with the reason on the outcome:
|
|
192
|
+
*
|
|
193
|
+
* 1. the hash does not name a commit;
|
|
194
|
+
* 2. the plan it names does not exist, or does not pass `plan check`;
|
|
195
|
+
* 3. the proof file is not on disk;
|
|
196
|
+
* 4. **G0** — the commit's diff holds no runtime code (dielime's non-negotiable gate, back as a
|
|
197
|
+
* refusal rather than a ratchet counter, per D-025).
|
|
198
|
+
*
|
|
199
|
+
* On success it appends ONE row to the progress file. That append is the only write it makes, and a
|
|
200
|
+
* refused tick makes none at all.
|
|
201
|
+
*/
|
|
202
|
+
declare const runTick: ({ commit, config, note, now, plan, proof, root, }: TickInput) => TickOutcome;
|
|
203
|
+
|
|
204
|
+
/** The column challenge C10 asks every register to carry. */
|
|
205
|
+
declare const REVISIT_COLUMN = "Revisit trigger";
|
|
206
|
+
type DecideInput = {
|
|
207
|
+
config: LedgerConfig;
|
|
208
|
+
evidence: string;
|
|
209
|
+
id: string;
|
|
210
|
+
revisit: string;
|
|
211
|
+
root: string;
|
|
212
|
+
status?: string;
|
|
213
|
+
text: string;
|
|
214
|
+
why: string;
|
|
215
|
+
};
|
|
216
|
+
type DecideOutcome = {
|
|
217
|
+
refusal?: string;
|
|
218
|
+
row?: string;
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* Appends one row to the decisions register.
|
|
222
|
+
*
|
|
223
|
+
* It refuses without a revisit trigger (C10 — a decision with no stated event that would reopen it
|
|
224
|
+
* is a diary entry, not an instrument), and it refuses a register whose header has no column for
|
|
225
|
+
* one, printing the exact header line to add. It does NOT add the column: the register's shape is
|
|
226
|
+
* the register's, and a tool that rewrites the shape it validates has become the source of truth
|
|
227
|
+
* for it.
|
|
228
|
+
*/
|
|
229
|
+
declare const runDecide: ({ config, evidence, id, revisit, root, status, text, why, }: DecideInput) => DecideOutcome;
|
|
230
|
+
|
|
231
|
+
/** The contract path from build-plan §3: the verify runner writes it, everything else reads it. */
|
|
232
|
+
declare const GATE_REPORT = ".geonosis/gate-report.json";
|
|
233
|
+
type GateSummary = {
|
|
234
|
+
finishedAt: string;
|
|
235
|
+
ok: boolean;
|
|
236
|
+
tier: string;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Three fields of the gate report, never the steps. The ledger reports what the runner found; it
|
|
240
|
+
* does not re-run or re-judge it, which is musa's rule that a digest never recomputes validation.
|
|
241
|
+
*/
|
|
242
|
+
declare const gateSummary: (root: string) => GateSummary | undefined;
|
|
243
|
+
/**
|
|
244
|
+
* How many counters the ratchet holds a number for. Read as JSON off disk, never through the
|
|
245
|
+
* ratchet package: the ledger reports the baseline and must never be one import from rewriting it.
|
|
246
|
+
*/
|
|
247
|
+
declare const baselineKeyCount: (root: string) => number | undefined;
|
|
248
|
+
|
|
249
|
+
declare const CLOSE_START = "<!-- geonosis-ledger:session-close -->";
|
|
250
|
+
declare const CLOSE_END = "<!-- /geonosis-ledger:session-close -->";
|
|
251
|
+
type HandoffInput = {
|
|
252
|
+
config: LedgerConfig;
|
|
253
|
+
root: string;
|
|
254
|
+
write: boolean;
|
|
255
|
+
};
|
|
256
|
+
type HandoffOutcome = {
|
|
257
|
+
block: string;
|
|
258
|
+
written: boolean;
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* The SESSION CLOSE block, rewritten between its markers.
|
|
262
|
+
*
|
|
263
|
+
* It is a pure function of the tree: no clock, no run id, nothing that changes when nothing did.
|
|
264
|
+
* A handoff that differs on every invocation is a diff nobody made, and after the third one nobody
|
|
265
|
+
* reads the block at all.
|
|
266
|
+
*
|
|
267
|
+
* Everything outside the markers is left exactly as it was — the file belongs to whoever writes it,
|
|
268
|
+
* and this tool owns four HTML comments' worth of it.
|
|
269
|
+
*/
|
|
270
|
+
declare const runHandoff: ({ config, root, write }: HandoffInput) => HandoffOutcome;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The digest is a perception surface, and an unbounded one is the context window it exists to
|
|
274
|
+
* protect. Six lines, always the same six, whatever the size of the repo behind them.
|
|
275
|
+
*/
|
|
276
|
+
declare const STATUS_MAX_LINES = 6;
|
|
277
|
+
type StatusDigest = {
|
|
278
|
+
baselineKeys?: number;
|
|
279
|
+
gate?: GateSummary;
|
|
280
|
+
head?: string;
|
|
281
|
+
journalRows: number;
|
|
282
|
+
lastTick?: string;
|
|
283
|
+
plans: {
|
|
284
|
+
count: number;
|
|
285
|
+
status: string;
|
|
286
|
+
}[];
|
|
287
|
+
};
|
|
288
|
+
type StatusInput = {
|
|
289
|
+
config: LedgerConfig;
|
|
290
|
+
root: string;
|
|
291
|
+
};
|
|
292
|
+
/** Read, never recompute: nothing here re-runs a gate or re-validates what a gate already judged. */
|
|
293
|
+
declare const readStatus: ({ config, root }: StatusInput) => StatusDigest;
|
|
294
|
+
/** The pinned shape. A contract test holds it, because a digest whose shape moves cannot be read. */
|
|
295
|
+
declare const formatStatus: (digest: StatusDigest) => string;
|
|
296
|
+
|
|
297
|
+
/** The one header the contract asks a target-architecture document to carry. */
|
|
298
|
+
declare const EDGES_HEADER = "| tag | packages | may depend on |";
|
|
299
|
+
type Edge = {
|
|
300
|
+
mayDependOn: string[];
|
|
301
|
+
notes: string[];
|
|
302
|
+
packages: string[];
|
|
303
|
+
tag: string;
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* during.day's table is the shape: `| tag | packages | may depend on |`, matched whitespace- and
|
|
307
|
+
* emphasis-insensitively, because a markdown table's padding is a formatter's business.
|
|
308
|
+
*/
|
|
309
|
+
declare const readEdges: (lines: string[]) => Edge[] | undefined;
|
|
310
|
+
type WorkspacePackage = {
|
|
311
|
+
dir: string;
|
|
312
|
+
name: string;
|
|
313
|
+
};
|
|
314
|
+
/** Every workspace directory and the package name it declares — the ground truth a table is checked against. */
|
|
315
|
+
declare const workspacePackages: (root: string) => WorkspacePackage[] | undefined;
|
|
316
|
+
type ArchitectureReport = {
|
|
317
|
+
edges: Edge[];
|
|
318
|
+
notes: string[];
|
|
319
|
+
packages?: WorkspacePackage[];
|
|
320
|
+
violations: string[];
|
|
321
|
+
};
|
|
322
|
+
type ArchitectureInput = {
|
|
323
|
+
config: LedgerConfig;
|
|
324
|
+
root: string;
|
|
325
|
+
workspace: boolean;
|
|
326
|
+
};
|
|
327
|
+
/**
|
|
328
|
+
* The architecture document as a checkable contract (challenge C8). Every package cell has to name a
|
|
329
|
+
* real workspace directory and every edge a declared tag, because the three configs `sync` generates
|
|
330
|
+
* from this table are only as true as the table is.
|
|
331
|
+
*/
|
|
332
|
+
declare const checkArchitecture: ({ config, root, workspace, }: ArchitectureInput) => ArchitectureReport;
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Replace the value at `path` with `rendered`, leaving **every other byte of the file exactly as it
|
|
336
|
+
* was**.
|
|
337
|
+
*
|
|
338
|
+
* `JSON.parse` then `JSON.stringify` would work and would reformat the whole file, which turns a
|
|
339
|
+
* one-key sync into a diff nobody can review — and in a repo whose formatter is not the one node
|
|
340
|
+
* ships with, it turns it into a fight with the formatter as well. So the value's span is found by
|
|
341
|
+
* scanning and spliced. It is not fooled by the key's name appearing inside a string, because
|
|
342
|
+
* strings are consumed whole.
|
|
343
|
+
*/
|
|
344
|
+
declare const replaceJsonValue: (source: string, path: string[], rendered: string) => string;
|
|
345
|
+
/** The value at `path`, or undefined — the same scan, used by `--check` to read what is committed. */
|
|
346
|
+
declare const readJsonValue: (source: string, path: string[]) => unknown;
|
|
347
|
+
|
|
348
|
+
declare const SYNC_TARGETS: readonly ["turbo", "layer-walls", "restricted-imports", "agents-md", "cursor"];
|
|
349
|
+
type SyncTarget = (typeof SYNC_TARGETS)[number];
|
|
350
|
+
declare const LAYER_WALLS_RULE = "biological-architecture/layer-walls";
|
|
351
|
+
type SyncInput = {
|
|
352
|
+
check?: string;
|
|
353
|
+
config: LedgerConfig;
|
|
354
|
+
packageName?: string;
|
|
355
|
+
root: string;
|
|
356
|
+
target: string;
|
|
357
|
+
write?: string;
|
|
358
|
+
};
|
|
359
|
+
type SyncOutcome = {
|
|
360
|
+
diff?: string;
|
|
361
|
+
generated: string;
|
|
362
|
+
ok: boolean;
|
|
363
|
+
written?: string;
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* One table, three spellings (challenge C8). Every spelling is GENERATED, and `--write` splices only
|
|
367
|
+
* the named fragment so the rest of the file — schema, tasks, every other rule — is untouched.
|
|
368
|
+
*
|
|
369
|
+
* The two document targets (C13's cross-tool parity) sit beside those three rather than inside
|
|
370
|
+
* them: they read the law and the rule files, not the edges table, and demanding an architecture
|
|
371
|
+
* file before generating an AGENTS.md would be a coupling nobody asked for.
|
|
372
|
+
*/
|
|
373
|
+
declare const runSync: ({ check, config, packageName, root, target, write, }: SyncInput) => SyncOutcome;
|
|
374
|
+
|
|
375
|
+
/** The targets that generate a DOCUMENT rather than splicing a fragment into someone's JSON. */
|
|
376
|
+
declare const DOC_TARGETS: readonly ["agents-md", "cursor"];
|
|
377
|
+
type DocTarget = (typeof DOC_TARGETS)[number];
|
|
378
|
+
declare const isDocTarget: (target: string) => target is DocTarget;
|
|
379
|
+
/** One generated file: where it goes, relative to the directory the caller named, and what is in it. */
|
|
380
|
+
type DocFile = {
|
|
381
|
+
contents: string;
|
|
382
|
+
name: string;
|
|
383
|
+
};
|
|
384
|
+
/**
|
|
385
|
+
* `AGENTS.md`, generated.
|
|
386
|
+
*
|
|
387
|
+
* Claude Code does not read `AGENTS.md`; it reads a `CLAUDE.md` that imports it. Every other agent
|
|
388
|
+
* on the standard reads `AGENTS.md` and nothing else. So one of the two files has to be generated
|
|
389
|
+
* from the other, and it is this one — the law is written by a person, and this is its projection.
|
|
390
|
+
*
|
|
391
|
+
* Three parts, none of them a copy of a whole file: the law's RULES section, one line per skill
|
|
392
|
+
* from the skill's own frontmatter, and one line per glob-scoped rule saying when it applies. A
|
|
393
|
+
* second copy of the law would be a second law.
|
|
394
|
+
*/
|
|
395
|
+
declare const buildAgentsMd: ({ config, root }: {
|
|
396
|
+
config: LedgerConfig;
|
|
397
|
+
root: string;
|
|
398
|
+
}) => string;
|
|
399
|
+
/**
|
|
400
|
+
* The same glob-scoped rules, in Cursor's vocabulary.
|
|
401
|
+
*
|
|
402
|
+
* `paths: ["**"]` and `alwaysApply: true` are one statement in two dialects, and Cursor IGNORES
|
|
403
|
+
* `globs` when `alwaysApply` is set — emitting both would be a line that does nothing beside a line
|
|
404
|
+
* that does. Cursor's globs are one comma-separated string, not a list.
|
|
405
|
+
*/
|
|
406
|
+
declare const buildCursorRules: ({ config, root, }: {
|
|
407
|
+
config: LedgerConfig;
|
|
408
|
+
root: string;
|
|
409
|
+
}) => DocFile[];
|
|
410
|
+
/** What a doc target generates: one file, or a directory of them. */
|
|
411
|
+
declare const buildDoc: ({ config, root, target, }: {
|
|
412
|
+
config: LedgerConfig;
|
|
413
|
+
root: string;
|
|
414
|
+
target: DocTarget;
|
|
415
|
+
}) => DocFile[];
|
|
416
|
+
|
|
417
|
+
type Refusal = {
|
|
418
|
+
refusal?: string;
|
|
419
|
+
};
|
|
420
|
+
/**
|
|
421
|
+
* The lines a commit message is judged on: the subject and the body, with the blank lines, the `#`
|
|
422
|
+
* lines git puts in the editor file, everything past the `--verbose` scissors, and the trailing
|
|
423
|
+
* block of trailers taken out.
|
|
424
|
+
*
|
|
425
|
+
* Trailers are metadata git appends; counting them would ration the body by how much tooling the
|
|
426
|
+
* repo runs. A `Note: …` in the middle of the body IS counted — the trailing block is the only
|
|
427
|
+
* place a trailer can be, which is git's own rule and not a new one.
|
|
428
|
+
*/
|
|
429
|
+
declare const countedLines: (message: string) => string[];
|
|
430
|
+
/**
|
|
431
|
+
* A delivery whose message needs a fifth line is a delivery that should have been two commits, or a
|
|
432
|
+
* paragraph that belongs in a proof file. The narration is not the work.
|
|
433
|
+
*/
|
|
434
|
+
declare const checkCommitMessage: (message: string, config: LedgerConfig) => Refusal;
|
|
435
|
+
type DeliveryInput = {
|
|
436
|
+
commit?: string;
|
|
437
|
+
root: string;
|
|
438
|
+
staged: boolean;
|
|
439
|
+
};
|
|
440
|
+
/**
|
|
441
|
+
* Refuses a delivery whose every changed line is a comment or whitespace.
|
|
442
|
+
*
|
|
443
|
+
* Deleting comments counts too: a sweep is still a comments-only delivery, and rides along with
|
|
444
|
+
* runtime code the same way G0 lets docs ride along. A file whose language is not known contributes
|
|
445
|
+
* nothing to the "all comments" verdict — its changed lines are treated as code, which is the safe
|
|
446
|
+
* direction for a gate that refuses.
|
|
447
|
+
*/
|
|
448
|
+
declare const checkDelivery: ({ commit, root, staged }: DeliveryInput) => Refusal;
|
|
449
|
+
|
|
450
|
+
type Probe = {
|
|
451
|
+
finding: string;
|
|
452
|
+
gate: string;
|
|
453
|
+
refusal?: string;
|
|
454
|
+
};
|
|
455
|
+
type ProveReport = {
|
|
456
|
+
ok: boolean;
|
|
457
|
+
probes: Probe[];
|
|
458
|
+
};
|
|
459
|
+
/**
|
|
460
|
+
* Each delivery gate, planted against.
|
|
461
|
+
*
|
|
462
|
+
* A gate that has never been shown refusing is a claim, not a gate — the same reasoning as the
|
|
463
|
+
* ratchet's `--prove`. Every probe writes the exact thing the rule forbids into a throwaway repo and
|
|
464
|
+
* the rule has to say so; a probe that comes back clean is the failure.
|
|
465
|
+
*/
|
|
466
|
+
declare const runProve: (config: LedgerConfig) => ProveReport;
|
|
467
|
+
declare const formatProve: (report: ProveReport) => string;
|
|
468
|
+
|
|
469
|
+
export { type ArchitectureReport, type Args, CLOSE_END, CLOSE_START, DOC_TARGETS, type DecideOutcome, type DeliveryInput, type DocFile, type DocTarget, EDGES_HEADER, type Edge, FALLBACK_KINDS, type FallbackKind, GATE_REPORT, type GateSummary, type HandoffOutcome, JOURNAL_HEADER, LAYER_WALLS_RULE, LEDGER_DEFAULT, type LedgerConfig, PROGRESS_HEADER, type PlanPatterns, type PlanReport, type PlanStatus, type Probe, type ProofOutcome, type ProveReport, REVISIT_COLUMN, type Refusal, type RuntimePatterns, STATUS_MAX_LINES, SYNC_TARGETS, type StatusDigest, type SyncOutcome, type SyncTarget, type TickOutcome, type WorkspacePackage, appendFallback, appendRow, baselineKeyCount, buildAgentsMd, buildCursorRules, buildDoc, captureProof, checkArchitecture, checkCommitMessage, checkDelivery, checkPlans, countedLines, firstTable, formatProve, formatStatus, gateSummary, headingsOf, isDocTarget, isoDate, loadLedgerConfig, matchesRuntime, newPlan, nextNumber, parseArgs, plainCell, planStatuses, readEdges, readJsonValue, readStatus, renderRow, replaceJsonValue, required, rowCells, runDecide, runHandoff, runProve, runSync, runTick, sectionUnder, workspacePackages };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLOSE_END,
|
|
3
|
+
CLOSE_START,
|
|
4
|
+
DOC_TARGETS,
|
|
5
|
+
EDGES_HEADER,
|
|
6
|
+
FALLBACK_KINDS,
|
|
7
|
+
GATE_REPORT,
|
|
8
|
+
JOURNAL_HEADER,
|
|
9
|
+
LAYER_WALLS_RULE,
|
|
10
|
+
LEDGER_DEFAULT,
|
|
11
|
+
PROGRESS_HEADER,
|
|
12
|
+
REVISIT_COLUMN,
|
|
13
|
+
STATUS_MAX_LINES,
|
|
14
|
+
SYNC_TARGETS,
|
|
15
|
+
appendFallback,
|
|
16
|
+
appendRow,
|
|
17
|
+
baselineKeyCount,
|
|
18
|
+
buildAgentsMd,
|
|
19
|
+
buildCursorRules,
|
|
20
|
+
buildDoc,
|
|
21
|
+
captureProof,
|
|
22
|
+
checkArchitecture,
|
|
23
|
+
checkCommitMessage,
|
|
24
|
+
checkDelivery,
|
|
25
|
+
checkPlans,
|
|
26
|
+
countedLines,
|
|
27
|
+
firstTable,
|
|
28
|
+
formatProve,
|
|
29
|
+
formatStatus,
|
|
30
|
+
gateSummary,
|
|
31
|
+
headingsOf,
|
|
32
|
+
isDocTarget,
|
|
33
|
+
isoDate,
|
|
34
|
+
loadLedgerConfig,
|
|
35
|
+
matchesRuntime,
|
|
36
|
+
newPlan,
|
|
37
|
+
nextNumber,
|
|
38
|
+
parseArgs,
|
|
39
|
+
plainCell,
|
|
40
|
+
planStatuses,
|
|
41
|
+
readEdges,
|
|
42
|
+
readJsonValue,
|
|
43
|
+
readStatus,
|
|
44
|
+
renderRow,
|
|
45
|
+
replaceJsonValue,
|
|
46
|
+
required,
|
|
47
|
+
rowCells,
|
|
48
|
+
runDecide,
|
|
49
|
+
runHandoff,
|
|
50
|
+
runProve,
|
|
51
|
+
runSync,
|
|
52
|
+
runTick,
|
|
53
|
+
sectionUnder,
|
|
54
|
+
workspacePackages
|
|
55
|
+
} from "./chunk-WI3N5B3J.js";
|
|
56
|
+
export {
|
|
57
|
+
CLOSE_END,
|
|
58
|
+
CLOSE_START,
|
|
59
|
+
DOC_TARGETS,
|
|
60
|
+
EDGES_HEADER,
|
|
61
|
+
FALLBACK_KINDS,
|
|
62
|
+
GATE_REPORT,
|
|
63
|
+
JOURNAL_HEADER,
|
|
64
|
+
LAYER_WALLS_RULE,
|
|
65
|
+
LEDGER_DEFAULT,
|
|
66
|
+
PROGRESS_HEADER,
|
|
67
|
+
REVISIT_COLUMN,
|
|
68
|
+
STATUS_MAX_LINES,
|
|
69
|
+
SYNC_TARGETS,
|
|
70
|
+
appendFallback,
|
|
71
|
+
appendRow,
|
|
72
|
+
baselineKeyCount,
|
|
73
|
+
buildAgentsMd,
|
|
74
|
+
buildCursorRules,
|
|
75
|
+
buildDoc,
|
|
76
|
+
captureProof,
|
|
77
|
+
checkArchitecture,
|
|
78
|
+
checkCommitMessage,
|
|
79
|
+
checkDelivery,
|
|
80
|
+
checkPlans,
|
|
81
|
+
countedLines,
|
|
82
|
+
firstTable,
|
|
83
|
+
formatProve,
|
|
84
|
+
formatStatus,
|
|
85
|
+
gateSummary,
|
|
86
|
+
headingsOf,
|
|
87
|
+
isDocTarget,
|
|
88
|
+
isoDate,
|
|
89
|
+
loadLedgerConfig,
|
|
90
|
+
matchesRuntime,
|
|
91
|
+
newPlan,
|
|
92
|
+
nextNumber,
|
|
93
|
+
parseArgs,
|
|
94
|
+
plainCell,
|
|
95
|
+
planStatuses,
|
|
96
|
+
readEdges,
|
|
97
|
+
readJsonValue,
|
|
98
|
+
readStatus,
|
|
99
|
+
renderRow,
|
|
100
|
+
replaceJsonValue,
|
|
101
|
+
required,
|
|
102
|
+
rowCells,
|
|
103
|
+
runDecide,
|
|
104
|
+
runHandoff,
|
|
105
|
+
runProve,
|
|
106
|
+
runSync,
|
|
107
|
+
runTick,
|
|
108
|
+
sectionUnder,
|
|
109
|
+
workspacePackages
|
|
110
|
+
};
|