import type { ParsedScopeKey } from "./scope-contract.js"; import type { HarvestReport } from "./types.js"; import type { MemoryInjection } from "./engine.js"; /** The personal plane's shared mount under the config root (ALL projects, one home — the plane is * keyed by scope, not by repo: `user:alice` is the same disk from every checkout). */ export declare function derivePersonalMemoryDir(configRoot: string): string; export declare function derivePersonalControlDir(configRoot: string): string; export interface ScopePlanes { /** proj:/legacy scopes — the repo/path-keyed plane (order preserved). */ project: string[]; /** user:/userproj:/org: scopes — the home-mount plane (order preserved). codex 复审 B1: `org` is * CENTRAL-authority (§2 表), so it routes with the personal keys — under a pinned in-repo File * backend an org layer projected into the repo would leak tenant-shared memory into commit * history. The mount is still the "personal" directory (one home plane; the plane is about * WHERE-NOT-to-project, not about ownership — org's authority disk is the central DB anyway). */ personal: string[]; /** Which plane owns the write face (null = read-only layering everywhere). */ writePlane: "project" | "personal" | null; } /** Classify a v2 session's scopes into planes. writeScope routes by its OWN key kind (it need not * be listed in scopes — normalizeMemorySpec contract). */ export declare function classifyScopePlanes(scopes: readonly string[], writeScope: string | null): ScopePlanes; /** True when the classified session needs the dual-root assembly at all. */ export declare function needsDualRoots(planes: ScopePlanes): boolean; /** Convenience for the placement gate: the parsed keys that stay on the PROJECT plane. */ export declare function parsedProjectPlane(planes: ScopePlanes, writeScope: string | null): ParsedScopeKey[]; /** * Merge the two planes' injections into ONE block. Plane order is fixed: PROJECT first (the stable * prefix — repo knowledge changes less often than personal notes), PERSONAL second; the instruction * (trusted half, "where to write") comes from whichever plane owns the write face and leads the * block, exactly like the single-root layout. v1 deliberately merges at BLOCK granularity — scope * interleaving across planes is not reproduced (documented; the within-plane order is untouched). */ export declare function mergeInjections(project: MemoryInjection | undefined, personal: MemoryInjection | undefined): MemoryInjection; /** Merge the two planes' harvest reports into the single report the runner surfaces. Counters add, * lists concatenate, `ok` ANDs, the first incident wins the seat (both are still visible via the * merged lists). 独立轨 F7: pass the WRITE plane's report as `a` — first-argument fields (incident * seat, degraded seat) prefer `a`, and the write plane's degradation is the one that matters. */ export declare function mergeHarvestReports(a: HarvestReport, b: HarvestReport): HarvestReport; //# sourceMappingURL=dual-root.d.ts.map