@ponythewhite/base-context 1.0.6 → 1.0.8

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.
Files changed (136) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/src/rlm/__init__.py +3 -0
  4. package/dist/base-context-runtime/src/rlm/harness.py +86 -48
  5. package/dist/base-context-runtime/test/test_harness.py +215 -140
  6. package/dist/base-context-runtime/uv.lock +1 -1
  7. package/dist/build-info.json +1 -1
  8. package/dist/bundle/amazon-bedrock.js +3 -3
  9. package/dist/bundle/{anthropic-UV5GZDGU.js → anthropic-5PSCZEER.js} +2 -7
  10. package/dist/bundle/{azure-openai-responses-WSNPXLYC.js → azure-openai-responses-AYTLJR33.js} +2 -2
  11. package/dist/bundle/{bundled-modules-MEACET4U.js → bundled-modules-IGMJH2MU.js} +5 -5
  12. package/dist/bundle/{chunk-UPVDERMD.js → chunk-2IPDSTDR.js} +11 -9
  13. package/dist/bundle/chunk-D3KOF57W.js +22040 -0
  14. package/dist/bundle/{chunk-QKI6KEGP.js → chunk-EXEFSSF4.js} +1509 -577
  15. package/dist/bundle/{chunk-VSIYFWYI.js → chunk-KT2BNEPE.js} +21 -8
  16. package/dist/bundle/{chunk-KTNETTHI.js → chunk-Q3MBSBEB.js} +3 -101
  17. package/dist/bundle/{chunk-LFPWHI42.js → chunk-QKIFBA7N.js} +2 -2
  18. package/dist/bundle/{chunk-LIZVVGHR.js → chunk-RVJVXZCS.js} +13 -10
  19. package/dist/bundle/{cli-main-ANUJY7Y4.js → cli-main-BUK7QTHO.js} +4 -4
  20. package/dist/bundle/cli.js +1 -1
  21. package/dist/bundle/{google-T32FMD4G.js → google-HTMCUJ7X.js} +2 -2
  22. package/dist/bundle/{google-vertex-56KP6I3B.js → google-vertex-ZQO65AXF.js} +2 -2
  23. package/dist/bundle/{main-4GIKOHIT.js → main-2FWHT2WZ.js} +5 -5
  24. package/dist/bundle/{mistral-WGBMYIVU.js → mistral-SB7LU56G.js} +1 -1
  25. package/dist/bundle/{openai-codex-responses-PIV2RQ3G.js → openai-codex-responses-5CEW4VN3.js} +53 -27
  26. package/dist/bundle/{openai-completions-64C3JPR4.js → openai-completions-BAZJQSS2.js} +1 -1
  27. package/dist/bundle/{openai-responses-UI7RSTDV.js → openai-responses-VHOE427P.js} +48 -5
  28. package/dist/core/agent-session.d.ts +6 -1
  29. package/dist/core/agent-session.d.ts.map +1 -1
  30. package/dist/core/agent-session.js +189 -31
  31. package/dist/core/agent-session.js.map +1 -1
  32. package/dist/core/canonical-context.d.ts +8 -0
  33. package/dist/core/canonical-context.d.ts.map +1 -1
  34. package/dist/core/canonical-context.js +37 -5
  35. package/dist/core/canonical-context.js.map +1 -1
  36. package/dist/core/compaction/compaction.d.ts +2 -2
  37. package/dist/core/compaction/compaction.d.ts.map +1 -1
  38. package/dist/core/compaction/compaction.js +31 -13
  39. package/dist/core/compaction/compaction.js.map +1 -1
  40. package/dist/core/context-epoch.d.ts +1 -1
  41. package/dist/core/context-epoch.d.ts.map +1 -1
  42. package/dist/core/context-epoch.js +20 -12
  43. package/dist/core/context-epoch.js.map +1 -1
  44. package/dist/core/extensions/types.d.ts +2 -2
  45. package/dist/core/extensions/types.d.ts.map +1 -1
  46. package/dist/core/extensions/types.js.map +1 -1
  47. package/dist/core/history-index-worker.d.ts.map +1 -1
  48. package/dist/core/history-index-worker.js +29 -8
  49. package/dist/core/history-index-worker.js.map +1 -1
  50. package/dist/core/history-index.d.ts +11 -1
  51. package/dist/core/history-index.d.ts.map +1 -1
  52. package/dist/core/history-index.js +2 -1
  53. package/dist/core/history-index.js.map +1 -1
  54. package/dist/core/inference-coordinator.d.ts.map +1 -1
  55. package/dist/core/inference-coordinator.js +110 -13
  56. package/dist/core/inference-coordinator.js.map +1 -1
  57. package/dist/core/kernel/bootstrap.d.ts.map +1 -1
  58. package/dist/core/kernel/bootstrap.js +97 -107
  59. package/dist/core/kernel/bootstrap.js.map +1 -1
  60. package/dist/core/kernel/repl-manager.d.ts.map +1 -1
  61. package/dist/core/kernel/repl-manager.js +11 -0
  62. package/dist/core/kernel/repl-manager.js.map +1 -1
  63. package/dist/core/kernel/shared.d.ts +2 -0
  64. package/dist/core/kernel/shared.d.ts.map +1 -1
  65. package/dist/core/kernel/shared.js.map +1 -1
  66. package/dist/core/messages.d.ts.map +1 -1
  67. package/dist/core/messages.js +4 -1
  68. package/dist/core/messages.js.map +1 -1
  69. package/dist/core/prompts/rlm.d.ts.map +1 -1
  70. package/dist/core/prompts/rlm.js +4 -2
  71. package/dist/core/prompts/rlm.js.map +1 -1
  72. package/dist/core/public-context.d.ts.map +1 -1
  73. package/dist/core/public-context.js +16 -0
  74. package/dist/core/public-context.js.map +1 -1
  75. package/dist/core/refinement/refinement.d.ts +19 -5
  76. package/dist/core/refinement/refinement.d.ts.map +1 -1
  77. package/dist/core/refinement/refinement.js +90 -35
  78. package/dist/core/refinement/refinement.js.map +1 -1
  79. package/dist/core/request-view-selection.d.ts +12 -4
  80. package/dist/core/request-view-selection.d.ts.map +1 -1
  81. package/dist/core/request-view-selection.js +242 -100
  82. package/dist/core/request-view-selection.js.map +1 -1
  83. package/dist/core/retained-tool-output.d.ts +28 -0
  84. package/dist/core/retained-tool-output.d.ts.map +1 -0
  85. package/dist/core/retained-tool-output.js +102 -0
  86. package/dist/core/retained-tool-output.js.map +1 -0
  87. package/dist/core/sdk.d.ts.map +1 -1
  88. package/dist/core/sdk.js +1 -1
  89. package/dist/core/sdk.js.map +1 -1
  90. package/dist/core/selective-recovery.d.ts +47 -3
  91. package/dist/core/selective-recovery.d.ts.map +1 -1
  92. package/dist/core/selective-recovery.js +428 -109
  93. package/dist/core/selective-recovery.js.map +1 -1
  94. package/dist/core/session-history-index.d.ts +3 -1
  95. package/dist/core/session-history-index.d.ts.map +1 -1
  96. package/dist/core/session-history-index.js +1 -1
  97. package/dist/core/session-history-index.js.map +1 -1
  98. package/dist/core/settings-manager.d.ts +5 -0
  99. package/dist/core/settings-manager.d.ts.map +1 -1
  100. package/dist/core/settings-manager.js +3 -0
  101. package/dist/core/settings-manager.js.map +1 -1
  102. package/dist/core/system-prompt.d.ts +3 -1
  103. package/dist/core/system-prompt.d.ts.map +1 -1
  104. package/dist/core/system-prompt.js +3 -3
  105. package/dist/core/system-prompt.js.map +1 -1
  106. package/dist/core/task-frame.d.ts +1 -1
  107. package/dist/core/task-frame.d.ts.map +1 -1
  108. package/dist/core/task-frame.js +21 -1
  109. package/dist/core/task-frame.js.map +1 -1
  110. package/dist/core/task-state-reader.d.ts +10 -2
  111. package/dist/core/task-state-reader.d.ts.map +1 -1
  112. package/dist/core/task-state-reader.js +75 -9
  113. package/dist/core/task-state-reader.js.map +1 -1
  114. package/dist/core/tools/ipython.d.ts +5 -0
  115. package/dist/core/tools/ipython.d.ts.map +1 -1
  116. package/dist/core/tools/ipython.js +59 -17
  117. package/dist/core/tools/ipython.js.map +1 -1
  118. package/dist/core/tools/prime-context.d.ts.map +1 -1
  119. package/dist/core/tools/prime-context.js +1 -1
  120. package/dist/core/tools/prime-context.js.map +1 -1
  121. package/dist/core/view-units.d.ts +4 -0
  122. package/dist/core/view-units.d.ts.map +1 -1
  123. package/dist/core/view-units.js +28 -19
  124. package/dist/core/view-units.js.map +1 -1
  125. package/dist/installer.mjs +98 -77
  126. package/dist/modes/interactive/components/refinement-outcome-message.d.ts.map +1 -1
  127. package/dist/modes/interactive/components/refinement-outcome-message.js.map +1 -1
  128. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  129. package/dist/modes/interactive/interactive-mode.js +5 -5
  130. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  131. package/dist/skills/skill-creator/SKILL.md +18 -1
  132. package/docs/settings.md +45 -0
  133. package/docs/skills.md +77 -2
  134. package/package.json +4 -4
  135. package/skills/skill-creator/SKILL.md +18 -1
  136. package/dist/bundle/chunk-W46VZFI6.js +0 -21681
