@plurnk/plurnk-digest 2.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/.env.defaults +5 -0
- package/README.md +31 -0
- package/SPEC.md +131 -0
- package/dist/Digest.d.ts +8 -0
- package/dist/Digest.d.ts.map +1 -0
- package/dist/Digest.js +243 -0
- package/dist/Digest.js.map +1 -0
- package/dist/DigestRender.d.ts +18 -0
- package/dist/DigestRender.d.ts.map +1 -0
- package/dist/DigestRender.js +1038 -0
- package/dist/DigestRender.js.map +1 -0
- package/dist/DigestRequiem.d.ts +13 -0
- package/dist/DigestRequiem.d.ts.map +1 -0
- package/dist/DigestRequiem.js +403 -0
- package/dist/DigestRequiem.js.map +1 -0
- package/dist/Share.d.ts +16 -0
- package/dist/Share.d.ts.map +1 -0
- package/dist/Share.js +97 -0
- package/dist/Share.js.map +1 -0
- package/dist/digest-paths.d.ts +6 -0
- package/dist/digest-paths.d.ts.map +1 -0
- package/dist/digest-paths.js +14 -0
- package/dist/digest-paths.js.map +1 -0
- package/dist/digest-rows.d.ts +347 -0
- package/dist/digest-rows.d.ts.map +1 -0
- package/dist/digest-rows.js +2 -0
- package/dist/digest-rows.js.map +1 -0
- package/dist/evidence.d.ts +49 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +2 -0
- package/dist/evidence.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/share.sql +6 -0
- package/package.json +53 -0
package/.env.defaults
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# Forensic interviews ({§digest-requiem}); only requested interviews call a model.
|
|
2
|
+
# Initial witness output allowance, tokens.
|
|
3
|
+
PLURNK_DIGEST_REQUIEM_MAX_TOKENS=16384
|
|
4
|
+
# Retry allowance for empty length-limited testimony; at least the initial allowance.
|
|
5
|
+
PLURNK_DIGEST_REQUIEM_RETRY_MAX_TOKENS=32768
|
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Plurnk Digest
|
|
2
|
+
|
|
3
|
+
Forensic Markdown, JSON, packet artifacts, SQLite snapshots and model interviews. Rendering is
|
|
4
|
+
independent of the daemon; the service supplies its canonical evidence reader.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { Digest, Share } from "@plurnk/plurnk-digest";
|
|
8
|
+
import EvidenceReader from "@plurnk/plurnk-service/evidence";
|
|
9
|
+
|
|
10
|
+
// A live database is snapshotted before reading.
|
|
11
|
+
await Share.write({ dbPath: "/data/plurnk.db", folder: "./report", openEvidence: EvidenceReader.open });
|
|
12
|
+
|
|
13
|
+
// A closed database can be read directly.
|
|
14
|
+
Digest.run({ dbPath: "./saved.db", digestDir: "./digest", openEvidence: EvidenceReader.open });
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Neither path overwrites existing reports. An interview additionally requires an explicit
|
|
18
|
+
`provider`: `Digest.requiem({ dbPath, digestDir, openEvidence, provider })`; `Share.write`
|
|
19
|
+
accepts that provider as `requiem`. No route is selected and no inference occurs implicitly.
|
|
20
|
+
|
|
21
|
+
The service CLI remains `plurnk-service share [database] [folder] [--requiem]`.
|
|
22
|
+
See [SPEC.md](./SPEC.md) for evidence ownership, artifact fidelity and reader lifetime;
|
|
23
|
+
[.env.defaults](./.env.defaults) owns interview allowances.
|
|
24
|
+
|
|
25
|
+
## Upgrading
|
|
26
|
+
|
|
27
|
+
The former service `/digest` and `/share` exports are removed. Import this package and explicitly
|
|
28
|
+
supply the service's `/evidence` reader. The interview settings are
|
|
29
|
+
`PLURNK_DIGEST_REQUIEM_MAX_TOKENS` and `PLURNK_DIGEST_REQUIEM_RETRY_MAX_TOKENS`; the former
|
|
30
|
+
`PLURNK_SERVICE_REQUIEM_*` names are refused, not aliases. Database and share-directory selection
|
|
31
|
+
remain service-owned.
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Forensic reports
|
|
2
|
+
|
|
3
|
+
The report package owns artifact generation, SQLite snapshots and requested model interviews.
|
|
4
|
+
The host supplies the evidence reader and selects any interview provider; the package never boots
|
|
5
|
+
or imports the daemon.
|
|
6
|
+
|
|
7
|
+
## Evidence boundary
|
|
8
|
+
|
|
9
|
+
§digest-evidence-reader **Interpret once, render independently.**
|
|
10
|
+
|
|
11
|
+
| Owner | Responsibility |
|
|
12
|
+
|---|---|
|
|
13
|
+
| Core `EvidenceReader`, exported at `@plurnk/plurnk-service/evidence` | Package-owned SQL, stored-packet validation, canonical wire and address projection, canonical request accounting, packet-echo classification and text weight. |
|
|
14
|
+
| `@plurnk/plurnk-digest` | Typed read interface, report selection/grouping, Markdown/JSON/artifacts, consistent snapshots and out-of-band interviews. No dependency on core or its private types. |
|
|
15
|
+
| Composition (CLI, daemon, harness) | Database/output paths and an explicit provider when an interview is requested. |
|
|
16
|
+
|
|
17
|
+
`openEvidence(path)` returns a disposable reader. `rows()` supplies the relational census and
|
|
18
|
+
durable source rows; packet, response and transport bodies are fetched individually. A packet view exposes canonical
|
|
19
|
+
text slots and messages without publishing the stored packet algebra. The reader caches at most
|
|
20
|
+
one packet. No connection or stored statement escapes it. Report failure closes the reader;
|
|
21
|
+
interviews close it before awaiting their provider. Neither migration nor deletion is a read effect.
|
|
22
|
+
|
|
23
|
+
## Artifacts and reports
|
|
24
|
+
|
|
25
|
+
§digest-storage **The digest states the file's health.** Beside the database path it
|
|
26
|
+
reports the file size, the free pages it holds, its `auto_vacuum` mode, and the six
|
|
27
|
+
largest tables and indexes by allocated bytes (`dbstat`), so growth is a number in
|
|
28
|
+
every digest (#764). The digest reads loops as stored, so it tolerates databases
|
|
29
|
+
missing later lifecycle columns.
|
|
30
|
+
|
|
31
|
+
§digest-turn-artifact-identity **Digest packet artifacts project durable turns.**
|
|
32
|
+
After selectors are applied, digest retains every turn with exact content or reasoning source, a
|
|
33
|
+
valid stored provider request, or malformed stored packet evidence; orders those
|
|
34
|
+
turns by durable chronology; and names each by its log coordinate ({§share-packet-names}). The
|
|
35
|
+
producer does not affect projection.
|
|
36
|
+
|
|
37
|
+
§share-packet-names **Packet artifacts carry the coordinate the log uses.** A turn's files are named
|
|
38
|
+
`<worker>-<loop>-<turn>`, the worker's name and the loop and turn sequences that `log:///<loop>/<turn>/…`
|
|
39
|
+
addresses: the model's first turn in its first loop is `<worker>-1-2`, because the initialization
|
|
40
|
+
survey is turn 1 and writes no packet. A digest spanning several workspaces nests each workspace's
|
|
41
|
+
files in a folder named for it; a name that cannot name a file (a workspace named by its path,
|
|
42
|
+
`~/ptl/x`) is slugged for the folder, `ptl-x`, while the digest text keeps the name verbatim, and
|
|
43
|
+
two names that slug alike are told apart by the row's id. `digest.json` records each turn's stem as `artifact`, so no
|
|
44
|
+
consumer reconstructs a name. A name that cannot be a file name, or two turns sharing one, fails.
|
|
45
|
+
|
|
46
|
+
| Artifact | Present when | Authority |
|
|
47
|
+
|----------|--------------|-----------|
|
|
48
|
+
| `<stem>.assistant.md` | The turn has an `ops` source | Exact `turn_sources.content`, independent of log rows |
|
|
49
|
+
| `<stem>.reasoning.md` | The turn has a `reasoning` source | Exact `turn_sources.content`, without relabeling it as content |
|
|
50
|
+
| `<stem>.system.md`, `<stem>.user.md` | The turn stored a provider request | Stored text sections projected through `PacketWire`; native parts are not Markdown |
|
|
51
|
+
| `<stem>.wire.json` | The turn stored a provider request | Reconstructed text-message envelope with its worker's emission rows placed ({§packet-wire-envelope}), not dispatched HTTP bytes. Excludes native payloads, provider controls, and SDK/transport transformations; `<stem>.wire.invalid.json` names a stored log that cannot be projected |
|
|
52
|
+
| `digest.json` turn `attachments` | Every turn | Stored native attachment descriptors; `[]` means a request without attachments, `null` means no valid stored request. Selection is not proof of provider acceptance. |
|
|
53
|
+
| `<stem>.assistantRaw.json` | The request has an admitted provider response | Stored opaque provider response |
|
|
54
|
+
| `<stem>.response.md`, attempt artifacts | The request received no admitted response | Stored request and attempt state |
|
|
55
|
+
| `<stem>.packet.raw.txt` | The stored packet fails typed validation | Exact stored packet text |
|
|
56
|
+
| `<stem>.packet.invalid.json` | The stored packet fails typed validation | Turn identity and complete validation error chain |
|
|
57
|
+
|
|
58
|
+
A source-backed turn without provider participation produces only its source-channel
|
|
59
|
+
artifacts; a request-only turn produces no fabricated assistant. A
|
|
60
|
+
source-less programmatic turn with no provider request has no forensic payload
|
|
61
|
+
to project and writes no files.
|
|
62
|
+
|
|
63
|
+
§share-snapshot **A database is copied by SQLite, never by the filesystem.** `Share.snapshot(dbPath, copy)`, exported as `@plurnk/plurnk-digest` with `Share.write({ openEvidence, dbPath, folder, workspaceId?, requiem? })` (`requiem` is an explicitly supplied provider), is the one consistent copy: a byte copy of a WAL-mode database drops every committed page still in its `-wal` file. A harness that keeps the database beside its digest takes it through `snapshot`; an existing `copy` is refused.
|
|
64
|
+
|
|
65
|
+
§digest-programmatic-surface **The digest is an importable forensic surface.**
|
|
66
|
+
|
|
67
|
+
| Surface | Contract |
|
|
68
|
+
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
69
|
+
| Import `@plurnk/plurnk-digest` | Ships `Digest`, `Share` and typed evidence inputs; importing performs no I/O or process action. Callers invoke it explicitly. |
|
|
70
|
+
| `run({ dbPath, openEvidence })` | Reads the required database and writes a complete digest to `./test/digest` relative to the caller's working directory. |
|
|
71
|
+
| `digestDir` | Selects a nonempty output path. `run` refuses a folder that exists and is not empty, and `requiem` refuses an existing `requiem.json` or `requiem.md`, before database or provider I/O; neither deletes ({§share}). Concurrent callers use distinct folders. |
|
|
72
|
+
| Reader lifetime | `run` reads heavy evidence on demand while rendering, then closes its reader on success or failure. `requiem` closes its reader before awaiting witness inference. |
|
|
73
|
+
| Export completion | Packet and response bodies are read and serialized one record at a time, without discarding evidence. `digest.json` is promoted from a partial file only after every artifact is written; its absence identifies an incomplete export. |
|
|
74
|
+
| `workerId` | Narrows workers and every dependent loop, turn, turn-attached logical inference, specialization, physical request, and log row to that one worker. |
|
|
75
|
+
| `workspaceId` | Narrows workers plus every logical inference and dependent evidence owned by one workspace, when both selectors are present they intersect. |
|
|
76
|
+
|
|
77
|
+
§digest-cost-kind **Cost basis named.** A rendered Cost line carries the basis of its dollar figure: `(charged)` only when every settled request's cost is provider-charged; `(estimated — catalog rates)` when any settled request's cost is an estimate, because a mixed sum is no more trustworthy than its weakest term. A dollar figure without its basis reads as billed truth, and an estimate must never impersonate a charge.
|
|
78
|
+
|
|
79
|
+
§digest-wire-line **Wire health aggregated.** Each worker summary renders a `Wire:` line — total physical provider requests, error-outcome count, and the error percentage when nonzero. Provider-level failures are absorbed by retries below the packet stream, so without this aggregate a rate-limit storm is invisible in every summary while the model's experience stays clean.
|
|
80
|
+
|
|
81
|
+
§digest-cache-ledger **Measured cache reuse and estimated prompt overlap are separate.**
|
|
82
|
+
|
|
83
|
+
| Projection | Meaning |
|
|
84
|
+
|---|---|
|
|
85
|
+
| `digest.json` provider-request `cachedTokens`, `inputTokens` | Exact provider-reported cache reads and input tokens; absent quantities remain `null`, reported zero remains zero. Every physical request counts, including retries and first requests of new loops. Stored packet availability is irrelevant to these counters. |
|
|
86
|
+
| Turn `cache=<cached>/<input>` | Sum each measured quantity over that turn's requests. If any request omits a quantity, that sum is `?`. |
|
|
87
|
+
| Workspace `Cache: <cached> of <input> reported input tokens read from cache (<pct>%) over <n> requests` | Sum only requests reporting both counters. Percentage is cache reads / input, rounded to one decimal; zero input is `n/a`. Requests missing either counter are counted separately as `missing input or cache usage (excluded)`. |
|
|
88
|
+
| `digest.json` provider-request `adjacentPrefixTokensEstimate` | Optional loop-local diagnostic: the longest common character prefix with the preceding request, weighted under {§tokenomics-agnostic-ruler} as a share of the current stored prompt, multiplied by reported input tokens. First request: `0`; missing current/preceding packet or current input: `null`. Empty prompts have zero overlap. |
|
|
89
|
+
|
|
90
|
+
The prefix estimate uses the stored emission packet's wire message order, roles
|
|
91
|
+
and content. A BARE request's input is not that packet; its prefix estimate and
|
|
92
|
+
the following request's comparison are unknown. The estimate is
|
|
93
|
+
neither provider tokenization nor a cache ceiling, and never supplies a cache-ratio
|
|
94
|
+
denominator. Caching across loops or against other provider-resident prefixes
|
|
95
|
+
does not make the measured counters inconsistent.
|
|
96
|
+
|
|
97
|
+
§digest-edit-census **Every model EDIT by the form it authored, how it landed, and whether it came back.** For each worker the digest reads every model-authored EDIT row and classifies the form from the row's stored marker and the durable statement's pattern: `hash` (one anchor), `line` (one line number), `range` (two marks), `insert` (the zero-width `<L,1,L,1>` form, {§zero-width-column-one-insert}), `column` (any other four-mark region), `prepend` / `append` (`<0>` / `<-1>`), `offset` (a tolerated anchor offset, {§anchor-offset}), `pattern` (a selection matcher), `whole` (no marker: a creation when it lands 201). It counts the EDITs, those refused (status ≥ 400), and the *revisits*: an EDIT of a path the same worker had edited within its previous two model turns — the shape of a repair without the claim of one. Each worker summary renders `EDITs: <n> · <form>=<count>… · refused=<k> · revisits=<r>` (`(no edits)` for none); `digest.json` carries the census as `edit_census` on every worker and stamps every EDIT log entry with its `edit_form` and `edit_revisit`. A form is a fact about what was written, never about intent; the bench sheet reads the counts as friction and leaves the judgement to the reader.
|
|
98
|
+
|
|
99
|
+
§digest-forensic-fidelity **Forensic fidelity and cardinality.** The digest's machine-readable JSON preserves every log event with its initial and current projection, causal `source`, and structured `attrs`; every exact log-KILL target effect; the exact Problem on every failed row; each loop's exact terminal result, settlement time, scheduled due time, recurring interval, and recurrence lineage; and every ordered physical provider request. Programs still produce chronological `assistant.md` artifacts after every READ receipt is KILLed; source is independent of log curation. Each worker summary's `Emissions:` line counts its announced emission rows, those the worker KILLed, and the headings it echoed ({§emission-row}); its `Reasonings:` line counts its landed reasoning rows, those the worker KILLed, and the turns that reasoned ({§reasoning-row}); the op mix leaves both harness rows out. Each stored packet validates independently: one malformed historical packet remains exact raw evidence with its complete validation error chain and never prevents healthy turns from being projected. Accounting on broader rows is the shared exact derivation from that ledger, never a second stored fact. A worker's Cost line names how many settled requests carry no usage at all (errored or aborted exchanges) — their server-side spend is unrecorded rather than silently priced as zero. The reasoning chronology distinguishes readable reasoning content from provider-reported reasoning usage: when tokens were reported but no readable content was returned, it states both facts instead of implying that no reasoning occurred. The human Markdown waterfall shows a present causal source and may preview only the Problem detail because it remains a triage projection, not the machine record. Targets reconstruct the model-visible address, including hostname, port, serialized query, and fragment; an authority-bearing URL must never degrade from `https://host/path` to `https:///path`, and durable resource coordinates render back to their authority form. Its human Markdown waterfall groups consecutive identical per-turn op outcomes and typed `entry_materialized` narrations, reporting the exact count and sequence span (`xN (seq A-B)`). Grouping keys include source and the complete target, so distinct causes, authorities, or channels never collapse, and non-consecutive events preserve their chronological order. Thus amplification is conspicuous without making the diagnostic artifact itself pathological; valid packet files remain byte-identical records of what the model saw.
|
|
100
|
+
|
|
101
|
+
Unrecognized actionless log rows are retained and labelled as such, not
|
|
102
|
+
interpreted as executable turnOps or allowed to prevent the remaining digest.
|
|
103
|
+
|
|
104
|
+
§digest-executor-evidence **A red command is work, not a defect.** Engine-materialized
|
|
105
|
+
completion rows for a failed command carry the executor's problem identity
|
|
106
|
+
(`https://problems.plurnk.xyz/executor/*`), and the digest classifies them as
|
|
107
|
+
evidence: they render like any row but never count toward a loop's error total,
|
|
108
|
+
its health verdict, or the per-turn `errs=` badge — a loop that concluded green
|
|
109
|
+
over red test runs is CLEAN, not DEGENERATE-WIN. This is the digest mirror of the
|
|
110
|
+
strike rail's exemption ({§engine-rails}, #425 F1): structural violations count,
|
|
111
|
+
executor evidence never does.
|
|
112
|
+
|
|
113
|
+
§digest-requiem **A requiem is an out-of-band forensic interview, not a worker
|
|
114
|
+
turn.** It cannot execute operations or alter the audited history.
|
|
115
|
+
|
|
116
|
+
| Aspect | Contract |
|
|
117
|
+
|-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|
118
|
+
| Scope | One interview for each worker with model-bearing inference turns; workers without inference evidence are omitted. |
|
|
119
|
+
| Evidence | The worker's final packet plus every attempt's exact normalized response and admission evidence; opaque raw transport remains in durable forensic artifacts. Quoted evidence is budgeted to the witness window ({§digest-requiem-evidence-budget}). |
|
|
120
|
+
| Witness | An explicitly supplied provider; CLI composition may resolve the active configured provider. Absence fails hard; the report package never selects a route. |
|
|
121
|
+
| Identity | The worker's durable provider identity ({§worker-provider-identity}) is sent as the `workerId`, without asserting a live worker topology. |
|
|
122
|
+
| Attempts | One call at `PLURNK_DIGEST_REQUIEM_MAX_TOKENS`; only an empty length-limited response receives one retry at `PLURNK_DIGEST_REQUIEM_RETRY_MAX_TOKENS`. |
|
|
123
|
+
| Artifacts | `requiem.md` carries testimony and exact nullable USD accounting. `requiem.json` is durably materialized before each call and preserves logical call state, messages, normalized responses, every physical request's state and accounting, and their shared aggregate projection. |
|
|
124
|
+
|
|
125
|
+
§digest-requiem-evidence-budget **Quoted evidence fits the witness.** The
|
|
126
|
+
interview's user message is budgeted against the witness provider's context
|
|
127
|
+
window minus the retry output allowance and system framing (chars/2, the
|
|
128
|
+
capacity gate's own estimator). Overflow elides the oldest provider attempts
|
|
129
|
+
behind an explicit `elidedOldestAttempts` count marker, never silently; the
|
|
130
|
+
final packet and the newest attempts always testify. A windowless witness
|
|
131
|
+
(`contextWindow` null) quotes unbudgeted.
|
package/dist/Digest.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import DigestRequiem from "./DigestRequiem.ts";
|
|
2
|
+
import type { DigestOptions } from "./digest-rows.ts";
|
|
3
|
+
export default class Digest {
|
|
4
|
+
#private;
|
|
5
|
+
static requiem(opts: Parameters<typeof DigestRequiem.interview>[0]): ReturnType<typeof DigestRequiem.interview>;
|
|
6
|
+
static run(opts: DigestOptions): void;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=Digest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Digest.d.ts","sourceRoot":"","sources":["../src/Digest.ts"],"names":[],"mappings":"AAKA,OAAO,aAAa,MAAM,oBAAoB,CAAC;AAG/C,OAAO,KAAK,EAUR,aAAa,EAChB,MAAM,kBAAkB,CAAC;AAE1B,MAAM,CAAC,OAAO,OAAO,MAAM;;IAEvB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,SAAS,CAAC,CAE9G;IAED,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAIpC;CA4IJ"}
|
package/dist/Digest.js
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
|
|
2
|
+
if (value !== null && value !== void 0) {
|
|
3
|
+
if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
|
|
4
|
+
var dispose, inner;
|
|
5
|
+
if (async) {
|
|
6
|
+
if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
|
|
7
|
+
dispose = value[Symbol.asyncDispose];
|
|
8
|
+
}
|
|
9
|
+
if (dispose === void 0) {
|
|
10
|
+
if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
|
|
11
|
+
dispose = value[Symbol.dispose];
|
|
12
|
+
if (async) inner = dispose;
|
|
13
|
+
}
|
|
14
|
+
if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
|
|
15
|
+
if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
|
|
16
|
+
env.stack.push({ value: value, dispose: dispose, async: async });
|
|
17
|
+
}
|
|
18
|
+
else if (async) {
|
|
19
|
+
env.stack.push({ async: true });
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
23
|
+
var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
|
|
24
|
+
return function (env) {
|
|
25
|
+
function fail(e) {
|
|
26
|
+
env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
|
|
27
|
+
env.hasError = true;
|
|
28
|
+
}
|
|
29
|
+
var r, s = 0;
|
|
30
|
+
function next() {
|
|
31
|
+
while (r = env.stack.pop()) {
|
|
32
|
+
try {
|
|
33
|
+
if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
|
|
34
|
+
if (r.dispose) {
|
|
35
|
+
var result = r.dispose.call(r.value);
|
|
36
|
+
if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
|
|
37
|
+
}
|
|
38
|
+
else s |= 1;
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
fail(e);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
|
|
45
|
+
if (env.hasError) throw env.error;
|
|
46
|
+
}
|
|
47
|
+
return next();
|
|
48
|
+
};
|
|
49
|
+
})(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
50
|
+
var e = new Error(message);
|
|
51
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
|
+
});
|
|
53
|
+
import { closeSync, existsSync, mkdirSync, openSync, readdirSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
54
|
+
import { join } from "node:path";
|
|
55
|
+
import { trace } from "@opentelemetry/api";
|
|
56
|
+
import { observedSync } from "@plurnk/plurnk-meta";
|
|
57
|
+
import DigestRender from "./DigestRender.js";
|
|
58
|
+
import DigestRequiem from "./DigestRequiem.js";
|
|
59
|
+
import { digestPaths } from "./digest-paths.js";
|
|
60
|
+
export default class Digest {
|
|
61
|
+
// {§digest-requiem} — the out-of-band forensic interview lives in DigestRequiem.
|
|
62
|
+
static requiem(opts) {
|
|
63
|
+
return DigestRequiem.interview(opts);
|
|
64
|
+
}
|
|
65
|
+
static run(opts) {
|
|
66
|
+
// {§observability-boundary} — the evidence write is observed; the digest
|
|
67
|
+
// paths themselves are environment-specific and stay off the boundary.
|
|
68
|
+
observedSync(trace.getTracer("@plurnk/plurnk-digest"), "digest.write", {}, () => { Digest.#runSettled(opts); });
|
|
69
|
+
}
|
|
70
|
+
static #runSettled(opts) {
|
|
71
|
+
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
72
|
+
try {
|
|
73
|
+
// {§digest-programmatic-surface}: refuse the destination before opening evidence.
|
|
74
|
+
const { dbPath, digestDir } = digestPaths(opts);
|
|
75
|
+
// {§share}: the digest never deletes; a caller reusing a folder removes it first.
|
|
76
|
+
if (existsSync(digestDir) && (!statSync(digestDir).isDirectory() || readdirSync(digestDir).length > 0)) {
|
|
77
|
+
throw new Error(`digest: ${digestDir} already exists and is not an empty folder; remove it first`);
|
|
78
|
+
}
|
|
79
|
+
const evidence = __addDisposableResource(env_1, opts.openEvidence(dbPath), false);
|
|
80
|
+
Digest.#write(evidence, dbPath, digestDir, opts);
|
|
81
|
+
}
|
|
82
|
+
catch (e_1) {
|
|
83
|
+
env_1.error = e_1;
|
|
84
|
+
env_1.hasError = true;
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
__disposeResources(env_1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
static #write(evidence, dbPath, digestDir, opts) {
|
|
91
|
+
const rows = evidence.rows();
|
|
92
|
+
let { workspaces, workers, inferenceCalls, modelCalls, turnAttempts, providerRequests, logEntries, editRows, curationEffects, workerRollupRows, opMixRows } = rows;
|
|
93
|
+
const { environmentRows, searchState, derivationState, dispositionCounts, dispositions, storageTables, emissionRows, reasoningRows } = rows;
|
|
94
|
+
let loops = rows.loops.map((loop) => ({ ...loop, claimed_at: loop.claimed_at ?? null }));
|
|
95
|
+
if (rows.storage === undefined)
|
|
96
|
+
throw new Error("digest: the database reported no storage facts");
|
|
97
|
+
const storage = { ...rows.storage, tables: storageTables };
|
|
98
|
+
let turns = rows.turns;
|
|
99
|
+
if (searchState === undefined || derivationState === undefined)
|
|
100
|
+
throw new Error("digest: search aggregate returned no row");
|
|
101
|
+
const dispositionCount = (value) => dispositionCounts.find(({ disposition }) => disposition === value)?.n ?? 0;
|
|
102
|
+
const search = {
|
|
103
|
+
...searchState,
|
|
104
|
+
indexed: dispositionCount("indexed"),
|
|
105
|
+
excluded: dispositionCount("excluded"),
|
|
106
|
+
unsearchable: dispositionCount("unsearchable"),
|
|
107
|
+
failed: dispositionCount("failed"),
|
|
108
|
+
dispositions,
|
|
109
|
+
derivation_artifacts_complete: derivationState.complete,
|
|
110
|
+
derivation_artifacts_building: derivationState.building,
|
|
111
|
+
};
|
|
112
|
+
// {§digest-programmatic-surface} — optional worker/workspace selectors narrow the
|
|
113
|
+
// kept worker graph and its dependent evidence rather than emitting the whole DB.
|
|
114
|
+
if (opts.workerId !== undefined)
|
|
115
|
+
workers = workers.filter((r) => r.id === opts.workerId);
|
|
116
|
+
if (opts.workspaceId !== undefined)
|
|
117
|
+
workers = workers.filter((r) => r.workspace_id === opts.workspaceId);
|
|
118
|
+
if (opts.workerId !== undefined || opts.workspaceId !== undefined) {
|
|
119
|
+
const keptWorkerIds = new Set(workers.map((r) => r.id));
|
|
120
|
+
const keptWorkspaceIds = new Set(workers.map((r) => r.workspace_id));
|
|
121
|
+
workspaces = workspaces.filter((s) => keptWorkspaceIds.has(s.id));
|
|
122
|
+
loops = loops.filter((l) => keptWorkerIds.has(l.worker_id));
|
|
123
|
+
const keptLoopIds = new Set(loops.map((l) => l.id));
|
|
124
|
+
turns = turns.filter((t) => keptLoopIds.has(t.loop_id));
|
|
125
|
+
const keptTurnIds = new Set(turns.map((t) => t.id));
|
|
126
|
+
inferenceCalls = inferenceCalls.filter((call) => keptTurnIds.has(call.turn_id));
|
|
127
|
+
const keptInferenceCallIds = new Set(inferenceCalls.map((call) => call.id));
|
|
128
|
+
modelCalls = modelCalls.filter((call) => keptInferenceCallIds.has(call.id));
|
|
129
|
+
turnAttempts = turnAttempts.filter((attempt) => keptTurnIds.has(attempt.turn_id));
|
|
130
|
+
providerRequests = providerRequests.filter((request) => keptInferenceCallIds.has(request.inference_call_id));
|
|
131
|
+
logEntries = logEntries.filter((le) => keptTurnIds.has(le.turn_id));
|
|
132
|
+
editRows = editRows.filter((row) => keptTurnIds.has(row.turn_id));
|
|
133
|
+
const keptLogEntryIds = new Set(logEntries.map((entry) => entry.id));
|
|
134
|
+
curationEffects = curationEffects.filter((effect) => keptLogEntryIds.has(effect.operation_log_entry_id)
|
|
135
|
+
&& keptLogEntryIds.has(effect.target_log_entry_id));
|
|
136
|
+
workerRollupRows = workerRollupRows.filter((r) => keptWorkerIds.has(r.worker_id));
|
|
137
|
+
opMixRows = opMixRows.filter((o) => keptWorkerIds.has(o.worker_id));
|
|
138
|
+
}
|
|
139
|
+
mkdirSync(digestDir, { recursive: true });
|
|
140
|
+
const workersByWorkspace = new Map();
|
|
141
|
+
for (const r of workers) {
|
|
142
|
+
const arr = workersByWorkspace.get(r.workspace_id) ?? [];
|
|
143
|
+
arr.push(r);
|
|
144
|
+
workersByWorkspace.set(r.workspace_id, arr);
|
|
145
|
+
}
|
|
146
|
+
const loopsByWorker = new Map();
|
|
147
|
+
for (const l of loops) {
|
|
148
|
+
const arr = loopsByWorker.get(l.worker_id) ?? [];
|
|
149
|
+
arr.push(l);
|
|
150
|
+
loopsByWorker.set(l.worker_id, arr);
|
|
151
|
+
}
|
|
152
|
+
const turnsByLoop = new Map();
|
|
153
|
+
for (const t of turns) {
|
|
154
|
+
const arr = turnsByLoop.get(t.loop_id) ?? [];
|
|
155
|
+
arr.push(t);
|
|
156
|
+
turnsByLoop.set(t.loop_id, arr);
|
|
157
|
+
}
|
|
158
|
+
const attemptsByTurn = new Map();
|
|
159
|
+
for (const attempt of turnAttempts) {
|
|
160
|
+
const arr = attemptsByTurn.get(attempt.turn_id) ?? [];
|
|
161
|
+
arr.push(attempt);
|
|
162
|
+
attemptsByTurn.set(attempt.turn_id, arr);
|
|
163
|
+
}
|
|
164
|
+
const requestsByInferenceCall = new Map();
|
|
165
|
+
const requestsByAttempt = new Map();
|
|
166
|
+
const requestsByTurn = new Map();
|
|
167
|
+
const requestsByLoop = new Map();
|
|
168
|
+
const requestsByWorker = new Map();
|
|
169
|
+
const requestsByWorkspace = new Map();
|
|
170
|
+
const appendRequest = (map, id, request) => {
|
|
171
|
+
const rows = map.get(id) ?? [];
|
|
172
|
+
rows.push(request);
|
|
173
|
+
map.set(id, rows);
|
|
174
|
+
};
|
|
175
|
+
for (const request of providerRequests) {
|
|
176
|
+
appendRequest(requestsByInferenceCall, request.inference_call_id, request);
|
|
177
|
+
if (request.turn_attempt_id !== null) {
|
|
178
|
+
appendRequest(requestsByAttempt, request.turn_attempt_id, request);
|
|
179
|
+
}
|
|
180
|
+
if (request.turn_id !== null)
|
|
181
|
+
appendRequest(requestsByTurn, request.turn_id, request);
|
|
182
|
+
if (request.loop_id !== null)
|
|
183
|
+
appendRequest(requestsByLoop, request.loop_id, request);
|
|
184
|
+
if (request.worker_id !== null)
|
|
185
|
+
appendRequest(requestsByWorker, request.worker_id, request);
|
|
186
|
+
appendRequest(requestsByWorkspace, request.workspace_id, request);
|
|
187
|
+
}
|
|
188
|
+
const editRowsByWorker = new Map();
|
|
189
|
+
for (const row of editRows) {
|
|
190
|
+
const arr = editRowsByWorker.get(row.worker_id) ?? [];
|
|
191
|
+
arr.push(row);
|
|
192
|
+
editRowsByWorker.set(row.worker_id, arr);
|
|
193
|
+
}
|
|
194
|
+
const logEntriesByTurn = new Map();
|
|
195
|
+
for (const le of logEntries) {
|
|
196
|
+
const arr = logEntriesByTurn.get(le.turn_id) ?? [];
|
|
197
|
+
arr.push(le);
|
|
198
|
+
logEntriesByTurn.set(le.turn_id, arr);
|
|
199
|
+
}
|
|
200
|
+
const loopsById = new Map(loops.map((l) => [l.id, l]));
|
|
201
|
+
const workersById = new Map(workers.map((r) => [r.id, r]));
|
|
202
|
+
const workerRollups = new Map(workerRollupRows.map((r) => [r.worker_id, r]));
|
|
203
|
+
const environments = new Map(environmentRows.map((row) => [`${row.workspace_id}:${row.stream}`, JSON.parse(row.env)]));
|
|
204
|
+
const emissionsByWorker = new Map();
|
|
205
|
+
for (const row of emissionRows) {
|
|
206
|
+
const map = emissionsByWorker.get(row.worker_id) ?? new Map();
|
|
207
|
+
map.set(row.coordinate, row.content);
|
|
208
|
+
emissionsByWorker.set(row.worker_id, map);
|
|
209
|
+
}
|
|
210
|
+
const opMixByWorker = new Map();
|
|
211
|
+
for (const o of opMixRows) {
|
|
212
|
+
const arr = opMixByWorker.get(o.worker_id) ?? [];
|
|
213
|
+
arr.push(o);
|
|
214
|
+
opMixByWorker.set(o.worker_id, arr);
|
|
215
|
+
}
|
|
216
|
+
const m = {
|
|
217
|
+
evidence,
|
|
218
|
+
dbPath, storage, digestDir, workspaces, workers, loops, turns, inferenceCalls, modelCalls, turnAttempts, providerRequests, logEntries, curationEffects,
|
|
219
|
+
workersByWorkspace, loopsByWorker, turnsByLoop, attemptsByTurn,
|
|
220
|
+
requestsByInferenceCall, requestsByAttempt, requestsByTurn, requestsByLoop, requestsByWorker, requestsByWorkspace,
|
|
221
|
+
logEntriesByTurn, emissionRows, reasoningRows, emissionsByWorker, editRows, editRowsByWorker, environments, loopsById, workersById,
|
|
222
|
+
workerRollups, opMixByWorker, search,
|
|
223
|
+
};
|
|
224
|
+
writeFileSync(join(digestDir, "digest.md"), DigestRender.waterfall(m));
|
|
225
|
+
const pending = join(digestDir, "digest.json.partial");
|
|
226
|
+
const descriptor = openSync(pending, "w");
|
|
227
|
+
try {
|
|
228
|
+
for (const chunk of DigestRender.json(m))
|
|
229
|
+
writeFileSync(descriptor, chunk);
|
|
230
|
+
}
|
|
231
|
+
finally {
|
|
232
|
+
closeSync(descriptor);
|
|
233
|
+
}
|
|
234
|
+
writeFileSync(join(digestDir, "reasoning.md"), DigestRender.reasoning(m));
|
|
235
|
+
const packetFiles = DigestRender.packetFiles(m);
|
|
236
|
+
const packetIds = [...new Set(packetFiles.map((f) => f.slice(0, f.indexOf("."))))];
|
|
237
|
+
renameSync(pending, join(digestDir, "digest.json"));
|
|
238
|
+
console.log(`digest: wrote ${digestDir}/{digest.md,digest.json,reasoning.md} + ${packetFiles.length} packet artifact files (${packetIds.join(", ") || "none"})`);
|
|
239
|
+
console.log(` source: ${dbPath}`);
|
|
240
|
+
console.log(` workspaces=${workspaces.length} workers=${workers.length} loops=${loops.length} turns=${turns.length} inference_calls=${inferenceCalls.length} model_calls=${modelCalls.length} turn_attempts=${turnAttempts.length} provider_requests=${providerRequests.length} log_entries=${logEntries.length} log_curation_effects=${curationEffects.length}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=Digest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Digest.js","sourceRoot":"","sources":["../src/Digest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ProviderAccounting } from "@plurnk/plurnk-providers";
|
|
2
|
+
import type { EditRow, EditForm, DigestModel, CacheLedgerEntry } from "./digest-rows.ts";
|
|
3
|
+
export default class DigestRender {
|
|
4
|
+
#private;
|
|
5
|
+
static parseJson(s: unknown, fallback?: unknown): unknown;
|
|
6
|
+
static usageSummary(accounting: ProviderAccounting | null): string;
|
|
7
|
+
static costSummary(accounting: ProviderAccounting | null): string;
|
|
8
|
+
static envLine(env: unknown): string | null;
|
|
9
|
+
static editForm(row: Pick<EditRow, "line_marker" | "pattern">): EditForm;
|
|
10
|
+
static cacheLedger(m: DigestModel): Map<number, CacheLedgerEntry>;
|
|
11
|
+
static wireLine(assistantRaw: unknown): string | null;
|
|
12
|
+
static waterfall(m: DigestModel): string;
|
|
13
|
+
static reasoning(m: DigestModel): string;
|
|
14
|
+
static packetStems(m: DigestModel): Map<number, string>;
|
|
15
|
+
static packetFiles(m: DigestModel): string[];
|
|
16
|
+
static json(m: DigestModel): Generator<string>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=DigestRender.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DigestRender.d.ts","sourceRoot":"","sources":["../src/DigestRender.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,kBAAkB,EAE1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAMR,OAAO,EAEP,QAAQ,EAER,WAAW,EACX,gBAAgB,EACnB,MAAM,kBAAkB,CAAC;AAQ1B,MAAM,CAAC,OAAO,OAAO,YAAY;;IAY7B,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,GAAE,OAAc,GAAG,OAAO,CAG9D;IAeD,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI,GAAG,MAAM,CAYjE;IAED,MAAM,CAAC,WAAW,CAAC,UAAU,EAAE,kBAAkB,GAAG,IAAI,GAAG,MAAM,CAGhE;IAsCD,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAe1C;IA6HD,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC,GAAG,QAAQ,CAevE;IAyDD,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAuChE;IAqHD,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAiBpD;IA2ED,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CA2EvC;IAED,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAuEvC;IASD,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA6BtD;IAWD,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CAmG3C;IAED,MAAM,CAAE,IAAI,CAAC,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CA6J9C;CACJ"}
|