@mnemom/mnemom 0.17.7-next.2 → 0.17.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -294,44 +294,22 @@ export declare const CONTEXT_TAIL_BUDGET_KEY = "CONTEXT_RUNTIME_TAIL_BUDGET_TOKE
294
294
  export declare const CONTEXT_READ_CACHE_KEY = "CONTEXT_RUNTIME_READ_CACHE_TOKENS";
295
295
  export declare const CONTEXT_HEAD_RECLAIM_KEY = "CONTEXT_RUNTIME_HEAD_BREAKPOINT_RECLAIM";
296
296
  /**
297
- * The gateway key that turns the size-banded fold policy on or off (allow-listed per session).
298
- * Only the literal `banded` enables it; any other value — the profiles send `off` — disables it,
299
- * and a session's value replaces the cell's own. The band thresholds and budgets stay at the
300
- * gateway's own defaults.
297
+ * The gateway key the `adaptive` context profile sets (allow-listed per session): turns on the
298
+ * size-banded fold policy. Only the literal `banded` enables it; the band thresholds and budgets
299
+ * stay at the gateway's own defaults.
301
300
  */
302
301
  export declare const CONTEXT_SIZE_POLICY_KEY = "CONTEXT_RUNTIME_SIZE_POLICY";
303
- /**
304
- * The two gateway env keys the `compaction_intercept` setting turns on for a single session
305
- * (payload-bound fix; both default OFF on the gateway, both read from the per-session overlay):
306
- * - `GATEWAY_USAGE_REAL_SIZE` — report the size of the body the client actually sent (the
307
- * REAL, unfolded context) in the last `usage.iterations` entry, so Claude Code's own
308
- * auto-compact threshold (its 1M default, or the user's `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` /
309
- * `CLAUDE_CODE_AUTO_COMPACT_WINDOW` / `autoCompactWindow`) fires as it would without the fold;
310
- * - `GATEWAY_COMPACTION_INTERCEPT` — answer the client's compaction request at once from the
311
- * gateway's own fold digest (no model call), so the compaction never blocks the user.
312
- * Sent together, value `"on"`, when the `compaction_intercept` setting is on
313
- * (`resolveCompactionIntercept`) OR when `--compact-at` arms a target below 1M (below) — a
314
- * target cannot be honored without both. The `off` context profile sends both as `"off"`.
315
- */
316
- export declare const USAGE_REAL_SIZE_KEY = "GATEWAY_USAGE_REAL_SIZE";
317
- export declare const COMPACTION_INTERCEPT_KEY = "GATEWAY_COMPACTION_INTERCEPT";
318
302
  /**
319
303
  * The named presets for how the gateway folds a session's context (`--context-profile`,
320
- * launcher.toml `context_profile`, `MNEMOM_AGENT_CONTEXT_PROFILE`). Choosing NONE sends no fold
321
- * key at all and the cell's own default decides (see `resolveContextProfile`). A chosen profile
322
- * is complete on its own, so a change to a cell's default can never change what it means:
323
- * - `off` → `CONTEXT_RUNTIME_ENABLED: "false"` plus `GATEWAY_USAGE_REAL_SIZE: "off"` and
324
- * `GATEWAY_COMPACTION_INTERCEPT: "off"` — compaction is left to the coding agent
325
- * and never intercepted, even on a cell whose default turns the intercept on.
326
- * The gateway already skips the intercept with the fold off, but the real-size
327
- * usage rewrite is not gated on the fold, so `off` turns both off by name.
328
- * - `balanced` → `CONTEXT_RUNTIME_SIZE_POLICY: "off"` — the cell's own fold budgets, never
329
- * the size bands, even on a cell whose default is adaptive.
330
- * - `aggressive` → a smaller tail budget + read cache and head-breakpoint reclaim on, size
331
- * policy off: folds earlier and keeps a tighter working set at every size.
304
+ * launcher.toml `context_profile`, `MNEMOM_AGENT_CONTEXT_PROFILE`):
305
+ * - `off` → `CONTEXT_RUNTIME_ENABLED: "false"` — compaction is left to the coding agent
306
+ * (the same bytes `--no-context` has always sent).
307
+ * - `balanced` → NO fold keys: the gateway's own defaults stand. The default.
308
+ * - `aggressive` → a smaller tail budget + read cache and head-breakpoint reclaim on: folds
309
+ * earlier and keeps a tighter working set.
332
310
  * - `adaptive` → `CONTEXT_RUNTIME_SIZE_POLICY: "banded"` — the gateway picks the fold by the
333
311
  * conversation's original size: no fold below 200k tokens, the aggressive
334
- * budgets from 200k to 1M, balanced above.
312
+ * budgets from 200k to 1M, balanced above. Opt-in; never the default.
335
313
  */
336
314
  export declare const CONTEXT_PROFILES: readonly ["off", "balanced", "aggressive", "adaptive"];
337
315
  export type ContextProfile = (typeof CONTEXT_PROFILES)[number];
@@ -344,6 +322,21 @@ export type ContextProfile = (typeof CONTEXT_PROFILES)[number];
344
322
  * header without the tool.
345
323
  */
346
324
  export declare const CONTEXT_HANDOFF_KEY = "CONTEXT_HANDOFF_ENABLED";
