import type { HarvestRejection, MemoryBackend, MemoryEntry, NotePatch, PatchReport, ScanFinding } from "./types.js";
/** Default per-file byte cap — SAME value as the host engine's MAX_MEMORY_BYTES (独立轨 F3: a 60KB
* entry legal on the host must not be re-rejected every remote round; one cap, one truth). */
export declare const REMOTE_HARVEST_PER_FILE_BYTES: number;
/** Missing-file ratio above which the harvest refuses wholesale (engine MASS_DELETION_FUSE_RATIO). */
export declare const REMOTE_MASS_DELETION_FUSE_RATIO = 0.5;
/** File-count cap per harvest (host DEFAULT_MAX_MEMORY_FILES parity — codex H10). */
export declare const REMOTE_HARVEST_MAX_FILES = 500;
/** Max DIRECTORY nesting depth below the memory root (host DEFAULT_MAX_ENTRY_DEPTH parity — the
* host's `scanEntryFiles` walks a subdir only while `depth + 1 <= maxDepth`, so it counts directory
* levels, NOT path segments: `a/b/c/note.md` (3 dirs) is accepted, `a/b/c/d/note.md` refused). */
export declare const REMOTE_HARVEST_MAX_DEPTH = 3;
export interface RemoteMemoryFile {
/** Path RELATIVE to the sandbox memory root, `/`-separated (e.g. `pref-editor.md`, `org-acme/x.md`). */
relPath: string;
content: string;
}
export interface RemoteMemoryBaseline {
writeScope: string | null;
/** Every file materialized into the sandbox, with its commit-time identity (the CAS base). */
files: Array<{
relPath: string;
id: string;
rev: string;
scope: string;
readonly: boolean;
}>;
/** Directory names of ALL read-only layers — including ZERO-entry ones (复审 D2): the harvest's
* containment prefixes are otherwise inferred from `files`, so an empty inherited layer would be
* invisible and a planted `
/new.md` would slip in as a writeScope add. Optional (additive):
* a baseline serialized before this field keeps the files-inferred prefixes only. */
readonlyDirs?: string[];
}
export interface RemoteMaterialization {
/** Ship these into the sandbox memory root (the deployment owns the transport + any chmod). */
files: Array;
/** Keep this (serializable) and pass it to {@link harvestFilesToPatches} at harvest time. */
baseline: RemoteMemoryBaseline;
}
/**
* Project backend entries into a shippable file list. Layout mirrors the host engine: the
* writeScope's entries sit at the memory root, every other scope under `/`
* (read-only inherited layers). Excluded: budget stubs (a remote v1 materializes full bodies only)
* and the derived MEMORY.md index (the deployment may render its own).
*/
export declare function materializeEntriesToFiles(backend: MemoryBackend, scopes: readonly string[], writeScope: string | null): Promise;
export interface RemoteHarvestResult {
/** Feed to `backend.applyPatches` (the deployment owns the call + the resulting PatchReport). */
patches: NotePatch[];
rejections: HarvestRejection[];
/** Baseline files absent from the read-back set (info; NEVER a delete — tombstones only). */
missing: string[];
/** Set instead of patches when the mass-deletion fuse trips (deployment surfaces it, human call). */
incident?: {
kind: "mass_deletion";
detail: string;
};
/** Canonical projections (minted ids / completed frontmatter) the deployment SHOULD write back into
* the sandbox after the backend commit succeeds, keyed by relPath — same promotion discipline as
* the host engine (project only what applied; see {@link projectionsToWriteBack}). */
projections: Array<{
relPath: string;
entry: MemoryEntry;
content: string;
}>;
}
/**
* The pure gate+diff core over files read back from a remote sandbox. Same judgment order as the
* host engine's harvest: readonly-layer tamper → rejection (restore is the deployment's I/O);
* missing + fuse; per-file size cap → scan rule set (secret/injection/filename) → parse →
* id-immutability (baseline id wins) → tombstone-only delete → CAS update / rename / add.
*/
export declare function harvestFilesToPatches(baseline: RemoteMemoryBaseline, files: readonly RemoteMemoryFile[], opts?: {
perFileBytes?: number;
massDeletionFuseRatio?: number;
maxFiles?: number;
maxDepth?: number;
now?: () => number;
}): RemoteHarvestResult;
/** After `backend.applyPatches(result.patches)`, the projections worth writing back into the sandbox:
* only those whose (id, non-delete op) actually APPLIED — the host engine's promotion discipline. */
export declare function projectionsToWriteBack(result: RemoteHarvestResult, report: PatchReport): Array<{
relPath: string;
content: string;
}>;
export interface InboundEntryFinding {
id: string;
findings: ScanFinding[];
}
/**
* design/142 §3③ — the central-side inbound gate as a PURE function. A sync channel is a write path
* that bypasses the harvest gate by construction (same class as git pull, §2.7): before entries from
* another plane touch an authority disk, screen body + slug + size with the SAME rule set the
* harvest gate runs. Gate logic single-sourced in core; the execution seat rides the data plane
* (service calls this in its write face). Returns findings per OFFENDING entry only — empty array =
* the batch is clean.
*/
export declare function screenInboundEntries(entries: readonly MemoryEntry[], opts?: {
perFileBytes?: number;
}): InboundEntryFinding[];
//# sourceMappingURL=data-plane.d.ts.map