chore(config): retire unread keys [sandbox] network, [sandbox] workspace_readonly, [complexity] top_k

Legacy inventory 2, item R3. The three keys loaded into ResolvedConfig and nothing read them: no
`.network`, `.workspace_readonly` or `.top_k` access exists in src outside config.py. The sandbox
runner always passes `--network none` and `--read-only` and rejects host networking by argv
inspection, so the two sandbox keys were knobs that turned nothing; no stage read top_k, and
`[complexity] max_hunter_hotspots` is the one complexity key the scan reads. They join RETIRED_KEYS
with the same 2026-10-02 mechanism as the other unread keys (RetiredConfigError naming the reason).
The fields and their loaders are removed; memory_mb, timeout_seconds, pids_limit (read by
regress/recipes.py and sandbox/runner.py) and max_hunter_hotspots stay. test_config.py covers the three
retirements and the override test now exercises max_hunter_hotspots. RELEASE_NOTES Unreleased carries
the line.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
Marius Ciepluch
2026-10-02 19:45:37 +02:00
co-authored by Claude Fable 5.1
parent adb70b6b98
commit 6db5a35f07
3 changed files with 19 additions and 17 deletions
+4
View File
@@ -13,6 +13,10 @@
keeps only the text chunker the skill router uses; the `VectorIndex` half had no caller, and nothing read the keeps only the text chunker the skill router uses; the `VectorIndex` half had no caller, and nothing read the
`chunks.json` the subcommand wrote. `[embeddings] model`/`store` fail to load with the reason, like the other `chunks.json` the subcommand wrote. `[embeddings] model`/`store` fail to load with the reason, like the other
retired keys; `OPENROUTER_EMBEDDING_MODEL` is no longer read (`ousast learn memory embed --model` names the model). retired keys; `OPENROUTER_EMBEDDING_MODEL` is no longer read (`ousast learn memory embed --model` names the model).
- **Retired three config keys nothing read** (2026-10-02): `[sandbox] network`, `[sandbox] workspace_readonly` and
`[complexity] top_k` now fail to load naming why. The sandbox always ran with `--network none` and a read-only
workspace regardless of the first two; no stage read `top_k`. `memory_mb`, `timeout_seconds`, `pids_limit` and
`max_hunter_hotspots` are read and stay.
# v2.0.0 (2026-10-02) # v2.0.0 (2026-10-02)
+9 -7
View File
@@ -24,6 +24,11 @@ _UNREAD_ON = "retired 2026-10-02 because nothing ever read it"
_UNREAD_DYNAMIC = "no dynamic or deep tier exists; deep mode will define its own keys when it is built" _UNREAD_DYNAMIC = "no dynamic or deep tier exists; deep mode will define its own keys when it is built"
_UNREAD_EVIDENCE = "evidence tiers come from the program model's ladder (model/ladder.py), not from configuration" _UNREAD_EVIDENCE = "evidence tiers come from the program model's ladder (model/ladder.py), not from configuration"
_UNREAD_VARIANTS = "the structural variant search it configured was deleted with semantic/variants.py" _UNREAD_VARIANTS = "the structural variant search it configured was deleted with semantic/variants.py"
_UNREAD_SANDBOX = (
"the sandbox always runs with `--network none` and a read-only workspace (sandbox/runner.py); that is an "
"invariant the runner enforces, not a knob"
)
_UNREAD_TOP_K = "no stage read it; `[complexity] max_hunter_hotspots` is the one complexity key the scan reads"
_UNREAD_EMBEDDINGS = ( _UNREAD_EMBEDDINGS = (
"the json-local vector index it configured and `ousast index` were deleted; the decision engine embeds through " "the json-local vector index it configured and `ousast index` were deleted; the decision engine embeds through "
"`ousast learn memory embed --model` (learn/embeddings.py)" "`ousast learn memory embed --model` (learn/embeddings.py)"
@@ -42,6 +47,9 @@ RETIRED_KEYS: dict[tuple[str, str], str] = {
("variants", "max_mechanisms"): f"{_UNREAD_ON}: {_UNREAD_VARIANTS}", ("variants", "max_mechanisms"): f"{_UNREAD_ON}: {_UNREAD_VARIANTS}",
("embeddings", "model"): f"{_UNREAD_ON}: {_UNREAD_EMBEDDINGS}", ("embeddings", "model"): f"{_UNREAD_ON}: {_UNREAD_EMBEDDINGS}",
("embeddings", "store"): f"{_UNREAD_ON}: {_UNREAD_EMBEDDINGS}", ("embeddings", "store"): f"{_UNREAD_ON}: {_UNREAD_EMBEDDINGS}",
("sandbox", "network"): f"{_UNREAD_ON}: {_UNREAD_SANDBOX}",
("sandbox", "workspace_readonly"): f"{_UNREAD_ON}: {_UNREAD_SANDBOX}",
("complexity", "top_k"): f"{_UNREAD_ON}: {_UNREAD_TOP_K}",
} }
RETIRED_SECTION = "harnessx" # retired 2026-09-30: loads with one warning and is otherwise ignored (Req 3.3) RETIRED_SECTION = "harnessx" # retired 2026-09-30: loads with one warning and is otherwise ignored (Req 3.3)
RETIRED_SECTION_WARNING = ( RETIRED_SECTION_WARNING = (
@@ -100,8 +108,6 @@ class ModelConfig:
@dataclass(frozen=True) @dataclass(frozen=True)
class SandboxConfig: class SandboxConfig:
network: bool = False
workspace_readonly: bool = True
memory_mb: int = 2048 memory_mb: int = 2048
timeout_seconds: int = 300 timeout_seconds: int = 300
pids_limit: int = 512 pids_limit: int = 512
@@ -146,8 +152,7 @@ class FusionConfig:
@dataclass(frozen=True) @dataclass(frozen=True)
class ComplexityConfig: class ComplexityConfig:
# Stage-2 map size and hunter attention. Small defaults keep PR/nightly map work cheap. # Hunter attention. A small default keeps PR/nightly map work cheap.
top_k: int = 20
max_hunter_hotspots: int = 8 max_hunter_hotspots: int = 8
@@ -276,8 +281,6 @@ def _load_models(value: object) -> ModelConfig:
def _load_sandbox(value: object) -> SandboxConfig: def _load_sandbox(value: object) -> SandboxConfig:
data = _section(value) data = _section(value)
return SandboxConfig( return SandboxConfig(
network=bool(data.get("network", False)),
workspace_readonly=bool(data.get("workspace_readonly", True)),
memory_mb=_int_value(data.get("memory_mb"), 2048), memory_mb=_int_value(data.get("memory_mb"), 2048),
timeout_seconds=_int_value(data.get("timeout_seconds"), 300), timeout_seconds=_int_value(data.get("timeout_seconds"), 300),
pids_limit=_int_value(data.get("pids_limit"), 512), pids_limit=_int_value(data.get("pids_limit"), 512),
@@ -337,7 +340,6 @@ def _load_fusion(value: object) -> FusionConfig:
def _load_complexity(value: object) -> ComplexityConfig: def _load_complexity(value: object) -> ComplexityConfig:
data = _section(value) data = _section(value)
return ComplexityConfig( return ComplexityConfig(
top_k=_int_value(data.get("top_k"), 20),
max_hunter_hotspots=_int_value(data.get("max_hunter_hotspots"), 8), max_hunter_hotspots=_int_value(data.get("max_hunter_hotspots"), 8),
) )
+6 -10
View File
@@ -75,6 +75,9 @@ def test_retired_llm_keys_fail_naming_the_replacement(tmp_path: Path, body: str,
("[variants]\nmax_mechanisms = 10\n", "`[variants] max_mechanisms`"), ("[variants]\nmax_mechanisms = 10\n", "`[variants] max_mechanisms`"),
('[embeddings]\nmodel = "openai/text-embedding-3-small"\n', "`[embeddings] model`"), ('[embeddings]\nmodel = "openai/text-embedding-3-small"\n', "`[embeddings] model`"),
('[embeddings]\nstore = "json-local"\n', "`[embeddings] store`"), ('[embeddings]\nstore = "json-local"\n', "`[embeddings] store`"),
("[sandbox]\nnetwork = true\n", "`[sandbox] network`"),
("[sandbox]\nworkspace_readonly = false\n", "`[sandbox] workspace_readonly`"),
("[complexity]\ntop_k = 3\n", "`[complexity] top_k`"),
], ],
) )
def test_unread_keys_fail_naming_why(tmp_path: Path, body: str, key: str) -> None: def test_unread_keys_fail_naming_why(tmp_path: Path, body: str, key: str) -> None:
@@ -147,24 +150,21 @@ def test_write_resolved_config_creates_json(tmp_path: Path) -> None:
def test_complexity_and_regress_defaults_when_section_absent() -> None: def test_complexity_and_regress_defaults_when_section_absent() -> None:
config = load_config(None) config = load_config(None)
assert config.complexity.top_k == 20
assert config.complexity.max_hunter_hotspots == 8 assert config.complexity.max_hunter_hotspots == 8
assert config.regress.max_candidates == 5 assert config.regress.max_candidates == 5
assert config.regress.images == () assert config.regress.images == ()
assert config.sandbox.network is False
assert config.sandbox.workspace_readonly is True
assert config.sandbox.memory_mb == 2048 assert config.sandbox.memory_mb == 2048
assert config.sandbox.timeout_seconds == 300 assert config.sandbox.timeout_seconds == 300
assert config.sandbox.pids_limit == 512 assert config.sandbox.pids_limit == 512
def test_override_changes_top_k_and_max_candidates_only(tmp_path: Path) -> None: def test_override_changes_max_hunter_hotspots_and_max_candidates_only(tmp_path: Path) -> None:
config_path = tmp_path / "openultrasast.toml" config_path = tmp_path / "openultrasast.toml"
config_path.write_text( config_path.write_text(
"\n".join( "\n".join(
[ [
"[complexity]", "[complexity]",
"top_k = 3", "max_hunter_hotspots = 3",
"[regress]", "[regress]",
"max_candidates = 2", "max_candidates = 2",
] ]
@@ -173,12 +173,9 @@ def test_override_changes_top_k_and_max_candidates_only(tmp_path: Path) -> None:
config = load_config(config_path) config = load_config(config_path)
assert config.complexity.top_k == 3 assert config.complexity.max_hunter_hotspots == 3
assert config.regress.max_candidates == 2 assert config.regress.max_candidates == 2
assert config.complexity.max_hunter_hotspots == 8
assert config.regress.images == () assert config.regress.images == ()
assert config.sandbox.network is False
assert config.sandbox.workspace_readonly is True
assert config.sandbox.memory_mb == 2048 assert config.sandbox.memory_mb == 2048
assert config.sandbox.timeout_seconds == 300 assert config.sandbox.timeout_seconds == 300
assert config.sandbox.pids_limit == 512 assert config.sandbox.pids_limit == 512
@@ -202,7 +199,6 @@ def test_load_config_reads_regress_image_pins(tmp_path: Path) -> None:
assert config.regress.max_candidates == 4 assert config.regress.max_candidates == 4
assert dict(config.regress.images) == {"python": "python:3.12-slim", "javascript": "node:22-slim"} assert dict(config.regress.images) == {"python": "python:3.12-slim", "javascript": "node:22-slim"}
assert config.complexity.top_k == 20
assert config.complexity.max_hunter_hotspots == 8 assert config.complexity.max_hunter_hotspots == 8
assert config.sandbox.memory_mb == 2048 assert config.sandbox.memory_mb == 2048