// Public type surface for the memory-retrieval layer (Epic #204 / Issue #210).
//
// Pure types + a handful of `Object.freeze`d default-weight tables. No IO, no clock, no
// randomness. All durable timestamps are epoch milliseconds; the caller supplies `nowMs`.
//
// Cross-cutting invariants encoded structurally:
//  1. MemoryQueryPort.listByScope is the SINGLE seam through which records enter this
//     layer. There is no "list all" surface — the port is scope-addressed, so cross-scope
//     leakage requires an explicit second call to a second scope. The orchestrator
//     (retrieve.ts) is the one place that decides which scopes to ask for, and it ONLY
//     iterates `request.scopes`.
//  2. ListByScopeOptions.maxResults bounds the upstream fetch so a misbehaving port can
//     never flood this layer; the orchestrator passes its own bound regardless of caller.
//  3. Every IncludedMemory carries the full subscore breakdown so audit and UI can
//     reconstruct WHY a memory was chosen without re-running the ranker.
//  4. Every OmittedMemory carries one of a closed-set of reasons so audit dashboards can
//     bucket suppressions without parsing free-form strings.
// Defaults are documented at the request-type boundary; this table is the single source of
// truth the orchestrator reads when a field is `undefined` on the request. Frozen so a
// downstream consumer cannot mutate the global default.
export const DEFAULT_RANKING_WEIGHTS = Object.freeze({
    relevance: 0.2,
    recency: 0.2,
    confidence: 0.2,
    pinned: 0.3,
    correction: 0.1,
    graph: 0.15,
    semantic: 0.25,
});
export const DEFAULT_BUDGET_TOKENS = 1500;
export const DEFAULT_MAX_INCLUDED = 12;
export const DEFAULT_STALE_CONFIDENCE_THRESHOLD = 0.3;
export const DEFAULT_LIST_BY_SCOPE_MAX_RESULTS = 500;