325
+ /**
326
+ * The two gateway env keys the `compaction_intercept` setting turns on for a single session
327
+ * (payload-bound fix; both default OFF on the gateway, both read from the per-session overlay):
328
+ * - `GATEWAY_USAGE_REAL_SIZE` — report the size of the body the client actually sent (the
329
+ * REAL, unfolded context) in the last `usage.iterations` entry, so Claude Code's own
330
+ * auto-compact threshold (its 1M default, or the user's `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` /
331
+ * `CLAUDE_CODE_AUTO_COMPACT_WINDOW` / `autoCompactWindow`) fires as it would without the fold;
332
+ * - `GATEWAY_COMPACTION_INTERCEPT` — answer the client's compaction request at once from the
333
+ * gateway's own fold digest (no model call), so the compaction never blocks the user.
334
+ * Sent together, value `"on"`, when the `compaction_intercept` setting is on
335
+ * (`resolveCompactionIntercept`) OR when `--compact-at` arms a target below 1M (below) — a
336
+ * target cannot be honored without both.
337
+ */
338
+ export declare const USAGE_REAL_SIZE_KEY = "GATEWAY_USAGE_REAL_SIZE";
339
+ export declare const COMPACTION_INTERCEPT_KEY = "GATEWAY_COMPACTION_INTERCEPT";
347
340
  export declare const GATEWAY_COMPACTION_UPLOAD_TARGET_KEY = "GATEWAY_COMPACTION_UPLOAD_TARGET_TOKENS";
348
341
  /** The lowest token count `--compact-at` / `compact_at` / `MNEMOM_COMPACT_AT` will accept. */
349
342
  export declare const COMPACT_AT_MIN_TOKENS = 50000;
@@ -419,19 +412,6 @@ export declare function assertCompactAtCompatible(opts: {
419
412
  compactionIntercept?: boolean;
420
413
  compactAt: number | null;
421
414
  }): void;
422
- /**
423
- * The `off` context profile turns the fold off, and the compaction intercept answers a compaction
424
- * from that fold, so `off` sends the intercept and real-size keys as `"off"`. An explicit
425
- * `--compaction-intercept` or `--compact-at <N>` in the same launch asks for the opposite —
426
- * refuse rather than silently drop the flag. A standing intercept or target (environment or
427
- * launcher.toml) is not refused: the session's `off` wins and `buildSessionConfig` leaves it out.
428
- * `compactionIntercept` / `compactAt` here are the raw flag values (`undefined` when not passed).
429
- */
430
- export declare function assertOffProfileCompatible(opts: {
431
- profile: ContextProfile | null;
432
- compactionIntercept?: boolean;
433
- compactAt?: number | null;
434
- }): void;
435
415
  /** The launch-banner line for the resolved compaction target (always printed). */
436
416
  export declare function describeCompactAt(compactAt: number | null): string;
437
417
  /**
@@ -491,10 +471,8 @@ export declare function launchPreferenceExplicit(opts: {
491
471
  * Has an orchestrator already run the session + µ-balance preflight for this
492
472
  * launch? `MNEMOM_AGENT_PREFLIGHTED=1` is for orchestrators (the ADW fleet) that
493
473
  * checked sign-in and balance themselves before spawning many launches; it skips
494
- * the per-launch session prompt and balance round trips. The launch org still
495
- * resolves as on a normal launch (active org, else personal org — the launch's
496
- * Mnemom key is minted for it), and the Mnemom Agent entitlement (which also
497
- * gates Remote Control, fail-closed) is still fetched for it.
474
+ * the per-launch session/personal-org/balance round trips. The Mnemom Agent
475
+ * entitlement (which also gates Remote Control, fail-closed) is still fetched.
498
476
  * Only the exact value `1` counts — anything else, including `true` or ` 1`, is
499
477
  * a normal launch.
500
478
  */