@@ -7,6 +7,7 @@ import sys
7
7
  import tempfile
8
8
  import unittest
9
9
  from pathlib import Path
10
+ from unittest.mock import Mock, patch
10
11
 
11
12
  from rlm import harness as package_harness
12
13
  from rlm import rlm as callable_rlm
@@ -21,6 +22,54 @@ PYTHON_REFERENCE = {
21
22
 
22
23
 
23
24
  class HarnessStateTest(unittest.TestCase):
25
+ def test_workspace_lessons_survive_sessions_and_route_explicit_crud(self) -> None:
26
+ with tempfile.TemporaryDirectory() as temp_dir:
27
+ root = Path(temp_dir)
28
+ workspace_dir = root / "project" / ".base-context"
29
+ env = {
30
+ "BASE_CONTEXT_HARNESS_STATE_DIR": str(root / "session-one"),
31
+ "BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR": str(root / "global"),
32
+ "BASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR": str(workspace_dir),
33
+ }
34
+ with patch.dict(os.environ, env):
35
+ workspace = callable_rlm.get_harness_state(scope="workspace")
36
+ self.assertIs(workspace, get_harness_state(scope="workspace"))
37
+ workspace.upsert("memory", "Project tests", "Problem: missing dependency. Fix: use .venv/bin/python.",
38
+ id="error-fix:project-tests", metadata={"tool": "ipython", "condition": "project tests"})
39
+ workspace.upsert("memory", "Project tests", "Problem: missing dependency. Fix: use project .venv.",
40
+ id="error-fix:project-tests")
41
+ self.assertEqual(len(workspace.list("memory")), 1)
42
+ self.assertEqual(workspace.file_path, workspace_dir / "harness-state.json")
43
+ # A new session reads the ordinary persisted workspace image, not the old store object.
44
+ with patch.dict(os.environ, {"BASE_CONTEXT_HARNESS_STATE_DIR": str(root / "session-two")}):
45
+ later = HarnessState(workspace.file_path, scope="workspace")
46
+ self.assertEqual(later.get("memory", "error-fix:project-tests").version, 2)
47
+ session = get_harness_state()
48
+ self.assertEqual(session.get("memory", "workspace:error-fix:project-tests").scope, "workspace")
49
+ session.update_memory("workspace:error-fix:project-tests", "Project tests", "Problem: x. Fix: y.")
50
+ self.assertIn("workspace:error-fix:project-tests", workspace.overview())
51
+ workspace.create_memory("Explicit global", "global only", id="global-note", global_=True)
52
+ self.assertIsNone(workspace.get("memory", "global-note"))
53
+ self.assertEqual(get_harness_state(global_=True).get("memory", "global-note").scope, "global")
54
+ self.assertTrue(session.delete_memory("workspace:error-fix:project-tests"))
55
+ self.assertIsNone(later.get("memory", "error-fix:project-tests"))
56
+ with self.assertRaisesRegex(ValueError, "conflicts"):
57
+ get_harness_state(scope="workspace", global_=True)
58
+ with self.assertRaisesRegex(ValueError, "conflicts"):
59
+ workspace.get("memory", "workspace:note", global_=True)
60
+
61
+ def test_workspace_never_falls_back_to_another_project_or_mutable_cwd(self) -> None:
62
+ with tempfile.TemporaryDirectory() as temp_dir:
63
+ first = Path(temp_dir) / "first" / ".base-context"
64
+ second = Path(temp_dir) / "second" / ".base-context"
65
+ with patch.dict(os.environ, {"BASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR": str(first)}):
66
+ get_harness_state(scope="workspace").create_memory("First project", "Only here", id="error-fix:tests")
67
+ with patch.dict(os.environ, {"BASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR": str(second)}):
68
+ self.assertEqual(get_harness_state(scope="workspace").list("memory"), [])
69
+ with patch.dict(os.environ, {"BASE_CONTEXT_WORKSPACE_HARNESS_STATE_DIR": ""}):
70
+ with self.assertRaisesRegex(RuntimeError, "Workspace harness state requires"):
71
+ get_harness_state(scope="workspace")
72
+
24
73
  def test_crud_for_all_entry_kinds(self) -> None:
25
74
  with tempfile.TemporaryDirectory() as temp_dir:
26
75
  state = HarnessState(Path(temp_dir) / "harness_state.json")
@@ -292,19 +341,45 @@ class HarnessStateTest(unittest.TestCase):
292
341
  arguments={},
293
342
  )
