/** Per-segment cap, measured AFTER encoding. A conservative portability policy adopted as contract * (research (d) recommendation — NOT a verified third-party hard limit; uuidv7 = 36 chars fits). */ export declare const SCOPE_SEGMENT_MAX_ENCODED = 64; /** * Canonical injective encoding for a raw identifier entering a scope key: everything outside * `[A-Za-z0-9._-]` becomes `%XX` (UTF-8 bytes), INCLUDING `%` itself (that self-encoding is what * makes the map injective — no `__`-style collidable escapes). Throws when the encoded segment * exceeds {@link SCOPE_SEGMENT_MAX_ENCODED} (an over-long principal is a deployment config error) * or when the raw value is empty. */ export declare function encodeScopeSegment(raw: string): string; /** * Inverse of {@link encodeScopeSegment}, CANONICAL-FORM ONLY (codex 复审 B6): the input must be * exactly what the encoder produces — safe chars stay bare (so `%41` for `A` is refused: two * spellings of one identity must not mint two keys), `%XX` sequences must decode as valid UTF-8 * (fatal decoder — no U+FFFD smoothing), and the 64-char cap holds here too (parse side enforces * what the format side promised). */ export declare function decodeScopeSegment(encoded: string): string; export type ParsedScopeKey = { kind: "user"; principal: string; } | { kind: "org"; tenant: string; } | { kind: "proj"; tenant: string; projectId: string; } | { kind: "userproj"; principal: string; projectId: string; } /** No recognized v2 prefix: an opaque legacy scope (fully valid under the v2 contract too). */ | { kind: "legacy"; raw: string; }; export declare function formatUserScope(principal: string): string; export declare function formatOrgScope(tenant: string): string; export declare function formatProjScope(tenant: string, projectId: string): string; export declare function formatUserProjScope(principal: string, projectId: string): string; /** * Parse a scope key under the v2 contract. A key carrying a recognized prefix MUST be well-formed * (fail-loud — a malformed `proj:` key under an explicit opt-in is a config error, not an opaque * scope); anything without a recognized prefix parses as `{ kind: "legacy" }` and keeps today's * opaque behavior. NEVER call this on a deployment that has not opted in (see module header). */ export declare function parseScopeKey(key: string): ParsedScopeKey; /** True when a v2-parsed key belongs to a PERSONAL plane (`user:` / `userproj:`). */ export declare function isPersonalScope(parsed: ParsedScopeKey): boolean; /** True when the key's AUTHORITY is central (design/142 §2 表: user/userproj/org rows) — these keys * must never project into an in-repo memory dir (they would leak to every collaborator AND enter * commit history; codex 复审 B1 extended the F9 gate from personal to org). `proj:`/legacy stay * repo-planed. */ export declare function isCentralAuthorityScope(parsed: ParsedScopeKey): boolean; /** * design/142 §7 S1 hard gate (复审 F9): until S1b per-scope physical roots land, ALL scopes of a * session materialize under ONE root — so a v2 session mixing `user:*`/`userproj:*` keys with an * IN-REPO memory dir would project personal memory into the repo (the exact §2.7 leak shape: * personal notes committed to a shared/open repo). Fail-loud, never fail-open: this throws a * `config.`-coded error the prepare path must NOT swallow. */ export declare function assertScopeContractPlacement(args: { parsedScopes: readonly ParsedScopeKey[]; memoryDir: string; /** The repo/workspace root the session works in (undefined = no repo context, gate passes). */ repoRoot: string | undefined; }): void; /** Repo-root marker file: minted once (by scaffold/deployment, NEVER by the engine), committed, and * from then on the project's identity survives clone/copy/rename/machine/cloud-sandbox. */ export declare const PROJECT_MARKER_PATH = ".sema/project"; /** projectId 格式单源([637]① 承诺):generic UUID,version nibble 不收紧——宽读严写(读面认外部/ * 历史 v4;铸造面 formatProjectMarker / center mint 统一产 uuidv7)。center 侧自持镜像+dev-only * drift 锁对着这条(registry-core coreTypes 先例)。 */ export declare const PROJECT_ID_REGEX: RegExp; /** Serialize a marker file body (scaffold-side helper; the engine itself never writes one). */ export declare function formatProjectMarker(projectId: string): string; /** Parse a marker body: TOML-subset `key = value` lines, `#` comments and blank lines ignored, * optional quotes around the value. Unknown keys are ignored (forward-compatible). codex 复审 H7: * ANY line that starts a `projectId` assignment but is not one canonical UUID assignment is a * CORRUPT marker (fail-loud, `config.memory_project_marker`) — an empty value, an unclosed quote, * a non-UUID, or a DUPLICATE projectId line must never degrade to "no marker" (that would be a * silent identity change back to the path key). Returns null only when NO projectId line exists. */ export declare function parseProjectMarker(body: string): { projectId: string; } | null; /** * design/142 §1.1 — resolve a project's identity. READS ONLY THE MARKER (复审 F2: never derives an * identity from a git remote; remote-URL normalization is a scaffold-side minting heuristic, not an * identity source). v1 scope (复审 F10): ONE marker at the project root — * - inside a git repo, the root is the REPO root; a marker at a nested directory that is not the * repo root is fail-loud (`config.memory_project_marker_nested`) — monorepo sub-project identity * is a future need-signal, not a silent second identity; * - outside git, the given rootDir IS the project root (path-form local projects). * Returns null when no marker exists (callers fall through the resolution ladder: explicit * declaration → path fallback with a warning). */ export declare function resolveProjectId(rootDir: string): { projectId: string; markerDir: string; } | null; //# sourceMappingURL=scope-contract.d.ts.map