/** * JIT layer-2 tools — run-payload store + trajectory. * * Blackboard layout (under TM_BLACKBOARD_DIR, default `/.blackboard/`): * runs/{run_id}/steps/{step_id}/{seq:03d}-{tool}.md full offloaded result * runs/{run_id}/index.jsonl one append per result * entry = { ts, run_id, step_id, seq, tool, ref, file, tokens, * content_type, expire_at, preview } * * Trajectory layout (under TM_TRAJECTORY_DIR, default `/.trajectory/`): * runs/{run_id}/steps.jsonl append-only, one line per event — NO code * path may rewrite, truncate or delete lines; * the TTL sweep of whole expired run dirs is * the sanctioned reclamation path. * runs/{run_id}/usage.jsonl RESERVED for T2.2 (constant below, unused). * * Reclamation philosophy mirrors blackboard.ts: a startup sweep removes run * dirs idle past the TTL — idleness measured across the whole run-dir tree * (file appends must count as activity; only this sweep is destructive). */ /** Reserved for T2.2 usage accounting — path constant only in this phase. */ export declare const USAGE_JSONL_RELPATH = "usage.jsonl"; export interface OffloadMeta { tool: string; content: string; tokens: number; contentType: string; preview: string; expireAt: number; } export interface StoredRef { stepId: string; seq: number; file: string; ref: string; expireAt: number; } export interface IndexEntry { ts: string; run_id: string; step_id: string; seq: number; tool: string; ref: string; file: string; tokens: number; content_type: string; expire_at: number; preview: string; } export interface RunStoreOptions { projectRoot: string; blackboardDir: string; trajectoryDir: string; runId: string; ttlDays: number; } export declare class RunStore { readonly blackboardRoot: string; readonly trajectoryRoot: string; private readonly _runId; private readonly _ttlMs; constructor(opts: RunStoreOptions); get runId(): string; private runDir; stepsRoot(): string; trajectoryFile(): string; /** The offload index for THIS run — every handle this process issued, with * the payload file path and preview (read back by tm_stats' recap). */ indexFile(): string; /** * Write one offloaded result: step file (single write, never rewritten) + * index.jsonl append. Throws on store failures — the caller degrades * (governance failures must not fail the task). */ writeResult(stepId: string, meta: OffloadMeta): StoredRef; /** * Append one trajectory event. Append-only by contract; best-effort * (trajectory failures are swallowed — the blackboard failure path is the * one that degrades upstream). */ appendTrajectory(event: Record): void; /** * Resolve a run directory under THIS store's blackboard root, refusing * anything that could escape it. A handle's ref carries its OWN run id * (tm_fetch verifies the token against that id), so the read path must * accept a foreign run — but only one that stays under `runs/`: `..`, * separators and absolute shapes resolve to null instead of a path. */ private runDirFor; /** Latest index entry for a ref (last append wins), or null. `runId` * defaults to this store's own run; tm_fetch passes the run named in the * handle's ref, so a handle issued before a process restart still finds * its expiry entry. */ findIndexEntry(ref: string, runId?: string): IndexEntry | null; /** Read the offloaded payload file of a step; null when gone/unreadable. * `runId` defaults to this store's own run; tm_fetch passes the run named * in the handle's ref (cross-process retrieval). With multiple seq files * in one step (defensive re-entry), the LATEST seq wins — consistent with * findIndexEntry's last-append-wins. */ readStepFile(stepId: string, runId?: string): { content: string; } | null; /** * Startup-only reclamation: remove run dirs (both stores) whose last tree * activity is older than the TTL. This is the ONLY destructive path in * this module. Returns the number of run dirs removed. Never throws. */ sweepExpired(now?: number): number; } //# sourceMappingURL=store.d.ts.map