294
343
 
295
- def test_load_tolerates_corrupt_or_non_object_state(self) -> None:
344
+ def test_load_rejects_corrupt_or_non_object_state(self) -> None:
296
345
  for payload in ("not json at all", "null", "[]", '"a string"', "123"):
297
346
  with tempfile.TemporaryDirectory() as temp_dir:
298
347
  state_path = Path(temp_dir) / "harness_state.json"
348
+ state = HarnessState(state_path)
299
349
  state_path.write_text(payload, encoding="utf-8")
300
350
 
301
- state = HarnessState(state_path)
351
+ with self.assertRaisesRegex(ValueError, "Invalid harness state"):
352
+ HarnessState(state_path)
353
+ with self.assertRaisesRegex(ValueError, "Invalid harness state"):
354
+ state.create_memory("New", "Must not overwrite corruption.")
355
+ self.assertEqual(state_path.read_text(encoding="utf-8"), payload)
302
356
 
303
- self.assertEqual(state.list(), [])
304
- self.assertEqual(state.refinements, [])
305
- # The store must remain usable and self-heal on the next write.
306
- created = state.create_memory("Recovered", "Works after corruption.", id="recovered")
307
- self.assertEqual(HarnessState(state_path).get("memory", "recovered").content, created.content)
357
+ def test_failed_temporary_write_preserves_file_and_mutations(self) -> None:
358
+ with tempfile.TemporaryDirectory() as temp_dir:
359
+ state_path = Path(temp_dir) / "harness_state.json"
360
+ state = HarnessState(state_path)
361
+ current = state.create_memory("Existing", "Original", id="existing")
362
+ image = state_path.read_bytes()
363
+ before = state.snapshot()
364
+
365
+ def failing_temporary_file(*args, **kwargs):
366
+ temporary = tempfile.NamedTemporaryFile(*args, **kwargs)
367
+ temporary.write = Mock(side_effect=OSError("temporary write failed"))
368
+ return temporary
369
+
370
+ with patch("rlm.harness.NamedTemporaryFile", side_effect=failing_temporary_file):
371
+ for mutation in (
372
+ lambda: state.update_memory("existing", "Changed", "Replacement"),
373
+ lambda: state.create_memory("New", "Not published", id="new"),
374
+ lambda: state.delete_memory("existing"),
375
+ lambda: state.record_refinement("failed save", []),
376
+ ):
377
+ with self.assertRaisesRegex(OSError, "temporary write failed"):
378
+ mutation()
379
+ self.assertEqual(state_path.read_bytes(), image)
380
+ self.assertEqual(state.snapshot(), before)
381
+ self.assertIs(state.get("memory", "existing"), current)
382
+ self.assertEqual(list(Path(temp_dir).iterdir()), [state_path])
308
383
 