@@ -543,11 +521,7 @@ export declare function resolveRemoteControlShape(args: {
543
521
  export declare function buildCustomHeaders(opts: {
544
522
  /** Absent on a subscription-login launch: Claude Code then sends its own claude.ai login. */
545
523
  anthropicKey?: string;
546
- /**
547
- * The Mnemom key every `mnemom agent` launch sends (lib/subscription-login.ts
548
- * resolveLaunchMnemomKey) — the gateway refuses the session without it, and on a subscription
549
- * login it is also the governed-identity anchor.
550
- */
524
+ /** The governed-identity anchor on a subscription-login launch (lib/subscription-login.ts). */
551
525
  mnemomKey?: string;
552
526
  agent: string;
553
527
  conversationId: string;
@@ -576,45 +550,36 @@ export declare function resolveContextFold(opts: {
576
550
  */
577
551
  export declare function parseContextProfile(raw: string, source: string): ContextProfile;
578
552
  /**
579
- * Which context profile this launch runs under, or `null` when none was chosen anywhere — then
580
- * no fold key is sent and the cell's own default decides. Precedence, highest wins:
553
+ * Which context profile this launch runs under. Precedence, highest wins:
581
554
  * 1. `--no-context` — always `off`. Combined with an explicit `--context-profile
582
555
  * balanced|aggressive|adaptive` it is a CONFLICT and the launch refuses (never a silent override);
583
556
  * `--context-profile off` agrees with it.
584
557
  * 2. an explicit `--context-profile <profile>` flag (`--context` alongside it is fine — the
585
558
  * profile wins);
586
- * 3. `resumed`: the profile the session this launch resumes ran under (from the session
587
- * ledger), so a resume keeps that session's own choice over the saved default;
588
- * 4. `MNEMOM_AGENT_CONTEXT_PROFILE` (which `applyConfigToEnv` sets from the `context_profile`
559
+ * 3. `MNEMOM_AGENT_CONTEXT_PROFILE` (which `applyConfigToEnv` sets from the `context_profile`
589
560
  * config key) — an invalid value is an error, never a silent default;
590
- * 5. the folding boolean when NO profile is set anywhere: `context = false` in launcher.toml
561
+ * 4. the folding boolean when NO profile is set anywhere: `context = false` in launcher.toml
591
562
  * (→ `MNEMOM_AGENT_CONTEXT`, see `resolveContextFold`) means `off`;
592
- * 6. `null` — unset, the cell default.
563
+ * 5. `balanced` (the default).
593
564
  */
594
565
  export declare function resolveContextProfile(opts: {
595
566
  contextProfile?: ContextProfile;
596
567
  context?: boolean;
597
- resumed?: ContextProfile | null;
598
568
  env?: NodeJS.ProcessEnv;
599
- }): ContextProfile | null;
569
+ }): ContextProfile;
600
570
  /**
601
571
  * The decoded per-session env overlay for this launch — the `config` object of the
602
572
  * `x-mnemom-session-config` payload, in wire order: the profile's keys first
603
- * (`CONTEXT_RUNTIME_ENABLED: "false"` + real-size and intercept `"off"` for `off`; the three fold-tuning keys + size policy off for
604
- * `aggressive`; size policy off for `balanced`; size policy banded for `adaptive`; nothing when
605
- * no profile was chosen), then `CONTEXT_HANDOFF_ENABLED: "true"` when context handoff is ON, then
573
+ * (`CONTEXT_RUNTIME_ENABLED` for `off`; the three fold-tuning keys for `aggressive`;
574
+ * `CONTEXT_RUNTIME_SIZE_POLICY` for `adaptive`; nothing for `balanced`), then `CONTEXT_HANDOFF_ENABLED: "true"` when context handoff is ON, then
606
575
  * `GATEWAY_USAGE_REAL_SIZE: "on"` + `GATEWAY_COMPACTION_INTERCEPT: "on"` when EITHER the
607
576
  * `compaction_intercept` setting is ON OR `--compact-at` arms a target below 1M (the target
608
577
  * cannot be honored without the intercept), then `GATEWAY_COMPACTION_UPLOAD_TARGET_TOKENS: "<N>"`
609
- * when a target is set. The `off` profile wins over the intercept and the target: a session with
610
- * no fold never has its compaction intercepted (`assertOffProfileCompatible` refuses the explicit
611
- * flag pair; a standing intercept or target from the environment or launcher.toml is dropped).
612
- * Empty with no profile chosen and everything off — the common case, where
613
- * no header is sent at all. Exported so `--dry-run` can list exactly what the header carries.
578
+ * when a target is set. Empty for `balanced` with everything off — the common case, where no
579
+ * header is sent at all. Exported so `--dry-run` can list exactly what the header carries.
614
580
  */
615
581
  export declare function buildSessionConfig(opts: {
616
- /** `resolveContextProfile` output: `null` ⇒ no profile chosen, no fold key sent. */
617
- profile: ContextProfile | null;
582
+ profile: ContextProfile;
618
583
  contextHandoff: boolean;
619
584
  compactionIntercept?: boolean;
620
585
  /** `resolveCompactAt` output: `null` (or absent) ⇒ no target, send nothing new. */
@@ -626,7 +591,7 @@ export declare function buildSessionConfig(opts: {
626
591
  * gateway's allow-list never sees them as env keys; it ignores unknown envelope fields.
627
592
  */
628
593
  export declare function buildSessionConfigPayload(opts: {
629
- profile: ContextProfile | null;
594
+ profile: ContextProfile;
630
595
  contextHandoff: boolean;
631
596
  compactionIntercept?: boolean;
632
597
  compactAt?: number | null;
@@ -638,12 +603,11 @@ export declare function buildSessionConfigPayload(opts: {
638
603
  } | undefined;
639
604
  /**
640
605
  * The `x-mnemom-session-config` value for this launch, or `undefined` when there is
641
- * nothing to override (the cell's own defaults stand — no profile chosen with everything else
642
- * off, byte-identical to a launch before profiles existed). Independent overlays:
606
+ * nothing to override (the gateway's own defaults stand — `balanced` with everything else off,
607
+ * byte-identical to a launch before profiles existed). Independent overlays:
643
608
  * - the context profile (`buildSessionConfig`): `off` → `CONTEXT_RUNTIME_ENABLED: "false"`,
644
- * `aggressive` → the three fold-tuning keys + `CONTEXT_RUNTIME_SIZE_POLICY: "off"`,
645
- * `balanced` → `CONTEXT_RUNTIME_SIZE_POLICY: "off"`, `adaptive` →
646
- * `CONTEXT_RUNTIME_SIZE_POLICY: "banded"`, none chosen → nothing;
609
+ * `aggressive` → the three fold-tuning keys, `adaptive` → `CONTEXT_RUNTIME_SIZE_POLICY:
610
+ * "banded"`, `balanced` → nothing;
647
611
  * - `compactionIntercept: true` → `GATEWAY_USAGE_REAL_SIZE` + `GATEWAY_COMPACTION_INTERCEPT`
648
612
  * `"on"` (the `compaction_intercept` setting);
649
613
  * - `compactAt: <N>` (`--compact-at`, below 1M) → the SAME two intercept keys plus
@@ -656,20 +620,12 @@ export declare function buildSessionConfigPayload(opts: {
656
620
  * base64url so it survives the gateway's inbound strip.
657
621
  */
658
622
  export declare function buildSessionConfigB64(opts: {
659
- profile: ContextProfile | null;
623
+ profile: ContextProfile;
660
624
  contextHandoff: boolean;
661
625
  compactionIntercept?: boolean;
662
626
  compactAt?: number | null;
663
627
  experimental?: readonly string[];
664
628
  }): string | undefined;
665
- /**
666
- * A no-op `x-mnemom-session-config` value: `{ v: 1, config: {} }` overrides nothing (the gateway
667
- * applies an empty set, exactly its own defaults). buildSessionConfigB64 returns `undefined` for
668
- * the defaults — no header at all; this is for a call that must be Mnemom agent traffic (the
669
- * gateway's agent-traffic gate keys on the header's presence) without changing any setting: the
670
- * launcher's birth probe (commands/wrap.ts birthThroughGateway).
671
- */
672
- export declare const NOOP_SESSION_CONFIG_B64: string;
673
629
  /**
674
630
  * Is the `handoff` MCP tool + `CONTEXT_HANDOFF_ENABLED` session-config header ON for
675
631
  * this launch? OFF by default (operator directive, curation 2026-09-25): an absent flag
@@ -705,12 +661,6 @@ export declare const HANDOFF_MCP_SERVER_NAME = "mnemom-handoff";
705
661
  * it the same way it inherits `ANTHROPIC_CUSTOM_HEADERS` under the terminal shape.
706
662
  */
707
663
  export declare const HANDOFF_RC_KEY_ENV_NAME = "MNEMOM_HANDOFF_KEY";
708
- /**
709
- * Beside `HANDOFF_RC_KEY_ENV_NAME`: the non-`ANTHROPIC_*` var `spawnRcCli` sets to the launch's
710
- * Mnemom key when context handoff is on, so the handoff call carries the `x-mnemom-api-key` the
711
- * gateway requires on every `mnemom agent` request.
712
- */
713
- export declare const HANDOFF_RC_MNEMOM_KEY_ENV_NAME = "MNEMOM_HANDOFF_MNEMOM_KEY";
714
664
  /**
715
665
  * How the `handoff` MCP server (cli/src/mcp/handoff-server.mjs) recovers the Anthropic key
716
666
  * WITHOUT it ever being written into the `--mcp-config` file on disk: `envName` is the NAME of a
@@ -742,12 +692,6 @@ export interface HandoffMcpParams {
742
692
  /** The gateway ORIGIN (e.g. https://gateway.mnemom.ai) — see `resolveHandoffGatewayHost`. */
743
693
  gatewayHost: string;
744
694
  anthropicKeySource: HandoffAnthropicKeySource;
745
- /**
746
- * Where the server reads the Mnemom key (`x-mnemom-api-key`) from — same contract as
747
- * `anthropicKeySource`: `ANTHROPIC_CUSTOM_HEADERS` (its `x-mnemom-api-key:` line) on a terminal
748
- * launch, `HANDOFF_RC_MNEMOM_KEY_ENV_NAME` under Remote Control. Absent ⇒ no Mnemom key header.
749
- */
750
- mnemomKeySource?: HandoffAnthropicKeySource;
751
695
  agent: string;
752
696
  conversationId: string;
753
697
  /** `buildSessionConfigB64` output — forwarded so the route resolves the SAME per-session flag. */
package/dist/lib/agent.js CHANGED
@@ -452,59 +452,32 @@ export const CONTEXT_TAIL_BUDGET_KEY = "CONTEXT_RUNTIME_TAIL_BUDGET_TOKENS";
452
452
  export const CONTEXT_READ_CACHE_KEY = "CONTEXT_RUNTIME_READ_CACHE_TOKENS";
453
453
  export const CONTEXT_HEAD_RECLAIM_KEY = "CONTEXT_RUNTIME_HEAD_BREAKPOINT_RECLAIM";
454
454
  /**
455
- * The gateway key that turns the size-banded fold policy on or off (allow-listed per session).
456
- * Only the literal `banded` enables it; any other value — the profiles send `off` — disables it,
457
- * and a session's value replaces the cell's own. The band thresholds and budgets stay at the
458
- * gateway's own defaults.
455
+ * The gateway key the `adaptive` context profile sets (allow-listed per session): turns on the
456
+ * size-banded fold policy. Only the literal `banded` enables it; the band thresholds and budgets
457
+ * stay at the gateway's own defaults.
459
458
  */
460
459
  export const CONTEXT_SIZE_POLICY_KEY = "CONTEXT_RUNTIME_SIZE_POLICY";
461
- /**
462
- * The two gateway env keys the `compaction_intercept` setting turns on for a single session
463
- * (payload-bound fix; both default OFF on the gateway, both read from the per-session overlay):
464
- * - `GATEWAY_USAGE_REAL_SIZE` — report the size of the body the client actually sent (the
465
- * REAL, unfolded context) in the last `usage.iterations` entry, so Claude Code's own
466
- * auto-compact threshold (its 1M default, or the user's `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` /
467
- * `CLAUDE_CODE_AUTO_COMPACT_WINDOW` / `autoCompactWindow`) fires as it would without the fold;
468
- * - `GATEWAY_COMPACTION_INTERCEPT` — answer the client's compaction request at once from the
469
- * gateway's own fold digest (no model call), so the compaction never blocks the user.
470
- * Sent together, value `"on"`, when the `compaction_intercept` setting is on
471
- * (`resolveCompactionIntercept`) OR when `--compact-at` arms a target below 1M (below) — a
472
- * target cannot be honored without both. The `off` context profile sends both as `"off"`.
473
- */
474
- export const USAGE_REAL_SIZE_KEY = "GATEWAY_USAGE_REAL_SIZE";
475
- export const COMPACTION_INTERCEPT_KEY = "GATEWAY_COMPACTION_INTERCEPT";
476
460
  /**
477
461
  * The named presets for how the gateway folds a session's context (`--context-profile`,
478
- * launcher.toml `context_profile`, `MNEMOM_AGENT_CONTEXT_PROFILE`). Choosing NONE sends no fold
479
- * key at all and the cell's own default decides (see `resolveContextProfile`). A chosen profile
480
- * is complete on its own, so a change to a cell's default can never change what it means:
481
- * - `off` → `CONTEXT_RUNTIME_ENABLED: "false"` plus `GATEWAY_USAGE_REAL_SIZE: "off"` and
482
- * `GATEWAY_COMPACTION_INTERCEPT: "off"` — compaction is left to the coding agent
483
- * and never intercepted, even on a cell whose default turns the intercept on.
484
- * The gateway already skips the intercept with the fold off, but the real-size
485
- * usage rewrite is not gated on the fold, so `off` turns both off by name.
486
- * - `balanced` → `CONTEXT_RUNTIME_SIZE_POLICY: "off"` — the cell's own fold budgets, never
487
- * the size bands, even on a cell whose default is adaptive.
488
- * - `aggressive` → a smaller tail budget + read cache and head-breakpoint reclaim on, size
489
- * policy off: folds earlier and keeps a tighter working set at every size.
462
+ * launcher.toml `context_profile`, `MNEMOM_AGENT_CONTEXT_PROFILE`):
463
+ * - `off` → `CONTEXT_RUNTIME_ENABLED: "false"` — compaction is left to the coding agent
464
+ * (the same bytes `--no-context` has always sent).
465
+ * - `balanced` → NO fold keys: the gateway's own defaults stand. The default.
466
+ * - `aggressive` → a smaller tail budget + read cache and head-breakpoint reclaim on: folds
467
+ * earlier and keeps a tighter working set.
490
468
  * - `adaptive` → `CONTEXT_RUNTIME_SIZE_POLICY: "banded"` — the gateway picks the fold by the
491
469
  * conversation's original size: no fold below 200k tokens, the aggressive
492
- * budgets from 200k to 1M, balanced above.
470
+ * budgets from 200k to 1M, balanced above. Opt-in; never the default.
493
471
  */
494
472
  export const CONTEXT_PROFILES = ["off", "balanced", "aggressive", "adaptive"];
495
473
  /** The per-session env overlay each profile expands to (key order is the wire order). */
496
474
  const CONTEXT_PROFILE_CONFIG = {
497
- off: [
498
- [CONTEXT_RUNTIME_KEY, "false"],
499
- [USAGE_REAL_SIZE_KEY, "off"],
500
- [COMPACTION_INTERCEPT_KEY, "off"],
501
- ],
502
- balanced: [[CONTEXT_SIZE_POLICY_KEY, "off"]],
475
+ off: [[CONTEXT_RUNTIME_KEY, "false"]],
476
+ balanced: [],
503
477
  aggressive: [
504
478
  [CONTEXT_TAIL_BUDGET_KEY, "60000"],
505
479
  [CONTEXT_READ_CACHE_KEY, "8000"],
506
480
  [CONTEXT_HEAD_RECLAIM_KEY, "true"],
507
- [CONTEXT_SIZE_POLICY_KEY, "off"],
508
481
  ],
509
482
  adaptive: [[CONTEXT_SIZE_POLICY_KEY, "banded"]],
510
483
  };
@@ -517,6 +490,21 @@ const CONTEXT_PROFILE_CONFIG = {
517
490
  * header without the tool.
518
491
  */
519
492
  export const CONTEXT_HANDOFF_KEY = "CONTEXT_HANDOFF_ENABLED";
493
+ /**
494
+ * The two gateway env keys the `compaction_intercept` setting turns on for a single session
495
+ * (payload-bound fix; both default OFF on the gateway, both read from the per-session overlay):
496
+ * - `GATEWAY_USAGE_REAL_SIZE` — report the size of the body the client actually sent (the
497
+ * REAL, unfolded context) in the last `usage.iterations` entry, so Claude Code's own
498
+ * auto-compact threshold (its 1M default, or the user's `CLAUDE_AUTOCOMPACT_PCT_OVERRIDE` /
499
+ * `CLAUDE_CODE_AUTO_COMPACT_WINDOW` / `autoCompactWindow`) fires as it would without the fold;
500
+ * - `GATEWAY_COMPACTION_INTERCEPT` — answer the client's compaction request at once from the
501
+ * gateway's own fold digest (no model call), so the compaction never blocks the user.
502
+ * Sent together, value `"on"`, when the `compaction_intercept` setting is on
503
+ * (`resolveCompactionIntercept`) OR when `--compact-at` arms a target below 1M (below) — a
504
+ * target cannot be honored without both.
505
+ */
506
+ export const USAGE_REAL_SIZE_KEY = "GATEWAY_USAGE_REAL_SIZE";
507
+ export const COMPACTION_INTERCEPT_KEY = "GATEWAY_COMPACTION_INTERCEPT";
520
508
  // ---------------------------------------------------------------------------
521
509
  // Compaction target (`--compact-at`, launcher.toml `compact_at`, MNEMOM_COMPACT_AT)
522
510
  // ---------------------------------------------------------------------------
@@ -663,28 +651,6 @@ export function assertCompactAtCompatible(opts) {
663
651
  "enable compaction-intercept`), or pass --compact-at off.");
664
652
  }
665
653
  }
666
- /**
667
- * The `off` context profile turns the fold off, and the compaction intercept answers a compaction
668
- * from that fold, so `off` sends the intercept and real-size keys as `"off"`. An explicit
669
- * `--compaction-intercept` or `--compact-at <N>` in the same launch asks for the opposite —
670
- * refuse rather than silently drop the flag. A standing intercept or target (environment or
671
- * launcher.toml) is not refused: the session's `off` wins and `buildSessionConfig` leaves it out.
672
- * `compactionIntercept` / `compactAt` here are the raw flag values (`undefined` when not passed).
673
- */
674
- export function assertOffProfileCompatible(opts) {
675
- if (opts.profile !== "off")
676
- return;
677
- const flag = opts.compactionIntercept === true
678
- ? "--compaction-intercept"
679
- : typeof opts.compactAt === "number"
680
- ? "--compact-at"
681
- : null;
682
- if (flag === null)
683
- return;
684
- throw new Error(`mnemom agent: context profile off and ${flag} disagree — with the fold off the gateway has ` +
685
- `no fold to answer a compaction from, so off sends the compaction intercept off. Drop ` +
686
- `${flag}, or choose another --context-profile.`);
687
- }
688
654
  /**
689
655
  * `200000` → `"200k"`, anything not k-aligned → the bare digits. Every real caller only ever
690
656
  * passes a `parseCompactAt`-validated value, which is bounded to
@@ -842,10 +808,8 @@ export function launchPreferenceExplicit(opts, env = process.env) {
842
808
  * Has an orchestrator already run the session + µ-balance preflight for this
843
809
  * launch? `MNEMOM_AGENT_PREFLIGHTED=1` is for orchestrators (the ADW fleet) that
844
810
  * checked sign-in and balance themselves before spawning many launches; it skips
845
- * the per-launch session prompt and balance round trips. The launch org still
846
- * resolves as on a normal launch (active org, else personal org — the launch's
847
- * Mnemom key is minted for it), and the Mnemom Agent entitlement (which also
848
- * gates Remote Control, fail-closed) is still fetched for it.
811
+ * the per-launch session/personal-org/balance round trips. The Mnemom Agent
812
+ * entitlement (which also gates Remote Control, fail-closed) is still fetched.
849
813
  * Only the exact value `1` counts — anything else, including `true` or ` 1`, is
850
814
  * a normal launch.
851
815
  */
@@ -946,20 +910,17 @@ export function parseContextProfile(raw, source) {
946
910
  throw new Error(`${source} must be one of ${CONTEXT_PROFILES.join(", ")} (got '${raw}').`);
947
911
  }
948
912
  /**
949
- * Which context profile this launch runs under, or `null` when none was chosen anywhere — then
950
- * no fold key is sent and the cell's own default decides. Precedence, highest wins:
913
+ * Which context profile this launch runs under. Precedence, highest wins:
951
914
  * 1. `--no-context` — always `off`. Combined with an explicit `--context-profile
952
915
  * balanced|aggressive|adaptive` it is a CONFLICT and the launch refuses (never a silent override);
953
916
  * `--context-profile off` agrees with it.
954
917
  * 2. an explicit `--context-profile <profile>` flag (`--context` alongside it is fine — the
955
918
  * profile wins);
956
- * 3. `resumed`: the profile the session this launch resumes ran under (from the session
957
- * ledger), so a resume keeps that session's own choice over the saved default;
958
- * 4. `MNEMOM_AGENT_CONTEXT_PROFILE` (which `applyConfigToEnv` sets from the `context_profile`
919
+ * 3. `MNEMOM_AGENT_CONTEXT_PROFILE` (which `applyConfigToEnv` sets from the `context_profile`
959
920
  * config key) — an invalid value is an error, never a silent default;
960
- * 5. the folding boolean when NO profile is set anywhere: `context = false` in launcher.toml
921
+ * 4. the folding boolean when NO profile is set anywhere: `context = false` in launcher.toml
961
922
  * (→ `MNEMOM_AGENT_CONTEXT`, see `resolveContextFold`) means `off`;
962
- * 6. `null` — unset, the cell default.
923
+ * 5. `balanced` (the default).
963
924
  */
964
925
  export function resolveContextProfile(opts) {
965
926
  if (opts.context === false) {
@@ -970,44 +931,34 @@ export function resolveContextProfile(opts) {
970
931
  }
971
932
  if (opts.contextProfile !== undefined)
972
933
  return opts.contextProfile;
973
- if (opts.resumed)
974
- return opts.resumed;
975
934
  const raw = (opts.env?.MNEMOM_AGENT_CONTEXT_PROFILE ?? "").trim();
976
935
  if (raw !== "")
977
936
  return parseContextProfile(raw, "MNEMOM_AGENT_CONTEXT_PROFILE");
978
937
  if (!resolveContextFold({ context: opts.context, env: opts.env }))
979
938
  return "off";
980
- return null;
939
+ return "balanced";
981
940
  }
982
941
  /**
983
942
  * The decoded per-session env overlay for this launch — the `config` object of the
984
943
  * `x-mnemom-session-config` payload, in wire order: the profile's keys first
985
- * (`CONTEXT_RUNTIME_ENABLED: "false"` + real-size and intercept `"off"` for `off`; the three fold-tuning keys + size policy off for
986
- * `aggressive`; size policy off for `balanced`; size policy banded for `adaptive`; nothing when
987
- * no profile was chosen), then `CONTEXT_HANDOFF_ENABLED: "true"` when context handoff is ON, then
944
+ * (`CONTEXT_RUNTIME_ENABLED` for `off`; the three fold-tuning keys for `aggressive`;
945
+ * `CONTEXT_RUNTIME_SIZE_POLICY` for `adaptive`; nothing for `balanced`), then `CONTEXT_HANDOFF_ENABLED: "true"` when context handoff is ON, then
988
946
  * `GATEWAY_USAGE_REAL_SIZE: "on"` + `GATEWAY_COMPACTION_INTERCEPT: "on"` when EITHER the
989
947
  * `compaction_intercept` setting is ON OR `--compact-at` arms a target below 1M (the target
990
948
  * cannot be honored without the intercept), then `GATEWAY_COMPACTION_UPLOAD_TARGET_TOKENS: "<N>"`
991
- * when a target is set. The `off` profile wins over the intercept and the target: a session with
992
- * no fold never has its compaction intercepted (`assertOffProfileCompatible` refuses the explicit
993
- * flag pair; a standing intercept or target from the environment or launcher.toml is dropped).
994
- * Empty with no profile chosen and everything off — the common case, where
995
- * no header is sent at all. Exported so `--dry-run` can list exactly what the header carries.
949
+ * when a target is set. Empty for `balanced` with everything off — the common case, where no
950
+ * header is sent at all. Exported so `--dry-run` can list exactly what the header carries.
996
951
  */
997
952
  export function buildSessionConfig(opts) {
998
953
  const config = {};
999
- if (opts.profile !== null) {
1000
- for (const [k, v] of CONTEXT_PROFILE_CONFIG[opts.profile])
1001
- config[k] = v;
1002
- }
954
+ for (const [k, v] of CONTEXT_PROFILE_CONFIG[opts.profile])
955
+ config[k] = v;
1003
956
  if (opts.contextHandoff)
1004
957
  config[CONTEXT_HANDOFF_KEY] = "true";
1005
958
  const hasCompactionTarget = opts.compactAt !== undefined && opts.compactAt !== null;
1006
959
  // A target needs the compaction intercept + real-size rewrite to arm (#2216) — without them
1007
960
  // the upload-target key is silently inert (compaction-align.ts: "armed only inside the
1008
961
  // intercept"). Deliberately NOT GATEWAY_COMPACTION_REFOLD — a separate, costlier opt-in.
1009
- if (opts.profile === "off")
1010
- return config;
1011
962
  if (opts.compactionIntercept || hasCompactionTarget) {
1012
963
  config[USAGE_REAL_SIZE_KEY] = "on";
1013
964
  config[COMPACTION_INTERCEPT_KEY] = "on";
@@ -1033,12 +984,11 @@ export function buildSessionConfigPayload(opts) {
1033
984
  }
1034
985
  /**
1035
986
  * The `x-mnemom-session-config` value for this launch, or `undefined` when there is
1036
- * nothing to override (the cell's own defaults stand — no profile chosen with everything else
1037
- * off, byte-identical to a launch before profiles existed). Independent overlays:
987
+ * nothing to override (the gateway's own defaults stand — `balanced` with everything else off,
988
+ * byte-identical to a launch before profiles existed). Independent overlays:
1038
989
  * - the context profile (`buildSessionConfig`): `off` → `CONTEXT_RUNTIME_ENABLED: "false"`,
1039
- * `aggressive` → the three fold-tuning keys + `CONTEXT_RUNTIME_SIZE_POLICY: "off"`,
1040
- * `balanced` → `CONTEXT_RUNTIME_SIZE_POLICY: "off"`, `adaptive` →
1041
- * `CONTEXT_RUNTIME_SIZE_POLICY: "banded"`, none chosen → nothing;
990
+ * `aggressive` → the three fold-tuning keys, `adaptive` → `CONTEXT_RUNTIME_SIZE_POLICY:
991
+ * "banded"`, `balanced` → nothing;
1042
992
  * - `compactionIntercept: true` → `GATEWAY_USAGE_REAL_SIZE` + `GATEWAY_COMPACTION_INTERCEPT`
1043
993
  * `"on"` (the `compaction_intercept` setting);
1044
994
  * - `compactAt: <N>` (`--compact-at`, below 1M) → the SAME two intercept keys plus
@@ -1056,14 +1006,6 @@ export function buildSessionConfigB64(opts) {
1056
1006
  return undefined;
1057
1007
  return Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
1058
1008
  }
1059
- /**
1060
- * A no-op `x-mnemom-session-config` value: `{ v: 1, config: {} }` overrides nothing (the gateway
1061
- * applies an empty set, exactly its own defaults). buildSessionConfigB64 returns `undefined` for
1062
- * the defaults — no header at all; this is for a call that must be Mnemom agent traffic (the
1063
- * gateway's agent-traffic gate keys on the header's presence) without changing any setting: the
1064
- * launcher's birth probe (commands/wrap.ts birthThroughGateway).
1065
- */
1066
- export const NOOP_SESSION_CONFIG_B64 = Buffer.from(JSON.stringify({ v: 1, config: {} }), "utf8").toString("base64url");
1067
1009
  /**
1068
1010
  * Is the `handoff` MCP tool + `CONTEXT_HANDOFF_ENABLED` session-config header ON for
1069
1011
  * this launch? OFF by default (operator directive, curation 2026-09-25): an absent flag
@@ -1107,12 +1049,6 @@ export const HANDOFF_MCP_SERVER_NAME = "mnemom-handoff";
1107
1049
  * it the same way it inherits `ANTHROPIC_CUSTOM_HEADERS` under the terminal shape.
1108
1050
  */
1109
1051
  export const HANDOFF_RC_KEY_ENV_NAME = "MNEMOM_HANDOFF_KEY";
1110
- /**
1111
- * Beside `HANDOFF_RC_KEY_ENV_NAME`: the non-`ANTHROPIC_*` var `spawnRcCli` sets to the launch's
1112
- * Mnemom key when context handoff is on, so the handoff call carries the `x-mnemom-api-key` the
1113
- * gateway requires on every `mnemom agent` request.
1114
- */
1115
- export const HANDOFF_RC_MNEMOM_KEY_ENV_NAME = "MNEMOM_HANDOFF_MNEMOM_KEY";
1116
1052
  /** The `--mcp-config` document registering exactly the `handoff` tool. Pure — no I/O. */
1117
1053
  export function buildHandoffMcpConfig(p) {
1118
1054
  const env = {
@@ -1121,8 +1057,6 @@ export function buildHandoffMcpConfig(p) {
1121
1057
  MNEMOM_HANDOFF_AGENT: p.agent,
1122
1058
  MNEMOM_HANDOFF_CONVERSATION_ID: p.conversationId,
1123
1059
  };
1124
- if (p.mnemomKeySource)
1125
- env.MNEMOM_HANDOFF_MNEMOM_KEY_ENV_NAME = p.mnemomKeySource.envName;
1126
1060
  if (p.sessionConfigB64)
1127
1061
  env.MNEMOM_HANDOFF_SESSION_CONFIG = p.sessionConfigB64;
1128
1062
  return {
package/dist/lib/api.d.ts CHANGED
@@ -1069,27 +1069,6 @@ export declare function listApiKeys(): Promise<ApiKeyListItem[]>;
1069
1069
  * for non-staff, admin:org for users not in any org-admin role).
1070
1070
  */
1071
1071
  export declare function createApiKey(name: string, scopes: ApiKeyScope[]): Promise<ApiKeyCreated>;
1072
- /**
1073
- * POST /v1/orgs/{org_id}/api-keys — mint an ORG-owned key (its `org_id` is that org, so the
1074
- * gateway births a new agent there). Owners and admins may mint any scopes; a member may mint a
1075
- * key whose scopes are exactly ["gateway"]. A refusal (viewer/auditor, a non-member, or an API
1076
- * that predates member org keys) is thrown as MnemomApiError with its status (403/404).
1077
- */
1078
- export declare function createOrgApiKey(orgId: string, name: string, scopes: ApiKeyScope[]): Promise<ApiKeyCreated>;
1079
- /**
1080
- * GET /v1/api-keys/whoami authenticated by `key` ALONE (`X-Mnemom-Api-Key`, no session): does
1081
- * the API accept this key? true = 200. false = 401/403 — revoked, rotated or unknown, OR a valid
1082
- * `gateway`-only key: the API refuses every key without an `api:*` scope (ADR-049), so false
1083
- * alone never proves a key dead. Throws on anything else (network, timeout, 429, 5xx): the
1084
- * caller reads that as "could not check".
1085
- */
1086
- export declare function apiAcceptsMnemomKey(key: string, timeoutMs: number): Promise<boolean>;
1087
- /**
1088
- * GET /v1/api-keys with a timeout, for checking a key: the signed-in caller's ACTIVE keys (a
1089
- * revoked or rotated key is absent). null when there is no usable session (no credential, or
1090
- * 401/403 after the refresh retry). Throws on anything else (network, timeout, 5xx).
1091
- */
1092
- export declare function listOwnApiKeysForCheck(timeoutMs: number): Promise<ApiKeyListItem[] | null>;
1093
1072
  /**
1094
1073
  * POST /v1/api-keys/{key_id}/rotate — atomic mint-new + revoke-old.
1095
1074
  * Returns the full new secret only on this call. The new key inherits
@@ -1099,13 +1078,9 @@ export declare function listOwnApiKeysForCheck(timeoutMs: number): Promise<ApiKe
1099
1078
  export declare function rotateApiKey(keyId: string): Promise<ApiKeyCreated>;
1100
1079
  /**
1101
1080
  * DELETE /v1/api-keys/{key_id} — soft-revoke. The key row stays for
1102
- * audit; `is_active` flips to false and `revoked_at` is timestamped. Only
1103
- * a key the signed-in user created (an org key they minted included) is
1104
- * found; anything else is a 404. `timeoutMs` bounds the call.
1081
+ * audit; `is_active` flips to false and `revoked_at` is timestamped.
1105
1082
  */
1106
- export declare function revokeApiKey(keyId: string, opts?: {
1107
- timeoutMs?: number;
1108
- }): Promise<void>;
1083
+ export declare function revokeApiKey(keyId: string): Promise<void>;
1109
1084
  export interface LicenseValidationResult {
1110
1085
  valid: boolean;
1111
1086
  license_id?: string;