import { StorageManager } from './storage.js';
import { MemoryFrontmatter } from './types.js';
import './page-versioning.js';
import './consolidation-operator.js';
import './memory-projection-store-D3vBHS4J.js';
import 'better-sqlite3';

/**
 * Issue #560 PR 3 — Memory Worth outcome signal pipeline.
 *
 * PR 1 added `mw_success` / `mw_fail` fields to MemoryFrontmatter. PR 2 added
 * a pure scoring helper. This module adds the one piece tying the two
 * together: a way for callers to record a single outcome observation against
 * a memory, which increments the appropriate counter in frontmatter.
 *
 * The public entry point is `recordMemoryOutcome({ memoryPath, outcome, ... })`.
 * Callers pass the full path to the memory file (not just the ID) because in
 * the usual outcome source — the observation ledger — the memory path is
 * already captured in the event payload, and path-based lookup avoids a
 * full-corpus scan.
 *
 * Intentional properties:
 *   - Works on a per-memory basis (no bulk API in this slice). Bulk update is
 *     an easy layer on top of this once a second caller needs it.
 *   - Reuses the existing `updateMemoryFrontmatter(id, patch)` write path so
 *     unrelated fields (confidence, importance, lifecycle hooks, etc.) are
 *     preserved. The PR 1 serializer rejects negative / non-integer counters,
 *     so we rely on that for defensive validation rather than duplicating it.
 *   - Only instruments categories in `MEMORY_WORTH_OUTCOME_ELIGIBLE_CATEGORIES`
 *     (currently `fact`, matching `MEMORY_WORTH_ELIGIBLE_CATEGORIES` in
 *     operator-toolkit.ts for the doctor audit). Non-eligible memories return
 *     `{ ok: false, reason: "ineligible_category" }` rather than throwing so
 *     the caller — typically a ledger consumer draining heterogeneous events
 *     — doesn't need to pre-filter by category.
 *   - Missing / unknown memory IDs return `{ ok: false, reason: "not_found" }`
 *     rather than throwing, because outcome events may reference memories
 *     that were archived/deleted between the session and the ledger drain.
 *     That isn't an operator-actionable error.
 *   - On success, returns the new counter values so observability surfaces
 *     can report the increment without a second read.
 *
 * Out of scope (later PRs):
 *   - Recall filter reading the counters (PR 4).
 *   - Benchmark + default flip (PR 5).
 *   - Automatic increments from extraction or summarization. Only the
 *     explicit `MEM_OUTCOME` ledger tag or an MCP tool call drives writes.
 */

/**
 * Exported so downstream tests / operators can query the allowlist without
 * re-declaring it. Returned as a frozen copy so consumers cannot mutate the
 * module-internal set.
 */
declare function memoryWorthOutcomeEligibleCategories(): ReadonlySet<MemoryFrontmatter["category"]>;
/**
 * The direction of an outcome — whether the session that consumed this
 * memory succeeded or failed. Restricted to a string literal union so
 * callers in TypeScript land can't pass arbitrary tags.
 */
type MemoryOutcomeKind = "success" | "failure";
/**
 * Arguments to `recordMemoryOutcome`.
 *
 * `memoryPath` is the filesystem path to the memory; we derive the ID from
 * the basename, matching how the operator-toolkit and recall layers map
 * paths to IDs.
 */
interface RecordMemoryOutcomeInput {
    /**
     * Absolute or repo-relative path to the memory file. Typically the value
     * of `MemoryFile.path` for a memory returned by `readAllMemories`.
     */
    memoryPath: string;
    /** Outcome direction — "success" bumps mw_success; "failure" bumps mw_fail. */
    outcome: MemoryOutcomeKind;
    /**
     * Optional observation timestamp for audit / telemetry. This PR doesn't
     * persist the timestamp (PR 4/5 will use `lastAccessed`, which already
     * covers the recency-decay requirement), but accepting it here keeps the
     * call shape stable so future ledger integrations don't need a breaking
     * change.
     */
    timestamp?: Date | string;
}
/**
 * Outcome of a `recordMemoryOutcome` call.
 *
 * `ok: true` means the counter was incremented and flushed. The returned
 * values reflect the post-increment state, so callers can log
 * `"fact-xyz: 4/1 → 5/1"` without re-reading.
 *
 * `ok: false` carries a short machine-readable `reason` so a ledger drainer
 * can aggregate metrics ("how many events hit not_found this hour?"). The
 * human-readable `message` is a friendlier version for logs.
 */
type RecordMemoryOutcomeResult = {
    ok: true;
    memoryId: string;
    /** New value of `mw_success` after the increment. */
    mw_success: number;
    /** New value of `mw_fail` after the increment. */
    mw_fail: number;
} | {
    ok: false;
    reason: "not_found" | "ineligible_category" | "invalid_outcome" | "invalid_path";
    message: string;
};
/**
 * Record a single outcome observation against a memory. Increments
 * `mw_success` or `mw_fail` on the memory's frontmatter (preserving all
 * other fields) via the existing `updateMemoryFrontmatter` write path.
 *
 * See the top-of-file doc comment for policy details (eligible categories,
 * error semantics, and what is intentionally out of scope).
 */
declare function recordMemoryOutcome(storage: StorageManager, input: RecordMemoryOutcomeInput): Promise<RecordMemoryOutcomeResult>;

export { type MemoryOutcomeKind, type RecordMemoryOutcomeInput, type RecordMemoryOutcomeResult, memoryWorthOutcomeEligibleCategories, recordMemoryOutcome };