309
384
  def test_update_skill_preserves_omitted_arguments(self) -> None:
310
385
  with tempfile.TemporaryDirectory() as temp_dir:
@@ -359,11 +434,11 @@ class HarnessStateTest(unittest.TestCase):
359
434
  self.assertEqual(state.get("memory", "grouped").path, "repo/other")
360
435
 
361
436
  def test_in_memory_state_never_touches_disk(self) -> None:
362
- previous = os.environ.get("RLM_HARNESS_STATE_DIR")
363
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
437
+ previous = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
438
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
364
439
  with tempfile.TemporaryDirectory() as temp_dir:
365
- os.environ["RLM_HARNESS_STATE_DIR"] = temp_dir
366
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
440
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = temp_dir
441
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
367
442
  try:
368
443
  state = HarnessState(in_memory=True)
369
444
  created = state.create_memory("Volatile", "in memory only", id="volatile")
@@ -376,27 +451,27 @@ class HarnessStateTest(unittest.TestCase):
376
451
  self.assertEqual(list(Path(temp_dir).iterdir()), [])
377
452
  finally:
378
453
  if previous is None:
379
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
454
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
380
455
  else:
381
- os.environ["RLM_HARNESS_STATE_DIR"] = previous
456
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous
382
457
  if previous_global is None:
383
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
458
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
384
459
  else:
385
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
460
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
386
461
 
387
462
  def test_in_memory_state_global_flag_uses_global_env_store(self) -> None:
388
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
463
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
389
464
  with tempfile.TemporaryDirectory() as temp_dir:
390
465
  global_dir = Path(temp_dir) / "global"
391
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
466
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
392
467
  try:
393
468
  state = HarnessState(in_memory=True)
394
469
  global_entry = state.create_memory("Global note", "persisted", id="global_note", global_=True)
395
470
  finally:
396
471
  if previous_global is None:
397
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
472
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
398
473
  else:
399
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
474
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
400
475
 
401
476
  self.assertIsNone(state.file_path)
402
477
  self.assertEqual(global_entry.scope, "global")
@@ -408,24 +483,24 @@ class HarnessStateTest(unittest.TestCase):
408
483
  )
409
484
 
410
485
  def test_in_memory_state_global_flag_uses_default_global_store(self) -> None:
411
- previous_agent_dir = os.environ.get("PRIME_AGENT_CODING_AGENT_DIR")
412
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
486
+ previous_agent_dir = os.environ.get("BASE_CONTEXT_HOME")
487
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
413
488
  with tempfile.TemporaryDirectory() as temp_dir:
414
489
  agent_dir = Path(temp_dir) / "agent"
415
- os.environ["PRIME_AGENT_CODING_AGENT_DIR"] = str(agent_dir)
416
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
490
+ os.environ["BASE_CONTEXT_HOME"] = str(agent_dir)
491
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
417
492
  try:
418
493
  state = HarnessState(in_memory=True)
419
494
  global_entry = state.create_memory("Default global", "persisted", id="default_global", global_=True)
420
495
  finally:
421
496
  if previous_agent_dir is None:
422
- os.environ.pop("PRIME_AGENT_CODING_AGENT_DIR", None)
497
+ os.environ.pop("BASE_CONTEXT_HOME", None)
423
498
  else:
424
- os.environ["PRIME_AGENT_CODING_AGENT_DIR"] = previous_agent_dir
499
+ os.environ["BASE_CONTEXT_HOME"] = previous_agent_dir
425
500
  if previous_global is None:
426
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
501
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
427
502
  else:
428
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
503
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
429
504
 
430
505
  self.assertIsNone(state.file_path)
431
506
  self.assertEqual(global_entry.scope, "global")
@@ -503,19 +578,19 @@ class HarnessStateTest(unittest.TestCase):
503
578
  self.assertEqual(state.file_path, Path(temp_dir).resolve() / "harness_state.json")
504
579
 
505
580
  def test_explicit_state_dir_global_flag_uses_matching_state_file(self) -> None:
506
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
581
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
507
582
  with tempfile.TemporaryDirectory() as temp_dir:
508
583
  explicit_dir = Path(temp_dir) / "explicit"
509
584
  env_global_dir = Path(temp_dir) / "env-global"
510
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(env_global_dir)
585
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(env_global_dir)
511
586
  try:
512
587
  state = get_harness_state(explicit_dir)
513
588
  global_entry = state.create_memory("Scoped global", "custom dir", id="scoped_global", global_=True)
514
589
  finally:
515
590
  if previous_global is None:
516
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
591
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
517
592
  else:
518
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
593
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
519
594
 
520
595
  self.assertEqual(global_entry.scope, "global")
521
596
  self.assertIsNotNone(
@@ -524,13 +599,13 @@ class HarnessStateTest(unittest.TestCase):
524
599
  self.assertFalse((env_global_dir / "harness_state.json").exists())
525
600
 
526
601
  def test_env_default_state_keeps_env_global_target_after_explicit_dir_cache_hit(self) -> None:
527
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
528
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
602
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
603
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
529
604
  with tempfile.TemporaryDirectory() as temp_dir:
530
605
  local_dir = Path(temp_dir) / "local"
531
606
  env_global_dir = Path(temp_dir) / "env-global"
532
- os.environ["RLM_HARNESS_STATE_DIR"] = str(local_dir)
533
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(env_global_dir)
607
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = str(local_dir)
608
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(env_global_dir)
534
609
  try:
535
610
  cached_from_env = get_harness_state()
536
611
  # An explicit state_dir that aliases the env local dir must not
@@ -544,13 +619,13 @@ class HarnessStateTest(unittest.TestCase):
544
619
  )
545
620
  finally:
546
621
  if previous_local is None:
547
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
622
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
548
623
  else:
549
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
624
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
550
625
  if previous_global is None:
551
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
626
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
552
627
  else:
553
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
628
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
554
629
 
555
630
  self.assertIs(cached_from_env, cached_from_explicit)
556
631
  self.assertEqual(global_entry.scope, "global")
@@ -564,68 +639,68 @@ class HarnessStateTest(unittest.TestCase):
564
639
  )
565
640
 
566
641
  def test_local_state_requires_local_path(self) -> None:
567
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
568
- previous_session = os.environ.get("RLM_SESSION_DIR")
642
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
643
+ previous_session = os.environ.get("BASE_CONTEXT_KERNEL_SESSION_DIR")
569
644
  try:
570
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
571
- os.environ.pop("RLM_SESSION_DIR", None)
645
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
646
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
572
647
  with self.assertRaisesRegex(RuntimeError, "Local harness state requires"):
573
648
  HarnessState()
574
649
  finally:
575
650
  if previous_local is None:
576
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
651
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
577
652
  else:
578
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
653
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
579
654
  if previous_session is None:
580
- os.environ.pop("RLM_SESSION_DIR", None)
655
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
581
656
  else:
582
- os.environ["RLM_SESSION_DIR"] = previous_session
657
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = previous_session
583
658
 
584
659
  def test_default_state_uses_global_harness_env_dir(self) -> None:
585
- previous = os.environ.get("RLM_HARNESS_STATE_DIR")
660
+ previous = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
586
661
  with tempfile.TemporaryDirectory() as temp_dir:
587
- os.environ["RLM_HARNESS_STATE_DIR"] = temp_dir
662
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = temp_dir
588
663
  try:
589
664
  state = HarnessState()
590
665
  finally:
591
666
  if previous is None:
592
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
667
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
593
668
  else:
594
- os.environ["RLM_HARNESS_STATE_DIR"] = previous
669
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous
595
670
 
596
671
  self.assertEqual(state.file_path, Path(temp_dir).resolve() / "harness_state.json")
