@manyoars/oars 0.2.0 → 0.4.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/README.md +147 -28
- package/dist/api.js +1 -1
- package/dist/bin.js +6 -29
- package/dist/cli.d.ts +10 -4
- package/dist/cli.js +440 -91
- package/dist/commands/keys.d.ts +31 -0
- package/dist/commands/keys.js +65 -0
- package/dist/commands/login.d.ts +1 -1
- package/dist/commands/login.js +3 -3
- package/dist/errors.d.ts +13 -13
- package/dist/errors.js +28 -11
- package/dist/gate/checks.d.ts +68 -0
- package/dist/gate/checks.js +584 -0
- package/dist/gate/command.d.ts +14 -0
- package/dist/gate/command.js +61 -0
- package/dist/gate/hook-fill-main.d.ts +1 -0
- package/dist/gate/hook-fill-main.js +16 -0
- package/dist/gate/hook-fill.d.ts +38 -0
- package/dist/gate/hook-fill.js +94 -0
- package/dist/gate/hook-main.d.ts +1 -0
- package/dist/gate/hook-main.js +47 -0
- package/dist/gate/hook-process.d.ts +24 -0
- package/dist/gate/hook-process.js +112 -0
- package/dist/gate/hook-record.d.ts +3 -0
- package/dist/gate/hook-record.js +8 -0
- package/dist/gate/hook.d.ts +48 -0
- package/dist/gate/hook.js +259 -0
- package/dist/gate/install.d.ts +25 -0
- package/dist/gate/install.js +126 -0
- package/dist/gate/local-bin.d.ts +8 -0
- package/dist/gate/local-bin.js +36 -0
- package/dist/gate/notes.d.ts +19 -0
- package/dist/gate/notes.js +27 -0
- package/dist/gate/novelty.d.ts +35 -0
- package/dist/gate/novelty.js +99 -0
- package/dist/gate/policy.d.ts +25 -0
- package/dist/gate/policy.js +73 -0
- package/dist/gate/record.d.ts +120 -0
- package/dist/gate/record.js +125 -0
- package/dist/gate/registry-state.d.ts +10 -0
- package/dist/gate/registry-state.js +30 -0
- package/dist/gate/registry.d.ts +56 -0
- package/dist/gate/registry.js +94 -0
- package/dist/gate/replay.d.ts +20 -0
- package/dist/gate/replay.js +254 -0
- package/dist/gate/report.d.ts +50 -0
- package/dist/gate/report.js +89 -0
- package/dist/gate/scope.d.ts +7 -0
- package/dist/gate/scope.js +27 -0
- package/dist/gate/transcripts.d.ts +68 -0
- package/dist/gate/transcripts.js +232 -0
- package/dist/hook-bin.d.ts +1 -0
- package/dist/hook-bin.js +50 -0
- package/dist/issuer.d.ts +10 -6
- package/dist/issuer.js +19 -24
- package/dist/main.d.ts +1 -0
- package/dist/main.js +67 -0
- package/dist/oidc.js +1 -1
- package/dist/sessions/actions.d.ts +35 -0
- package/dist/sessions/actions.js +429 -0
- package/dist/sessions/allow.d.ts +23 -0
- package/dist/sessions/allow.js +71 -0
- package/dist/sessions/archive.d.ts +11 -0
- package/dist/sessions/archive.js +38 -0
- package/dist/sessions/audit.d.ts +42 -0
- package/dist/sessions/audit.js +104 -0
- package/dist/sessions/baseline.d.ts +62 -0
- package/dist/sessions/baseline.js +190 -0
- package/dist/sessions/call-shape.d.ts +19 -0
- package/dist/sessions/call-shape.js +85 -0
- package/dist/sessions/capture-runtime.d.ts +10 -0
- package/dist/sessions/capture-runtime.js +12 -0
- package/dist/sessions/cell-increments.d.ts +47 -0
- package/dist/sessions/cell-increments.js +243 -0
- package/dist/sessions/cells.d.ts +109 -0
- package/dist/sessions/cells.js +261 -0
- package/dist/sessions/codex.d.ts +53 -0
- package/dist/sessions/codex.js +745 -0
- package/dist/sessions/command.d.ts +127 -0
- package/dist/sessions/command.js +419 -0
- package/dist/sessions/copilot.d.ts +40 -0
- package/dist/sessions/copilot.js +432 -0
- package/dist/sessions/coverage.d.ts +19 -0
- package/dist/sessions/coverage.js +56 -0
- package/dist/sessions/cursor.d.ts +24 -0
- package/dist/sessions/cursor.js +324 -0
- package/dist/sessions/derive.d.ts +57 -0
- package/dist/sessions/derive.js +386 -0
- package/dist/sessions/exclusion.d.ts +87 -0
- package/dist/sessions/exclusion.js +361 -0
- package/dist/sessions/extract.d.ts +181 -0
- package/dist/sessions/extract.js +1806 -0
- package/dist/sessions/fold.d.ts +17 -0
- package/dist/sessions/fold.js +71 -0
- package/dist/sessions/frame.d.ts +24 -0
- package/dist/sessions/frame.js +95 -0
- package/dist/sessions/gemini.d.ts +37 -0
- package/dist/sessions/gemini.js +613 -0
- package/dist/sessions/gold-arms.d.ts +67 -0
- package/dist/sessions/gold-arms.js +172 -0
- package/dist/sessions/gold.d.ts +197 -0
- package/dist/sessions/gold.js +463 -0
- package/dist/sessions/graph.d.ts +12 -0
- package/dist/sessions/graph.js +34 -0
- package/dist/sessions/grok.d.ts +36 -0
- package/dist/sessions/grok.js +421 -0
- package/dist/sessions/hook-calls.d.ts +3 -0
- package/dist/sessions/hook-calls.js +47 -0
- package/dist/sessions/hook-index.d.ts +66 -0
- package/dist/sessions/hook-index.js +164 -0
- package/dist/sessions/hooks.d.ts +17 -0
- package/dist/sessions/hooks.js +281 -0
- package/dist/sessions/identity.d.ts +27 -0
- package/dist/sessions/identity.js +131 -0
- package/dist/sessions/install.d.ts +70 -0
- package/dist/sessions/install.js +246 -0
- package/dist/sessions/lineage.d.ts +19 -0
- package/dist/sessions/lineage.js +118 -0
- package/dist/sessions/mcp.d.ts +7 -0
- package/dist/sessions/mcp.js +157 -0
- package/dist/sessions/merkle.d.ts +7 -0
- package/dist/sessions/merkle.js +28 -0
- package/dist/sessions/motif.d.ts +44 -0
- package/dist/sessions/motif.js +59 -0
- package/dist/sessions/opencode.d.ts +33 -0
- package/dist/sessions/opencode.js +319 -0
- package/dist/sessions/otel.d.ts +60 -0
- package/dist/sessions/otel.js +494 -0
- package/dist/sessions/package-books.d.ts +48 -0
- package/dist/sessions/package-books.js +120 -0
- package/dist/sessions/package-resolve.d.ts +32 -0
- package/dist/sessions/package-resolve.js +185 -0
- package/dist/sessions/pending.d.ts +34 -0
- package/dist/sessions/pending.js +142 -0
- package/dist/sessions/pi.d.ts +36 -0
- package/dist/sessions/pi.js +353 -0
- package/dist/sessions/pool-books.d.ts +21 -0
- package/dist/sessions/pool-books.js +75 -0
- package/dist/sessions/pool-choices.d.ts +5 -0
- package/dist/sessions/pool-choices.js +11 -0
- package/dist/sessions/pool-command.d.ts +115 -0
- package/dist/sessions/pool-command.js +669 -0
- package/dist/sessions/pool-delta.d.ts +54 -0
- package/dist/sessions/pool-delta.js +190 -0
- package/dist/sessions/pool-nightly-deps.d.ts +3 -0
- package/dist/sessions/pool-nightly-deps.js +11 -0
- package/dist/sessions/pool-nightly.d.ts +10 -0
- package/dist/sessions/pool-nightly.js +85 -0
- package/dist/sessions/pool-outbox.d.ts +76 -0
- package/dist/sessions/pool-outbox.js +313 -0
- package/dist/sessions/pool-print.d.ts +26 -0
- package/dist/sessions/pool-print.js +68 -0
- package/dist/sessions/pool-raw.d.ts +27 -0
- package/dist/sessions/pool-raw.js +68 -0
- package/dist/sessions/pool-replica.d.ts +35 -0
- package/dist/sessions/pool-replica.js +91 -0
- package/dist/sessions/pool-send-lock.d.ts +20 -0
- package/dist/sessions/pool-send-lock.js +87 -0
- package/dist/sessions/pool-sent.d.ts +4 -0
- package/dist/sessions/pool-sent.js +26 -0
- package/dist/sessions/pool-totals.d.ts +10 -0
- package/dist/sessions/pool-totals.js +21 -0
- package/dist/sessions/pool-wire.d.ts +435 -0
- package/dist/sessions/pool-wire.js +1100 -0
- package/dist/sessions/pool.d.ts +32 -0
- package/dist/sessions/pool.js +164 -0
- package/dist/sessions/projection.d.ts +75 -0
- package/dist/sessions/projection.js +165 -0
- package/dist/sessions/public-vocabulary.d.ts +72 -0
- package/dist/sessions/public-vocabulary.js +295 -0
- package/dist/sessions/query.d.ts +123 -0
- package/dist/sessions/query.js +268 -0
- package/dist/sessions/read-adoption.d.ts +2 -0
- package/dist/sessions/read-adoption.js +27 -0
- package/dist/sessions/read-call-shape.d.ts +2 -0
- package/dist/sessions/read-call-shape.js +25 -0
- package/dist/sessions/read-change.d.ts +2 -0
- package/dist/sessions/read-change.js +30 -0
- package/dist/sessions/read-cost.d.ts +4 -0
- package/dist/sessions/read-cost.js +48 -0
- package/dist/sessions/read-day-move.d.ts +3 -0
- package/dist/sessions/read-day-move.js +65 -0
- package/dist/sessions/read-fit.d.ts +7 -0
- package/dist/sessions/read-fit.js +41 -0
- package/dist/sessions/read-interaction.d.ts +5 -0
- package/dist/sessions/read-interaction.js +62 -0
- package/dist/sessions/read-lead-lag.d.ts +15 -0
- package/dist/sessions/read-lead-lag.js +81 -0
- package/dist/sessions/read-live.d.ts +6 -0
- package/dist/sessions/read-live.js +38 -0
- package/dist/sessions/read-method.d.ts +2 -0
- package/dist/sessions/read-method.js +29 -0
- package/dist/sessions/read-next-step.d.ts +2 -0
- package/dist/sessions/read-next-step.js +35 -0
- package/dist/sessions/read-order.d.ts +54 -0
- package/dist/sessions/read-order.js +62 -0
- package/dist/sessions/read-readable.d.ts +8 -0
- package/dist/sessions/read-readable.js +24 -0
- package/dist/sessions/read-recovery-edge.d.ts +2 -0
- package/dist/sessions/read-recovery-edge.js +26 -0
- package/dist/sessions/read-recovery.d.ts +20 -0
- package/dist/sessions/read-recovery.js +97 -0
- package/dist/sessions/read-rows.d.ts +13 -0
- package/dist/sessions/read-rows.js +47 -0
- package/dist/sessions/read-substitution.d.ts +5 -0
- package/dist/sessions/read-substitution.js +51 -0
- package/dist/sessions/read-support.d.ts +48 -0
- package/dist/sessions/read-support.js +73 -0
- package/dist/sessions/read-tool-day.d.ts +2 -0
- package/dist/sessions/read-tool-day.js +26 -0
- package/dist/sessions/read-version-boundary.d.ts +31 -0
- package/dist/sessions/read-version-boundary.js +95 -0
- package/dist/sessions/read.d.ts +86 -0
- package/dist/sessions/read.js +87 -0
- package/dist/sessions/recall-bundle.d.ts +12 -0
- package/dist/sessions/recall-bundle.js +33 -0
- package/dist/sessions/recall-consequence.d.ts +45 -0
- package/dist/sessions/recall-consequence.js +179 -0
- package/dist/sessions/recall-frames.d.ts +18 -0
- package/dist/sessions/recall-frames.js +44 -0
- package/dist/sessions/recall-next.d.ts +145 -0
- package/dist/sessions/recall-next.js +241 -0
- package/dist/sessions/recall-object.d.ts +139 -0
- package/dist/sessions/recall-object.js +78 -0
- package/dist/sessions/recall-pool.d.ts +19 -0
- package/dist/sessions/recall-pool.js +96 -0
- package/dist/sessions/recall-push.d.ts +26 -0
- package/dist/sessions/recall-push.js +47 -0
- package/dist/sessions/recall-reads.d.ts +124 -0
- package/dist/sessions/recall-reads.js +417 -0
- package/dist/sessions/recall-render.d.ts +19 -0
- package/dist/sessions/recall-render.js +168 -0
- package/dist/sessions/recovery-calls.d.ts +21 -0
- package/dist/sessions/recovery-calls.js +25 -0
- package/dist/sessions/redact.d.ts +17 -0
- package/dist/sessions/redact.js +113 -0
- package/dist/sessions/repo-root.d.ts +10 -0
- package/dist/sessions/repo-root.js +101 -0
- package/dist/sessions/schema.d.ts +694 -0
- package/dist/sessions/schema.js +167 -0
- package/dist/sessions/session-shape.d.ts +76 -0
- package/dist/sessions/session-shape.js +355 -0
- package/dist/sessions/sources.d.ts +50 -0
- package/dist/sessions/sources.js +233 -0
- package/dist/sessions/steps.d.ts +105 -0
- package/dist/sessions/steps.js +250 -0
- package/dist/sessions/store.d.ts +309 -0
- package/dist/sessions/store.js +1498 -0
- package/dist/sessions/strata.d.ts +26 -0
- package/dist/sessions/strata.js +77 -0
- package/dist/sessions/survival.d.ts +27 -0
- package/dist/sessions/survival.js +230 -0
- package/dist/sessions/transcript-tail.d.ts +14 -0
- package/dist/sessions/transcript-tail.js +64 -0
- package/dist/sessions/verify.d.ts +53 -0
- package/dist/sessions/verify.js +286 -0
- package/dist/sessions/vocab-load.d.ts +26 -0
- package/dist/sessions/vocab-load.js +61 -0
- package/dist/sessions/vscode-copilot.d.ts +38 -0
- package/dist/sessions/vscode-copilot.js +494 -0
- package/dist/telemetry/command.d.ts +8 -0
- package/dist/telemetry/command.js +85 -0
- package/dist/telemetry/consent.d.ts +17 -0
- package/dist/telemetry/consent.js +63 -0
- package/dist/telemetry/crash.d.ts +8 -0
- package/dist/telemetry/crash.js +52 -0
- package/dist/telemetry/emit.d.ts +31 -0
- package/dist/telemetry/emit.js +42 -0
- package/dist/telemetry/fields.d.ts +16 -0
- package/dist/telemetry/fields.js +26 -0
- package/dist/telemetry/health.d.ts +21 -0
- package/dist/telemetry/health.js +108 -0
- package/dist/telemetry/hook-emit.d.ts +4 -0
- package/dist/telemetry/hook-emit.js +18 -0
- package/dist/telemetry/measures.d.ts +32 -0
- package/dist/telemetry/measures.js +128 -0
- package/dist/telemetry/observe.d.ts +13 -0
- package/dist/telemetry/observe.js +51 -0
- package/dist/telemetry/read-events.d.ts +9 -0
- package/dist/telemetry/read-events.js +17 -0
- package/dist/telemetry/record.d.ts +17 -0
- package/dist/telemetry/record.js +26 -0
- package/dist/telemetry/report.d.ts +77 -0
- package/dist/telemetry/report.js +188 -0
- package/dist/telemetry/schema.d.ts +40 -0
- package/dist/telemetry/schema.js +187 -0
- package/dist/telemetry/send-main.d.ts +1 -0
- package/dist/telemetry/send-main.js +11 -0
- package/dist/telemetry/send.d.ts +36 -0
- package/dist/telemetry/send.js +172 -0
- package/dist/telemetry/spool.d.ts +17 -0
- package/dist/telemetry/spool.js +70 -0
- package/dist/telemetry/wire.d.ts +25 -0
- package/dist/telemetry/wire.js +76 -0
- package/package.json +4 -5
- package/vocab/crates.json +1 -0
- package/vocab/go.json +1 -0
- package/vocab/harness.json +1 -0
- package/vocab/homebrew.json +1 -0
- package/vocab/manifest.json +1 -0
- package/vocab/maven.json +1 -0
- package/vocab/models.json +1 -0
- package/vocab/npm.json +1 -0
- package/vocab/programs.json +1 -0
- package/vocab/pypi.json +1 -0
- package/vocab/rubygems.json +1 -0
- package/dist/commands/deploy-input.d.ts +0 -38
- package/dist/commands/deploy-input.js +0 -150
- package/dist/commands/deploy.d.ts +0 -22
- package/dist/commands/deploy.js +0 -124
- package/dist/commands/status.d.ts +0 -7
- package/dist/commands/status.js +0 -18
- package/dist/commands/templates.d.ts +0 -11
- package/dist/commands/templates.js +0 -32
- package/dist/commands/test-charge.d.ts +0 -11
- package/dist/commands/test-charge.js +0 -34
- package/dist/journal.d.ts +0 -26
- package/dist/journal.js +0 -58
- package/parity/deploy-plans/paid-api.json +0 -34
- package/parity/deploy-plans/per-task-agent.json +0 -34
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import type { Frame } from './schema.js';
|
|
2
|
+
export declare const recallsPath: (storeDir: string) => string;
|
|
3
|
+
/** The share of pushes held back (spec Section 8, open parameter). */
|
|
4
|
+
export declare const HOLDBACK_RATE = 0.1;
|
|
5
|
+
export declare const RECALL_CLASSES: {
|
|
6
|
+
readonly A: readonly ["sid", "at", "query.text"];
|
|
7
|
+
readonly P: readonly ["id", "n", "frame", "mode", "query.form", "query.prefix", "query.entity", "query.family", "query.slice", "poolVersion", "arm", "answer", "evidence", "consequence"];
|
|
8
|
+
};
|
|
9
|
+
export type RecallMode = 'pull' | 'push';
|
|
10
|
+
export type RecallArm = 'shown' | 'held';
|
|
11
|
+
export type RecallForm = 'pattern' | 'entity' | 'question' | 'text';
|
|
12
|
+
/** Which frames a read covers. Each name is held to the public vocabulary before it is shown. */
|
|
13
|
+
export interface RecallSlice {
|
|
14
|
+
harnessVersion?: string;
|
|
15
|
+
model?: string;
|
|
16
|
+
tool?: string;
|
|
17
|
+
cls?: string;
|
|
18
|
+
sinceDays?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface RecallQueryObject {
|
|
21
|
+
form: RecallForm;
|
|
22
|
+
/** What the asker's steps so far name: motif IDs, stored read IDs, or the shape and signature hashes `recall-reads.ts` computes. */
|
|
23
|
+
prefix?: string[];
|
|
24
|
+
/** A public name: package, tool, MCP server, or model. */
|
|
25
|
+
entity?: string;
|
|
26
|
+
family?: string;
|
|
27
|
+
slice?: RecallSlice;
|
|
28
|
+
/** Class A, local only. */
|
|
29
|
+
text?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface RecallAnswer {
|
|
32
|
+
kind: 'hit' | 'miss';
|
|
33
|
+
/** Read IDs, in the order shown. */
|
|
34
|
+
reads: string[];
|
|
35
|
+
/** The size of what was injected, or of what a held recall would have injected. */
|
|
36
|
+
tokens: number;
|
|
37
|
+
/** The UTF-8 bytes of `rendered`: what a hook injected, or would have. Absent on rows written before it was recorded. */
|
|
38
|
+
bytes?: number;
|
|
39
|
+
/** What the asker saw, or for a held recall would have seen. It holds structured fields only (`recall-render.ts`). */
|
|
40
|
+
rendered: string;
|
|
41
|
+
/** The closed names a follow can match: canonical actions, in the order shown. */
|
|
42
|
+
names: string[];
|
|
43
|
+
}
|
|
44
|
+
export type DeltaAxis = 'same' | 'differs' | 'unknown';
|
|
45
|
+
/** How far the evidence sits from the asker, per axis, never collapsed into a score (spec Section 3). */
|
|
46
|
+
export interface RecallDelta {
|
|
47
|
+
harness: DeltaAxis;
|
|
48
|
+
/** The asker's version minus the evidence's newest, when only the last component differs; null when that does not read as a count. */
|
|
49
|
+
harnessVersions: number | null;
|
|
50
|
+
model: DeltaAxis;
|
|
51
|
+
/** How many of the evidence's models are not the asker's; null when the asker's is unknown. */
|
|
52
|
+
modelVersions: number | null;
|
|
53
|
+
platform: DeltaAxis;
|
|
54
|
+
shell: DeltaAxis;
|
|
55
|
+
stack: DeltaAxis;
|
|
56
|
+
/** No record states a tool's version yet. */
|
|
57
|
+
toolVersion: number | null;
|
|
58
|
+
ageDays: number | null;
|
|
59
|
+
}
|
|
60
|
+
export interface FrameRange {
|
|
61
|
+
harnesses: string[];
|
|
62
|
+
harnessVersions: string[];
|
|
63
|
+
models: string[];
|
|
64
|
+
}
|
|
65
|
+
export interface RecallEvidence {
|
|
66
|
+
/** A read, cell, or recall ID. Never another account's session. */
|
|
67
|
+
ref: string;
|
|
68
|
+
frameRange: FrameRange;
|
|
69
|
+
firstDay: string | null;
|
|
70
|
+
lastDay: string | null;
|
|
71
|
+
n: number;
|
|
72
|
+
clusters: number;
|
|
73
|
+
delta: RecallDelta;
|
|
74
|
+
}
|
|
75
|
+
/** The outcome signals of the window's prompt, held separately: no composite (spec Section 2.7). */
|
|
76
|
+
export interface RecallOutcome {
|
|
77
|
+
errors: number | null;
|
|
78
|
+
verify: string | null;
|
|
79
|
+
stopped: string | null;
|
|
80
|
+
commits: number | null;
|
|
81
|
+
redo: boolean | null;
|
|
82
|
+
}
|
|
83
|
+
/** Derived from the capture records, never captured live. */
|
|
84
|
+
export interface RecallConsequence {
|
|
85
|
+
/** The calls the window holds, by position, and why it ended. */
|
|
86
|
+
window: {
|
|
87
|
+
from: number;
|
|
88
|
+
to: number;
|
|
89
|
+
calls: number;
|
|
90
|
+
end: 'prompt' | 'calls' | 'session';
|
|
91
|
+
};
|
|
92
|
+
motifs: string[];
|
|
93
|
+
followed: boolean;
|
|
94
|
+
/** `tokens` is null when no call in the window measured any: an older capture has no step costs, and zero would read as a free window. */
|
|
95
|
+
cost: {
|
|
96
|
+
tokens: number | null;
|
|
97
|
+
durationMs: number;
|
|
98
|
+
};
|
|
99
|
+
outcome: RecallOutcome;
|
|
100
|
+
}
|
|
101
|
+
export interface Recall {
|
|
102
|
+
id: string;
|
|
103
|
+
/** The session the asker ran in; null for a pull made outside one, which no consequence can be read for. Class A. */
|
|
104
|
+
sid: string | null;
|
|
105
|
+
/** Class A. */
|
|
106
|
+
at: string;
|
|
107
|
+
/** The asker's position among its calls. A hook cannot know it without reading the transcript, so derive fills it from `at`. */
|
|
108
|
+
n: number | null;
|
|
109
|
+
frame: Frame | null;
|
|
110
|
+
mode: RecallMode;
|
|
111
|
+
query: RecallQueryObject;
|
|
112
|
+
/** The snapshot answered from: the deposit time of the store or index, so "older than the recall" is a comparison. */
|
|
113
|
+
poolVersion: string;
|
|
114
|
+
arm: RecallArm;
|
|
115
|
+
answer: RecallAnswer;
|
|
116
|
+
evidence: RecallEvidence[];
|
|
117
|
+
consequence?: RecallConsequence;
|
|
118
|
+
}
|
|
119
|
+
export interface RecallInput {
|
|
120
|
+
sid: string | null;
|
|
121
|
+
at: string;
|
|
122
|
+
frame: Frame | null;
|
|
123
|
+
mode: RecallMode;
|
|
124
|
+
query: RecallQueryObject;
|
|
125
|
+
poolVersion: string;
|
|
126
|
+
arm: RecallArm;
|
|
127
|
+
reads: readonly string[];
|
|
128
|
+
rendered: string;
|
|
129
|
+
names: readonly string[];
|
|
130
|
+
evidence: readonly RecallEvidence[];
|
|
131
|
+
}
|
|
132
|
+
export declare const makeRecall: (input: RecallInput) => Recall;
|
|
133
|
+
/** `held` for the hash's first 32 bits under the rate. One session asking from one prefix against one pool always lands on one arm. */
|
|
134
|
+
export declare const armOf: (sid: string, prefix: readonly string[], poolVersion: string, rate?: number) => RecallArm;
|
|
135
|
+
/** Evidence must come from a pool older than the recall (spec Section 3): that one rule is why the commons holds no cycles. */
|
|
136
|
+
export declare const evidencePredates: (recall: Recall) => boolean;
|
|
137
|
+
export declare const appendRecall: (storeDir: string, recall: Recall) => Promise<void>;
|
|
138
|
+
export declare const parseRecalls: (text: string) => Recall[];
|
|
139
|
+
export declare const readRecalls: (storeDir: string) => Promise<Recall[]>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// The recall object (recall spec Section 2.7): one event in the asker's graph, with edges back to the evidence it drew on and forward to what the asker
|
|
2
|
+
// did next. A pull and a push are the same object, and both land in `recalls.jsonl`, append-only, whether or not anything was injected.
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { appendFile, mkdir, readFile } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
const RECALLS_FILE = 'recalls.jsonl';
|
|
7
|
+
export const recallsPath = (storeDir) => join(storeDir, RECALLS_FILE);
|
|
8
|
+
/** The share of pushes held back (spec Section 8, open parameter). */
|
|
9
|
+
export const HOLDBACK_RATE = 0.1;
|
|
10
|
+
export const RECALL_CLASSES = {
|
|
11
|
+
A: ['sid', 'at', 'query.text'],
|
|
12
|
+
P: ['id', 'n', 'frame', 'mode', 'query.form', 'query.prefix', 'query.entity', 'query.family', 'query.slice', 'poolVersion', 'arm', 'answer', 'evidence', 'consequence'],
|
|
13
|
+
};
|
|
14
|
+
/** Characters per token, the rule of thumb: the size is a count for comparing arms, not a bill. */
|
|
15
|
+
const CHARS_PER_TOKEN = 4;
|
|
16
|
+
const hash = (parts) => createHash('sha256').update(JSON.stringify(parts)).digest('hex');
|
|
17
|
+
export const makeRecall = (input) => ({
|
|
18
|
+
id: hash([input.sid, input.at, input.mode, input.query, input.poolVersion]).slice(0, 16),
|
|
19
|
+
sid: input.sid,
|
|
20
|
+
at: input.at,
|
|
21
|
+
n: null,
|
|
22
|
+
frame: input.frame,
|
|
23
|
+
mode: input.mode,
|
|
24
|
+
query: input.query,
|
|
25
|
+
poolVersion: input.poolVersion,
|
|
26
|
+
arm: input.arm,
|
|
27
|
+
answer: {
|
|
28
|
+
kind: input.reads.length === 0 ? 'miss' : 'hit',
|
|
29
|
+
reads: [...input.reads],
|
|
30
|
+
tokens: Math.ceil(input.rendered.length / CHARS_PER_TOKEN),
|
|
31
|
+
bytes: Buffer.byteLength(input.rendered),
|
|
32
|
+
rendered: input.rendered,
|
|
33
|
+
names: [...input.names],
|
|
34
|
+
},
|
|
35
|
+
evidence: [...input.evidence],
|
|
36
|
+
});
|
|
37
|
+
const SCALE = 0x1_0000_0000;
|
|
38
|
+
/** `held` for the hash's first 32 bits under the rate. One session asking from one prefix against one pool always lands on one arm. */
|
|
39
|
+
export const armOf = (sid, prefix, poolVersion, rate = HOLDBACK_RATE) => Number.parseInt(hash([sid, prefix, poolVersion]).slice(0, 8), 16) / SCALE < rate ? 'held' : 'shown';
|
|
40
|
+
/** Evidence must come from a pool older than the recall (spec Section 3): that one rule is why the commons holds no cycles. */
|
|
41
|
+
export const evidencePredates = (recall) => {
|
|
42
|
+
const day = recall.at.slice(0, 10);
|
|
43
|
+
return recall.poolVersion <= recall.at && recall.evidence.every((item) => item.lastDay === null || item.lastDay <= day);
|
|
44
|
+
};
|
|
45
|
+
export const appendRecall = async (storeDir, recall) => {
|
|
46
|
+
await mkdir(storeDir, { recursive: true });
|
|
47
|
+
await appendFile(recallsPath(storeDir), `${JSON.stringify(recall)}\n`, { mode: 0o600 });
|
|
48
|
+
};
|
|
49
|
+
const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
50
|
+
/** The file is ours, so a line's shape is checked only as far as telling a recall from a torn or foreign line. */
|
|
51
|
+
const isRecall = (value) => isRecord(value) && typeof value.id === 'string' && typeof value.at === 'string' && isRecord(value.answer) && isRecord(value.query);
|
|
52
|
+
export const parseRecalls = (text) => {
|
|
53
|
+
const recalls = [];
|
|
54
|
+
for (const line of text.split('\n')) {
|
|
55
|
+
if (line === '')
|
|
56
|
+
continue;
|
|
57
|
+
try {
|
|
58
|
+
const parsed = JSON.parse(line);
|
|
59
|
+
if (isRecall(parsed))
|
|
60
|
+
recalls.push(parsed);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// A torn line is skipped.
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return recalls;
|
|
67
|
+
};
|
|
68
|
+
export const readRecalls = async (storeDir) => {
|
|
69
|
+
let text = '';
|
|
70
|
+
try {
|
|
71
|
+
text = await readFile(recallsPath(storeDir), 'utf8');
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
if (!(error instanceof Error && 'code' in error && error.code === 'ENOENT'))
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
return parseRecalls(text);
|
|
78
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type Pool } from './cells.js';
|
|
2
|
+
import type { Read } from './read.js';
|
|
3
|
+
import type { RecallRead } from './recall-reads.js';
|
|
4
|
+
export interface CurrentPool {
|
|
5
|
+
pool: Pool;
|
|
6
|
+
reads: readonly Read[];
|
|
7
|
+
}
|
|
8
|
+
/** Each answer under its stored read's ID, where the pool holds one. */
|
|
9
|
+
export declare const resolveReads: (reads: readonly RecallRead[], stored: readonly Read[]) => RecallRead[];
|
|
10
|
+
/** The answers to a question about a family only the pool holds, best first. */
|
|
11
|
+
export declare const readsOfFamily: (family: string, current: CurrentPool) => RecallRead[];
|
|
12
|
+
/**
|
|
13
|
+
* What a prefix names in the pool: a stored read by its ID, or a motif by its ID. A stored read with a stand-in goes back through it, because the store's own counts answer those;
|
|
14
|
+
* `standIns` holds those hashes for the caller to match, and `reads` every other answer.
|
|
15
|
+
*/
|
|
16
|
+
export declare const namedByPrefix: (prefix: readonly string[], current: CurrentPool) => {
|
|
17
|
+
standIns: string[];
|
|
18
|
+
reads: RecallRead[];
|
|
19
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// What ties a recall's answer to the stored read of the current pool. A store-wide count answers the asker, and the read it rests on is what `lineage` can
|
|
2
|
+
// walk, so each answer carries that read's ID. Without a stored read for it, an answer keeps its stand-in hash, which `lineage` reports as evidence with no further hop.
|
|
3
|
+
import { bucketFields, cellIdOf, lastDayOfCell, UNKNOWN } from './cells.js';
|
|
4
|
+
import { motifName } from './motif.js';
|
|
5
|
+
/** The stand-in hash a stored read answers for: a recovery read's signature hash and a call-shape read's shape are the values `recall-reads.ts` computes from the store. */
|
|
6
|
+
const standInOf = (read) => {
|
|
7
|
+
if (read.family === 'recovery')
|
|
8
|
+
return read.slice.sig;
|
|
9
|
+
return read.family === 'fit' ? read.slice.shape : undefined;
|
|
10
|
+
};
|
|
11
|
+
const keyOf = (family, standIn) => `${family}/${standIn}`;
|
|
12
|
+
/** Each answer under its stored read's ID, where the pool holds one. */
|
|
13
|
+
export const resolveReads = (reads, stored) => {
|
|
14
|
+
const ids = new Map(stored.flatMap((read) => {
|
|
15
|
+
const standIn = standInOf(read);
|
|
16
|
+
return standIn === undefined ? [] : [[keyOf(read.family, standIn), read.readId]];
|
|
17
|
+
}));
|
|
18
|
+
return reads.map((read) => ({ ...read, readId: ids.get(keyOf(read.family, read.readId)) ?? read.readId }));
|
|
19
|
+
};
|
|
20
|
+
const countIn = (value) => (typeof value === 'number' ? value : 0);
|
|
21
|
+
const nextOf = (read) => {
|
|
22
|
+
const { next } = read.value;
|
|
23
|
+
if (typeof next !== 'object' || next === null)
|
|
24
|
+
return [];
|
|
25
|
+
return Object.entries(next).sort(([a, one], [b, two]) => two - one || a.localeCompare(b));
|
|
26
|
+
};
|
|
27
|
+
const FOLLOWED = 3;
|
|
28
|
+
const presentOf = (values) => [...new Set(values.filter((value) => value !== UNKNOWN && value !== ''))].sort();
|
|
29
|
+
/** A stored read as an answer. Its evidence's frames and days come from the cells it cites; a daily session count cannot be summed, so `n` is the floor those cells prove. */
|
|
30
|
+
const answerOfStored = (read, cells) => {
|
|
31
|
+
const cited = read.inputs.flatMap((input) => cells.get(input) ?? []);
|
|
32
|
+
const frames = cited.map((cell) => bucketFields(cell.frameBucket));
|
|
33
|
+
// `firstDay` over a week cell is that week's Monday: the earliest day the evidence can hold, which the evidence may not have touched.
|
|
34
|
+
const days = presentOf(cited.map((cell) => cell.day));
|
|
35
|
+
// A week cell may hold any of its seven days, so the last day the evidence can hold is the week's end, but never past the pool the read was made from: a read cannot hold a day its pool
|
|
36
|
+
// had not seen, and a recall made on the Wednesday of its evidence's week must not find that evidence dated after itself.
|
|
37
|
+
const lastDays = presentOf(cited.map((cell) => (read.asOf.day !== null && lastDayOfCell(cell) > read.asOf.day ? read.asOf.day : lastDayOfCell(cell))));
|
|
38
|
+
const isRate = read.family === 'fit';
|
|
39
|
+
const failed = countIn(read.value.failed);
|
|
40
|
+
return {
|
|
41
|
+
readId: read.readId,
|
|
42
|
+
family: read.family,
|
|
43
|
+
tool: read.slice.motif ?? read.slice.prefix ?? read.slice.class ?? read.slice.action ?? read.family,
|
|
44
|
+
keys: [],
|
|
45
|
+
n: cited.reduce((highest, cell) => Math.max(highest, cell.sessions), 0),
|
|
46
|
+
count: isRate ? failed : read.n,
|
|
47
|
+
calls: isRate ? failed + countIn(read.value.ok) : null,
|
|
48
|
+
clusters: read.clusters,
|
|
49
|
+
firstDay: days[0] ?? null,
|
|
50
|
+
lastDay: lastDays[lastDays.length - 1] ?? null,
|
|
51
|
+
harnesses: presentOf(frames.map((frame) => frame.harness)),
|
|
52
|
+
harnessVersions: [],
|
|
53
|
+
models: presentOf(frames.map((frame) => frame.model)),
|
|
54
|
+
followed: nextOf(read).slice(0, FOLLOWED),
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/** A pull can answer an agent, and an experimental read goes to no agent (`docs/sessions-store.md`), so a recall never serves one; `oars sessions read` still prints it. */
|
|
58
|
+
const isServed = (read) => read.value.label !== 'experimental';
|
|
59
|
+
const cellsOf = (pool) => new Map(pool.cells.map((cell) => [cellIdOf(cell), cell]));
|
|
60
|
+
const ranked = (reads) => [...reads].sort((a, b) => b.n - a.n || b.count - a.count || a.readId.localeCompare(b.readId));
|
|
61
|
+
/** The answers to a question about a family only the pool holds, best first. */
|
|
62
|
+
export const readsOfFamily = (family, current) => {
|
|
63
|
+
const cells = cellsOf(current.pool);
|
|
64
|
+
return ranked(current.reads.filter((read) => read.family === family && isServed(read)).map((read) => answerOfStored(read, cells)));
|
|
65
|
+
};
|
|
66
|
+
const ofMotif = (motif, reads) => {
|
|
67
|
+
const name = motifName(motif);
|
|
68
|
+
return reads.filter((read) => (read.family === 'fit' && read.slice.motif === name && read.slice.level === motif.level) || (read.family === 'next-step' && motif.level === 'shape' && read.slice.prefix === name));
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* What a prefix names in the pool: a stored read by its ID, or a motif by its ID. A stored read with a stand-in goes back through it, because the store's own counts answer those;
|
|
72
|
+
* `standIns` holds those hashes for the caller to match, and `reads` every other answer.
|
|
73
|
+
*/
|
|
74
|
+
export const namedByPrefix = (prefix, current) => {
|
|
75
|
+
const named = new Set();
|
|
76
|
+
for (const id of prefix) {
|
|
77
|
+
for (const read of current.reads)
|
|
78
|
+
if (read.readId === id && isServed(read))
|
|
79
|
+
named.add(read);
|
|
80
|
+
const motif = current.pool.motifs.get(id);
|
|
81
|
+
if (motif !== undefined)
|
|
82
|
+
for (const read of ofMotif(motif, current.reads))
|
|
83
|
+
named.add(read);
|
|
84
|
+
}
|
|
85
|
+
const cells = cellsOf(current.pool);
|
|
86
|
+
const standIns = [];
|
|
87
|
+
const reads = [];
|
|
88
|
+
for (const read of named) {
|
|
89
|
+
const standIn = standInOf(read);
|
|
90
|
+
if (standIn === undefined)
|
|
91
|
+
reads.push(answerOfStored(read, cells));
|
|
92
|
+
else
|
|
93
|
+
standIns.push(standIn);
|
|
94
|
+
}
|
|
95
|
+
return { standIns, reads: ranked(reads) };
|
|
96
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HookIndex } from './hook-index.js';
|
|
2
|
+
import { type Recall } from './recall-object.js';
|
|
3
|
+
import { type Frame } from './schema.js';
|
|
4
|
+
import { tailOf } from './transcript-tail.js';
|
|
5
|
+
export { tailOf };
|
|
6
|
+
/**
|
|
7
|
+
* The asker's frame, as far as a transcript's tail states it. The stack and the shell need the whole transcript, which a hook has no time to read, so they stay
|
|
8
|
+
* unknown here; `delta` says unknown for them, and derive reads the session's real frame.
|
|
9
|
+
*/
|
|
10
|
+
export declare const frameOfTail: (tail: string, platform: string, at: string) => Frame;
|
|
11
|
+
export interface PushInput {
|
|
12
|
+
storeDir: string;
|
|
13
|
+
sid: string;
|
|
14
|
+
tool: string;
|
|
15
|
+
/** The call's input key names, never their values. */
|
|
16
|
+
keys: readonly string[];
|
|
17
|
+
transcript: string | undefined;
|
|
18
|
+
platform: string;
|
|
19
|
+
at: string;
|
|
20
|
+
index: HookIndex;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* The recall a call about to run gets, written before anything is injected: an exposure with no record is the one failure the arms cannot survive. Undefined when no read
|
|
24
|
+
* covers the shape, which keeps no row (no one asked, so it is not a want, and it would be a row per call), and when this session has already been told about this shape.
|
|
25
|
+
*/
|
|
26
|
+
export declare const pushRecall: (input: PushInput) => Promise<Recall | undefined>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// The push: a pre-tool hook's recall (spec Section 2.7). The harness tells the hook only the call it is about to run, so the query is the call's shape, and a shape
|
|
2
|
+
// with a read over the floors and `PUSH_MIN_LIFT` is the one thing that can arm a push. A held push stores what it would have shown and injects nothing, which is the unexposed baseline.
|
|
3
|
+
import { closedFrame, closedStack, utcDay } from './frame.js';
|
|
4
|
+
import { appendRecall, armOf, makeRecall, parseRecalls, recallsPath } from './recall-object.js';
|
|
5
|
+
import { toolShapeId } from './recall-reads.js';
|
|
6
|
+
import { evidenceOf, renderAnswer } from './recall-render.js';
|
|
7
|
+
import { harnessOf } from './schema.js';
|
|
8
|
+
import { statedOf, tailOf } from './transcript-tail.js';
|
|
9
|
+
export { tailOf };
|
|
10
|
+
/**
|
|
11
|
+
* The asker's frame, as far as a transcript's tail states it. The stack and the shell need the whole transcript, which a hook has no time to read, so they stay
|
|
12
|
+
* unknown here; `delta` says unknown for them, and derive reads the session's real frame.
|
|
13
|
+
*/
|
|
14
|
+
export const frameOfTail = (tail, platform, at) => {
|
|
15
|
+
const { harnessVersion, model, effort } = statedOf(tail);
|
|
16
|
+
return closedFrame({ harness: harnessOf({}), harnessVersion, model, effort, day: utcDay(at), platform, shell: null, stack: closedStack({ languages: [], frameworks: [], size: null }) });
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The recall a call about to run gets, written before anything is injected: an exposure with no record is the one failure the arms cannot survive. Undefined when no read
|
|
20
|
+
* covers the shape, which keeps no row (no one asked, so it is not a want, and it would be a row per call), and when this session has already been told about this shape.
|
|
21
|
+
*/
|
|
22
|
+
export const pushRecall = async (input) => {
|
|
23
|
+
const shape = toolShapeId(input.tool, input.keys);
|
|
24
|
+
const read = input.index.fit?.[shape];
|
|
25
|
+
if (read === undefined)
|
|
26
|
+
return undefined;
|
|
27
|
+
const earlier = parseRecalls(await tailOf(recallsPath(input.storeDir)));
|
|
28
|
+
if (earlier.some((recall) => recall.mode === 'push' && recall.sid === input.sid && recall.query.prefix?.[0] === shape))
|
|
29
|
+
return undefined;
|
|
30
|
+
const frame = frameOfTail(input.transcript === undefined ? '' : await tailOf(input.transcript), input.platform, input.at);
|
|
31
|
+
const { rendered, names } = renderAnswer([read], frame);
|
|
32
|
+
const recall = makeRecall({
|
|
33
|
+
sid: input.sid,
|
|
34
|
+
at: input.at,
|
|
35
|
+
frame,
|
|
36
|
+
mode: 'push',
|
|
37
|
+
query: { form: 'pattern', prefix: [shape] },
|
|
38
|
+
poolVersion: input.index.at,
|
|
39
|
+
arm: armOf(input.sid, [shape], input.index.at),
|
|
40
|
+
reads: [read.readId],
|
|
41
|
+
rendered,
|
|
42
|
+
names,
|
|
43
|
+
evidence: [evidenceOf(read, frame)],
|
|
44
|
+
});
|
|
45
|
+
await appendRecall(input.storeDir, recall);
|
|
46
|
+
return recall;
|
|
47
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { type CanonicalAction } from './actions.js';
|
|
2
|
+
import { type RecallQuery, type RecallResult } from './query.js';
|
|
3
|
+
import { type Family } from './read.js';
|
|
4
|
+
import { type CurrentPool } from './recall-pool.js';
|
|
5
|
+
import { type Recall, type RecallForm, type RecallSlice } from './recall-object.js';
|
|
6
|
+
import { type ErrorObservation, type Frame, type ToolObservation } from './schema.js';
|
|
7
|
+
import type { Store } from './store.js';
|
|
8
|
+
export type ReadFamily = Family | 'entity';
|
|
9
|
+
export interface RecallRead {
|
|
10
|
+
readId: string;
|
|
11
|
+
family: ReadFamily;
|
|
12
|
+
/** The native tool name, as recorded. A renderer holds it to the public vocabulary, because a name can carry text. */
|
|
13
|
+
tool: string;
|
|
14
|
+
/** The call's input key names; empty for a read not about a call shape. */
|
|
15
|
+
keys: string[];
|
|
16
|
+
/** Sessions. */
|
|
17
|
+
n: number;
|
|
18
|
+
/** Errors, for recovery and fit; calls, for entity. */
|
|
19
|
+
count: number;
|
|
20
|
+
/** All calls of the shape, the denominator of `count`; null when the read has none. */
|
|
21
|
+
calls: number | null;
|
|
22
|
+
/** One operator's store is one cluster (spec Section 6). */
|
|
23
|
+
clusters: number;
|
|
24
|
+
firstDay: string | null;
|
|
25
|
+
lastDay: string | null;
|
|
26
|
+
harnesses: string[];
|
|
27
|
+
harnessVersions: string[];
|
|
28
|
+
models: string[];
|
|
29
|
+
/** Native tool names that came next, most common first. */
|
|
30
|
+
followed: Array<[string, number]>;
|
|
31
|
+
}
|
|
32
|
+
/** A signature's stand-in: the hash a stored recovery read holds as `slice.sig`. */
|
|
33
|
+
export declare const readIdOf: (sig: string) => string;
|
|
34
|
+
/** The ID of a call's shape: its tool and input key names, nothing the caller typed as a value. */
|
|
35
|
+
export declare const toolShapeId: (tool: string, keys: readonly string[]) => string;
|
|
36
|
+
export declare const recoveryReads: (store: Store, keep?: (error: ErrorObservation) => boolean) => RecallRead[];
|
|
37
|
+
/** The main-line calls of each session, one row per call, in call order. */
|
|
38
|
+
export declare const callsBySession: (store: Store) => Map<string, ToolObservation[]>;
|
|
39
|
+
export interface FitFloors {
|
|
40
|
+
minFailedSessions: number;
|
|
41
|
+
minFailedShare: number;
|
|
42
|
+
minCalls: number;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The floors a call shape needs before it is pushed. On the operator's store (6,264 sessions, 361,914 calls) they keep 14 shapes, among them the wrong-input
|
|
46
|
+
* calls that always fail (`Monitor` with `query`, `Read` with `path`), and leave Bash, whose failures do not depend on its shape. Open parameters.
|
|
47
|
+
*/
|
|
48
|
+
export declare const FIT_FLOORS: FitFloors;
|
|
49
|
+
/**
|
|
50
|
+
* The floors the pre-tool push holds a shape to (t926). The pre-tool hook fires after the call is decided, so a push is a warning or nothing: a shape that fails less than half
|
|
51
|
+
* its calls is a base rate (the two broad shell shapes, `Bash` and `PowerShell` with a command, fail about a third of theirs whatever the command) and warning on it tells the
|
|
52
|
+
* agent nothing it can act on. A shape that fails at least half its calls is a defect of the call itself (`Monitor` with `query`, `Read` with `path`). Pulls and the pool keep
|
|
53
|
+
* `FIT_FLOORS`: a base rate is still a fact to read on request.
|
|
54
|
+
*/
|
|
55
|
+
export declare const PUSH_FLOORS: FitFloors;
|
|
56
|
+
/** `keep` narrows which calls are tallied, not what can come next: the call after a kept one is what followed it, wherever the slice ends. */
|
|
57
|
+
export declare const fitReads: (store: Store, floors?: FitFloors, keep?: (call: ToolObservation) => boolean) => RecallRead[];
|
|
58
|
+
/** The action of a tool under the first of its harnesses whose table lists it, else under the first harness (the default one when a read names none). */
|
|
59
|
+
export declare const actionOfShape: (tool: string, harnesses: readonly string[]) => CanonicalAction;
|
|
60
|
+
/**
|
|
61
|
+
* What a push must beat: a shape is pushed only when its failure share is at least this many times the share of all calls of its action. The floors above keep
|
|
62
|
+
* a shape that fails often; this keeps one that fails more often than its action does, and guards a store whose base rate is high. On the replay of 2026-11-02 it kept
|
|
63
|
+
* 79 of 79 pushes, at 4.5x and 8.6x their action's share: a real signal, not a defect. Open parameter, like the floors.
|
|
64
|
+
*/
|
|
65
|
+
export declare const PUSH_MIN_LIFT = 2;
|
|
66
|
+
/**
|
|
67
|
+
* The reads whose shape fails at `lift` times the share of its whole action or more, where the action's share counts every call of every shape of it, those under the floors too.
|
|
68
|
+
* A tool no table lists is the action `other` (or `mcp.call`), so it is held to that action's share like any other and can enter the index and fire. Compared in integers, so a tie is exact.
|
|
69
|
+
*/
|
|
70
|
+
export declare const aboveBaseRate: (store: Store, reads: readonly RecallRead[], lift?: number) => RecallRead[];
|
|
71
|
+
/** The snapshot a store answers from: its latest deposit. A deposit time compares with a recall's `at`, which is what "older than the recall" needs. */
|
|
72
|
+
export declare const poolVersionOf: (store: Store) => string;
|
|
73
|
+
export interface ClosedQuery {
|
|
74
|
+
form: RecallForm;
|
|
75
|
+
prefix?: readonly string[];
|
|
76
|
+
entity?: string;
|
|
77
|
+
family?: string;
|
|
78
|
+
slice?: RecallSlice;
|
|
79
|
+
text?: string;
|
|
80
|
+
}
|
|
81
|
+
export type PullInput = ClosedQuery | RecallQuery;
|
|
82
|
+
/** The closed form a command line asks for; undefined when it names none, and only `recall()`'s inputs are left. */
|
|
83
|
+
export declare const closedQueryOf: (options: {
|
|
84
|
+
pattern: readonly string[];
|
|
85
|
+
entity?: string | undefined;
|
|
86
|
+
family?: string | undefined;
|
|
87
|
+
text?: string | undefined;
|
|
88
|
+
cls?: string | undefined;
|
|
89
|
+
sinceDays?: number | undefined;
|
|
90
|
+
}) => ClosedQuery | undefined;
|
|
91
|
+
/** The reads a query's form asks for, best first, over the local store: an empty list is a miss, which a recall keeps. */
|
|
92
|
+
export declare const answerQuery: (store: Store, input: ClosedQuery, now: number, current?: CurrentPool) => RecallRead[];
|
|
93
|
+
/** The families a question can answer. `lead-lag` is experimental, so it stays with `oars sessions read`. */
|
|
94
|
+
export declare const RECALL_FAMILIES: readonly Family[];
|
|
95
|
+
/**
|
|
96
|
+
* Why this pull cannot be asked; undefined when it can. Only `recovery` and `fit` count their answers from the store's own rows, so any other closed form or family cannot apply a
|
|
97
|
+
* slice, and answering them anyway would state counts the slice did not narrow. The text names a form or a family that has passed `isFamily`, so it holds nothing an asker typed.
|
|
98
|
+
*/
|
|
99
|
+
export declare const pullRefusal: (input: PullInput) => string | undefined;
|
|
100
|
+
/** The forms a pull can name, in the order a refusal lists them. `error` with `path` is one form: the signature lookup. */
|
|
101
|
+
export declare const FORM_NAMES: readonly ["prefix", "entity", "family", "text", "error or path"];
|
|
102
|
+
/**
|
|
103
|
+
* Why a pull naming several forms cannot be asked; undefined when it names at most one. Answering the first form and dropping the rest would state counts for a question the asker did
|
|
104
|
+
* not put, and the rendered answer names no signature to show it. The text lists fixed form names, so it holds nothing an asker typed.
|
|
105
|
+
*/
|
|
106
|
+
export declare const formsRefusal: (named: readonly (typeof FORM_NAMES)[number][]) => string | undefined;
|
|
107
|
+
export interface PullContext {
|
|
108
|
+
/** The session asking; null when the pull came from outside one, which is every pull until the MCP path can name it. */
|
|
109
|
+
sid: string | null;
|
|
110
|
+
now: number;
|
|
111
|
+
/** The asker's frame, when the caller knows it; otherwise `sid` may name a stored session, whose frame stands in. */
|
|
112
|
+
frame: Frame | null;
|
|
113
|
+
redactDomains?: readonly string[];
|
|
114
|
+
/** The pool an answer's stored read comes from; without one, an answer keeps its stand-in hash. */
|
|
115
|
+
current?: CurrentPool | undefined;
|
|
116
|
+
}
|
|
117
|
+
export interface PullResult {
|
|
118
|
+
recall: Recall;
|
|
119
|
+
reads: RecallRead[];
|
|
120
|
+
/** What `recall()` found, when the pull came through its `error`, `path`, or `cls` inputs. */
|
|
121
|
+
legacy?: RecallResult;
|
|
122
|
+
}
|
|
123
|
+
/** A pull always answers (spec 2.7): the holdback runs on pushes alone. */
|
|
124
|
+
export declare const pull: (store: Store, input: PullInput, context: PullContext) => PullResult;
|