/** 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: 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;
/**
 * THE org-scope judge for a host that admits, stores or routes org keys: is `key` a well-formed v2 org
 * scope — `org:` followed by ONE encoded segment ({@link encodeScopeSegment}'s alphabet, at most
 * {@link SCOPE_SEGMENT_MAX_ENCODED} encoded characters, canonical spelling)? It is {@link parseScopeKey}'s own
 * reading, asked as a yes/no: a malformed `org:` key (an unencoded non-ASCII character, an over-long
 * segment, a non-canonical escape) answers `false` here where `parseScopeKey` would throw, and a key of any
 * other kind (`user:`, `proj:`, an unprefixed opaque string) answers `false` too. A prefix-plus-any-non-space
 * pattern restated outside core answers a different question and disagrees on exactly those inputs.
 */
export declare function isOrgScopeKey(key: string): boolean;
/** 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; 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 格式单源: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).
 *  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;