597
672
 
598
673
  def test_global_scope_default_state_uses_global_harness_env_dir(self) -> None:
599
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
600
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
674
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
675
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
601
676
  with tempfile.TemporaryDirectory() as temp_dir:
602
677
  local_dir = Path(temp_dir) / "local"
603
678
  global_dir = Path(temp_dir) / "global"
604
- os.environ["RLM_HARNESS_STATE_DIR"] = str(local_dir)
605
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
679
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = str(local_dir)
680
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
606
681
  try:
607
682
  state = HarnessState(scope="global")
608
683
  finally:
609
684
  if previous_local is None:
610
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
685
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
611
686
  else:
612
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
687
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
613
688
  if previous_global is None:
614
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
689
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
615
690
  else:
616
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
691
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
617
692
 
618
693
  self.assertEqual(state.scope, "global")
619
694
  self.assertEqual(state.file_path, global_dir.resolve() / "harness_state.json")
620
695
 
621
696
  def test_default_state_is_local_and_global_flag_targets_global_store(self) -> None:
622
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
623
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
697
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
698
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
624
699
  with tempfile.TemporaryDirectory() as temp_dir:
625
700
  local_dir = Path(temp_dir) / "local"
626
701
  global_dir = Path(temp_dir) / "global"
627
- os.environ["RLM_HARNESS_STATE_DIR"] = str(local_dir)
628
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
702
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = str(local_dir)
703
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
629
704
  try:
630
705
  state = get_harness_state()
631
706
  global_state = get_harness_state(global_=True)
@@ -639,13 +714,13 @@ class HarnessStateTest(unittest.TestCase):
639
714
  )
640
715
  finally:
641
716
  if previous_local is None:
642
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
717
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
643
718
  else:
644
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
719
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
645
720
  if previous_global is None:
646
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
721
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
647
722
  else:
648
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
723
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
649
724
 
650
725
  self.assertEqual(state.file_path, local_dir.resolve() / "harness_state.json")
651
726
  self.assertEqual(global_state.file_path, global_dir.resolve() / "harness_state.json")
@@ -667,11 +742,11 @@ class HarnessStateTest(unittest.TestCase):
667
742
  state.create_memory("Bad global flag", "bad", id="bad_global", **{"global": "false"})
668
743
 
669
744
  def test_state_cache_keeps_scope_distinct_when_local_and_global_share_a_file(self) -> None:
670
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
671
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
745
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
746
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
672
747
  with tempfile.TemporaryDirectory() as temp_dir:
673
- os.environ["RLM_HARNESS_STATE_DIR"] = temp_dir
674
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = temp_dir
748
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = temp_dir
749
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = temp_dir
675
750
  try:
676
751
  state = get_harness_state()
677
752
  global_state = get_harness_state(global_=True)
@@ -679,13 +754,13 @@ class HarnessStateTest(unittest.TestCase):
679
754
  global_entry = state.create_memory("Global note", "All sessions.", id="global_note", global_=True)
680
755
  finally:
681
756
  if previous_local is None:
682
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
757
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
683
758
  else:
684
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
759
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
685
760
  if previous_global is None:
686
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
761
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
687
762
  else:
688
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
763
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
689
764
 
690
765
  self.assertIsNot(state, global_state)
691
766
  self.assertEqual(state.file_path, global_state.file_path)
@@ -698,13 +773,13 @@ class HarnessStateTest(unittest.TestCase):
698
773
  self.assertEqual(reloaded.get("memory", "global_note").scope, "global")
699
774
 
700
775
  def test_scope_prefixed_ids_route_to_the_displayed_scope(self) -> None:
701
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
702
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
776
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
777
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
703
778
  with tempfile.TemporaryDirectory() as temp_dir:
704
779
  local_dir = Path(temp_dir) / "local"
705
780
  global_dir = Path(temp_dir) / "global"
706
- os.environ["RLM_HARNESS_STATE_DIR"] = str(local_dir)
707
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
781
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = str(local_dir)
782
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
708
783
  try:
709
784
  state = get_harness_state()
710
785
  state.create_memory("Global note", "v1", id="routed", global_=True)
@@ -722,13 +797,13 @@ class HarnessStateTest(unittest.TestCase):
722
797
  self.assertIsNone(state.get("memory", "local_note"))
723
798
  finally:
724
799
  if previous_local is None:
725
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
800
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
726
801
  else:
727
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
802
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
728
803
  if previous_global is None:
729
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
804
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
730
805
  else:
731
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
806
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
732
807
 
733
808
  self.assertEqual(
734
809
  HarnessState(global_dir / "harness_state.json", scope="global").get("memory", "routed").content,
@@ -736,25 +811,25 @@ class HarnessStateTest(unittest.TestCase):
736
811
  )
737
812
 
738
813
  def test_create_with_prefixed_id_does_not_mint_literal_id(self) -> None:
739
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
740
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
814
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
815
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
741
816
  with tempfile.TemporaryDirectory() as temp_dir:
742
817
  local_dir = Path(temp_dir) / "local"
743
818
  global_dir = Path(temp_dir) / "global"
744
- os.environ["RLM_HARNESS_STATE_DIR"] = str(local_dir)
745
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
819
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = str(local_dir)
820
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
746
821
  try:
747
822
  state = get_harness_state()
748
823
  entry = state.create_memory("Validation", "content", id="global:validation")
749
824
  finally:
750
825
  if previous_local is None:
751
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
826
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
752
827
  else:
753
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
828
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
754
829
  if previous_global is None:
755
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
830
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
756
831
  else:
757
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
832
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
758
833
 
759
834
  self.assertEqual(entry.id, "validation")
760
835
  self.assertEqual(entry.scope, "global")
@@ -767,39 +842,39 @@ class HarnessStateTest(unittest.TestCase):
767
842
  # Forkserver scenario: rlm is imported in the template process without the
768
843
  # per-session env; the child applies env after fork. rlm.harness must then
769
844
  # resolve against the new env instead of a store frozen at import time.
770
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
771
- previous_session = os.environ.get("RLM_SESSION_DIR")
845
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
846
+ previous_session = os.environ.get("BASE_CONTEXT_KERNEL_SESSION_DIR")
772
847
  with tempfile.TemporaryDirectory() as temp_dir:
773
848
  try:
774
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
775
- os.environ.pop("RLM_SESSION_DIR", None)
849
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
850
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
776
851
  # Without local env, local writes fail loudly instead of vanishing.
777
852
  with self.assertRaisesRegex(RuntimeError, "global_=True"):
778
853
  package_harness.create_memory("Volatile", "pre-env", id="pre_env")
779
854
 
780
- os.environ["RLM_HARNESS_STATE_DIR"] = temp_dir
855
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = temp_dir
781
856
  entry = package_harness.create_memory("Session note", "persisted", id="session_note")
782
857
  self.assertIsNone(package_harness.get("memory", "pre_env"))
783
858
  finally:
784
859
  if previous_local is None:
785
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
860
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
786
861
  else:
787
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
862
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
788
863
  if previous_session is None:
789
- os.environ.pop("RLM_SESSION_DIR", None)
864
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
790
865
  else:
791
- os.environ["RLM_SESSION_DIR"] = previous_session
866
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = previous_session
792
867
 
793
868
  self.assertEqual(entry.scope, "local")
794
869
  reloaded = HarnessState(Path(temp_dir) / "harness_state.json")
795
870
  self.assertEqual(reloaded.get("memory", "session_note").content, "persisted")
796
871
 
797
872
  def test_module_harness_without_env_raises_on_local_writes_and_reads_work(self) -> None:
798
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
799
- previous_session = os.environ.get("RLM_SESSION_DIR")
873
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
874
+ previous_session = os.environ.get("BASE_CONTEXT_KERNEL_SESSION_DIR")
800
875
  try:
801
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
802
- os.environ.pop("RLM_SESSION_DIR", None)
876
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
877
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
803
878
 
