2026-06-12 16:42:05 +00:00
|
|
|
"""Config loading for the memory plugin hooks (deep module).
|
|
|
|
|
|
|
|
|
|
Replaces the duplicated inline YAML parsers in the four bash hooks with a single
|
|
|
|
|
load_config() call returning a frozen Config dataclass. Fail-open: a missing or
|
|
|
|
|
malformed config file yields defaults, never an exception.
|
os-vault: WS2 write-behavior eval harness + untuned baseline grid
plugins/os-vault/eval/ — held-out unprompted vault-write discrimination eval:
ambiguity ladder L1 explicit -> L3 conceptual, paired positives/negatives,
6 run-set scenarios on a new reportgen Ruby fixture + 6 frozen reserve twins,
isolated sandbox vault, headless-only runner, deterministic-first Ruby checker
(narrow judge fallback stubbable via OS_VAULT_EVAL_JUDGE_CMD), model-free
self-test 21/21. Scenario Task blocks are held-out; reserve never read.
Isolation seam: OS_VAULT_PATH overrides vault_path via config.load_config();
OS_VAULT_SKIP_REBUILD suppresses the SessionStart graphify rebuild. Write
SKILL.md contract fix (defers to vault-conventions.md) + Vault location section.
Baseline grid (run-set x sonnet/haiku x 3 reps + 1 counted canary, 37 reps):
positives 1/19, negatives 18/18. L1 persists every rep but routes to built-in
auto-memory instead of the vault; L2/L3 mostly don't persist; zero
over-triggering. Wording loop (step 4, not started) targets: trigger at
L2/L3, route to vault at L1. Loop-input candidates: vault note
os-vault-write-eval-baseline-grid-results. CLAUDE.md pointers updated for
this and os-status.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:46:22 +00:00
|
|
|
|
|
|
|
|
OS_VAULT_PATH in the environment overrides vault_path from config.yaml — this is
|
|
|
|
|
the isolation seam the os-vault eval harness uses to point every hook at a
|
|
|
|
|
sandbox vault instead of the real one.
|
2026-06-12 16:42:05 +00:00
|
|
|
"""
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
import os
|
|
|
|
|
from dataclasses import dataclass, field
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
import yaml
|
|
|
|
|
except Exception: # pragma: no cover - yaml is provided via graphify
|
|
|
|
|
yaml = None
|
|
|
|
|
|
2026-07-03 13:43:18 +00:00
|
|
|
CONFIG_PATH = os.path.expanduser("~/.claude/plugins/os-vault/config.yaml")
|
2026-06-12 16:42:05 +00:00
|
|
|
|
|
|
|
|
DEFAULT_VAULT_PATH = "~/Documents/SecondBrain"
|
2026-07-16 20:36:23 +00:00
|
|
|
DEFAULT_GRAPHIFY_OUTPUT_DIR = "~/Documents/SecondBrain/graphify-out"
|
2026-06-12 16:42:05 +00:00
|
|
|
DEFAULT_MODEL = "qwen25-coder-7b-16k"
|
|
|
|
|
DEFAULT_STALE_DAYS = 7
|
|
|
|
|
DEFAULT_MEMSEARCH_DIR = "~/.memsearch"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Config:
|
|
|
|
|
vault_path: str
|
|
|
|
|
graphify_output_dir: str
|
|
|
|
|
model: str
|
|
|
|
|
stale_days: int
|
|
|
|
|
memsearch_dir: str
|
|
|
|
|
env: dict = field(default_factory=dict)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def load_config(path: str = CONFIG_PATH) -> "Config":
|
|
|
|
|
cfg = {}
|
|
|
|
|
if yaml is not None:
|
|
|
|
|
try:
|
|
|
|
|
with open(os.path.expanduser(path)) as f:
|
|
|
|
|
cfg = yaml.safe_load(f) or {}
|
|
|
|
|
except Exception:
|
|
|
|
|
cfg = {}
|
|
|
|
|
if not isinstance(cfg, dict):
|
|
|
|
|
cfg = {}
|
|
|
|
|
|
|
|
|
|
def expand(value):
|
|
|
|
|
return os.path.expanduser(str(value))
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
stale_days = int(cfg.get("stale_threshold_days", DEFAULT_STALE_DAYS))
|
|
|
|
|
except Exception:
|
|
|
|
|
stale_days = DEFAULT_STALE_DAYS
|
|
|
|
|
|
|
|
|
|
env_block = cfg.get("env") or {}
|
|
|
|
|
if not isinstance(env_block, dict):
|
|
|
|
|
env_block = {}
|
|
|
|
|
|
os-vault: WS2 write-behavior eval harness + untuned baseline grid
plugins/os-vault/eval/ — held-out unprompted vault-write discrimination eval:
ambiguity ladder L1 explicit -> L3 conceptual, paired positives/negatives,
6 run-set scenarios on a new reportgen Ruby fixture + 6 frozen reserve twins,
isolated sandbox vault, headless-only runner, deterministic-first Ruby checker
(narrow judge fallback stubbable via OS_VAULT_EVAL_JUDGE_CMD), model-free
self-test 21/21. Scenario Task blocks are held-out; reserve never read.
Isolation seam: OS_VAULT_PATH overrides vault_path via config.load_config();
OS_VAULT_SKIP_REBUILD suppresses the SessionStart graphify rebuild. Write
SKILL.md contract fix (defers to vault-conventions.md) + Vault location section.
Baseline grid (run-set x sonnet/haiku x 3 reps + 1 counted canary, 37 reps):
positives 1/19, negatives 18/18. L1 persists every rep but routes to built-in
auto-memory instead of the vault; L2/L3 mostly don't persist; zero
over-triggering. Wording loop (step 4, not started) targets: trigger at
L2/L3, route to vault at L1. Loop-input candidates: vault note
os-vault-write-eval-baseline-grid-results. CLAUDE.md pointers updated for
this and os-status.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:46:22 +00:00
|
|
|
env_vault = os.environ.get("OS_VAULT_PATH")
|
|
|
|
|
|
2026-06-12 16:42:05 +00:00
|
|
|
return Config(
|
os-vault: WS2 write-behavior eval harness + untuned baseline grid
plugins/os-vault/eval/ — held-out unprompted vault-write discrimination eval:
ambiguity ladder L1 explicit -> L3 conceptual, paired positives/negatives,
6 run-set scenarios on a new reportgen Ruby fixture + 6 frozen reserve twins,
isolated sandbox vault, headless-only runner, deterministic-first Ruby checker
(narrow judge fallback stubbable via OS_VAULT_EVAL_JUDGE_CMD), model-free
self-test 21/21. Scenario Task blocks are held-out; reserve never read.
Isolation seam: OS_VAULT_PATH overrides vault_path via config.load_config();
OS_VAULT_SKIP_REBUILD suppresses the SessionStart graphify rebuild. Write
SKILL.md contract fix (defers to vault-conventions.md) + Vault location section.
Baseline grid (run-set x sonnet/haiku x 3 reps + 1 counted canary, 37 reps):
positives 1/19, negatives 18/18. L1 persists every rep but routes to built-in
auto-memory instead of the vault; L2/L3 mostly don't persist; zero
over-triggering. Wording loop (step 4, not started) targets: trigger at
L2/L3, route to vault at L1. Loop-input candidates: vault note
os-vault-write-eval-baseline-grid-results. CLAUDE.md pointers updated for
this and os-status.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:46:22 +00:00
|
|
|
vault_path=expand(env_vault) if env_vault else expand(cfg.get("vault_path", DEFAULT_VAULT_PATH)),
|
2026-06-12 16:42:05 +00:00
|
|
|
graphify_output_dir=expand(cfg.get("graphify_output_dir", DEFAULT_GRAPHIFY_OUTPUT_DIR)),
|
|
|
|
|
model=str(cfg.get("ollama_model", DEFAULT_MODEL)),
|
|
|
|
|
stale_days=stale_days,
|
|
|
|
|
memsearch_dir=expand(cfg.get("memsearch_dir", DEFAULT_MEMSEARCH_DIR)),
|
|
|
|
|
env={str(k): str(v) for k, v in env_block.items()},
|
|
|
|
|
)
|