804
879
  for mutate in (
805
880
  lambda: package_harness.create_memory("Lost", "content", id="lost"),
@@ -818,38 +893,38 @@ class HarnessStateTest(unittest.TestCase):
818
893
  self.assertEqual(package_harness.snapshot()["refinements"], [])
819
894
  finally:
820
895
  if previous_local is None:
821
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
896
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
822
897
  else:
823
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
898
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
824
899
  if previous_session is None:
825
- os.environ.pop("RLM_SESSION_DIR", None)
900
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
826
901
  else:
827
- os.environ["RLM_SESSION_DIR"] = previous_session
902
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = previous_session
828
903
 
829
904
  def test_module_harness_without_env_still_routes_global_writes(self) -> None:
830
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
831
- previous_session = os.environ.get("RLM_SESSION_DIR")
832
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
905
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
906
+ previous_session = os.environ.get("BASE_CONTEXT_KERNEL_SESSION_DIR")
907
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
833
908
  with tempfile.TemporaryDirectory() as temp_dir:
834
909
  global_dir = Path(temp_dir) / "global"
835
910
  try:
836
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
837
- os.environ.pop("RLM_SESSION_DIR", None)
838
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
911
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
912
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
913
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(global_dir)
839
914
  entry = package_harness.create_memory("Lesson", "keep me", id="no_session_lesson", global_=True)
840
915
  finally:
841
916
  if previous_local is None:
842
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
917
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
843
918
  else:
844
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
919
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
845
920
  if previous_session is None:
846
- os.environ.pop("RLM_SESSION_DIR", None)
921
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
847
922
  else:
848
- os.environ["RLM_SESSION_DIR"] = previous_session
923
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = previous_session
849
924
  if previous_global is None:
850
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
925
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
851
926
  else:
852
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
927
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
853
928
 
854
929
  self.assertEqual(entry.scope, "global")
855
930
  self.assertEqual(
@@ -859,8 +934,8 @@ class HarnessStateTest(unittest.TestCase):
859
934
 
860
935
  def test_import_rlm_without_env_does_not_raise(self) -> None:
861
936
  env = dict(os.environ)
862
- env.pop("RLM_HARNESS_STATE_DIR", None)
863
- env.pop("RLM_SESSION_DIR", None)
937
+ env.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
938
+ env.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
864
939
  env["PYTHONPATH"] = str(Path(__file__).resolve().parents[1] / "src")
865
940
  result = subprocess.run(
866
941
  [sys.executable, "-c", "import rlm; repr(rlm.harness); rlm.harness.overview(); rlm.harness.create_memory"],
@@ -871,43 +946,43 @@ class HarnessStateTest(unittest.TestCase):
871
946
  self.assertEqual(result.returncode, 0, result.stderr)
872
947
 
873
948
  def test_empty_local_state_dir_env_is_treated_as_unset(self) -> None:
874
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
875
- previous_session = os.environ.get("RLM_SESSION_DIR")
949
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
950
+ previous_session = os.environ.get("BASE_CONTEXT_KERNEL_SESSION_DIR")
876
951
  with tempfile.TemporaryDirectory() as temp_dir:
877
952
  try:
878
953
  # Empty local dir must not fall through to the global agent-dir default.
879
- os.environ["RLM_HARNESS_STATE_DIR"] = ""
880
- os.environ.pop("RLM_SESSION_DIR", None)
954
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = ""
955
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
881
956
  with self.assertRaisesRegex(RuntimeError, "Local harness state requires"):
882
957
  HarnessState()
883
958
 
884
959
  # With a session dir it takes the session fallback instead.
885
- os.environ["RLM_SESSION_DIR"] = temp_dir
960
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = temp_dir
886
961
  state = HarnessState()
887
962
  self.assertEqual(state.file_path, Path(temp_dir).resolve() / "harness" / "harness_state.json")
888
963
 
889
964
  # A whitespace-only session dir is also unset.
890
- os.environ["RLM_SESSION_DIR"] = " "
965
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = " "
891
966
  with self.assertRaisesRegex(RuntimeError, "Local harness state requires"):
892
967
  HarnessState()
893
968
  finally:
894
969
  if previous_local is None:
895
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
970
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
896
971
  else:
897
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
972
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
898
973
  if previous_session is None:
899
- os.environ.pop("RLM_SESSION_DIR", None)
974
+ os.environ.pop("BASE_CONTEXT_KERNEL_SESSION_DIR", None)
900
975
  else:
901
- os.environ["RLM_SESSION_DIR"] = previous_session
976
+ os.environ["BASE_CONTEXT_KERNEL_SESSION_DIR"] = previous_session
902
977
 
903
978
  def test_explicit_dir_aliasing_env_local_dir_keeps_env_global_target(self) -> None:
904
- previous_local = os.environ.get("RLM_HARNESS_STATE_DIR")
905
- previous_global = os.environ.get("RLM_GLOBAL_HARNESS_STATE_DIR")
979
+ previous_local = os.environ.get("BASE_CONTEXT_HARNESS_STATE_DIR")
980
+ previous_global = os.environ.get("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR")
906
981
  with tempfile.TemporaryDirectory() as temp_dir:
907
982
  local_dir = Path(temp_dir) / "local"
908
983
  env_global_dir = Path(temp_dir) / "env-global"
909
- os.environ["RLM_HARNESS_STATE_DIR"] = str(local_dir)
910
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = str(env_global_dir)
984
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = str(local_dir)
985
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = str(env_global_dir)
911
986
  try:
912
987
  # First construction happens via an explicit dir that merely aliases
913
988
  # the env local dir; global writes must still hit the env global dir.
@@ -915,13 +990,13 @@ class HarnessStateTest(unittest.TestCase):
915
990
  global_entry = state.create_memory("Aliased", "still global", id="alias_global", global_=True)
916
991
  finally:
917
992
  if previous_local is None:
918
- os.environ.pop("RLM_HARNESS_STATE_DIR", None)
993
+ os.environ.pop("BASE_CONTEXT_HARNESS_STATE_DIR", None)
919
994
  else:
920
- os.environ["RLM_HARNESS_STATE_DIR"] = previous_local
995
+ os.environ["BASE_CONTEXT_HARNESS_STATE_DIR"] = previous_local
921
996
  if previous_global is None:
922
- os.environ.pop("RLM_GLOBAL_HARNESS_STATE_DIR", None)
997
+ os.environ.pop("BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR", None)
923
998
  else:
924
- os.environ["RLM_GLOBAL_HARNESS_STATE_DIR"] = previous_global
999
+ os.environ["BASE_CONTEXT_GLOBAL_HARNESS_STATE_DIR"] = previous_global
925
1000
 
926
1001
  self.assertEqual(global_entry.scope, "global")
927
1002
  self.assertIsNotNone(