no-mistakes(review): Harden GC gate key aliases, fail closed, fix baseline

This commit is contained in:
root
2026-09-12 18:42:36 +00:00
parent 4ea2d0309f
commit de1428b4ae
3 changed files with 31 additions and 8 deletions
+2 -1
View File
@@ -24,11 +24,12 @@ done
| Agent | CT | Node | IP | LiteLLM Alias | Key Source | Platform |
|-------|-----|------|-----|---------------|------------|----------|
| Koby | 111 | amdpve | .129 | `koby` | Infisical vault | **Hermes** |
| Koby | 111 | storepve | .129 | `koby` | Infisical vault | **Hermes** |
| Koonimo | 113 | amdpve | .114 | `koonimo` | Infisical vault | Hermes |
| Shumba | — | 192.168.68.119 | N/A | N/A (DeepSeek) | Hermes (RETIRED — CT119 now Infisical vault) |
> **Note**: CT hostnames (tdunna→CT111, baggy→CT113) differ from agent identities (koby, koonimo).
> CT 111 (tdunna, 192.168.68.129, storepve) is report-only — Theo's box; alert only, never garbage-collect.
Access: `pct-run <CT_ID> <command>` — no IPs needed. GPU hosts (.8, .110, .15) use SSH.
Keys are stored in Infisical vault (project=agents, env=production) and injected at
+18 -6
View File
@@ -22,7 +22,8 @@ Usage:
cat scan.json | disk-gc-plan.py # same, via stdin
disk-gc-plan.py --scan scan.json --json # machine-readable plan
Scan entries may carry any of: id / guest / vmid, hostname / name, ip.
Scan entries may carry any of: id / guest / vmid / ct / ctid, hostname / name, ip.
A threshold-crossing entry with no recognizable identity is reported, never GC'd.
Exit codes: 0 ok, 1 usage/parse error.
"""
from __future__ import annotations
@@ -40,6 +41,9 @@ DEFAULT_CONTRACT = REPO / "disk-gc-threat-response.prose.md"
AMBER, RED, CRITICAL = 75, 85, 95
IDENTITY_FIELDS = ("id", "guest", "vmid", "ct", "ctid", "hostname", "name", "ip")
UNIDENTIFIED_REASON = "unidentified target - refusing to schedule GC"
def load_report_only_guests(contract_path: pathlib.Path) -> list[dict]:
"""Read the authoritative report_only_guests block out of the contract.
@@ -64,7 +68,7 @@ def _keys(entry: dict) -> set[str]:
"""Guest/host identity keys, shared by exclusions and scan entries so the two
sides of the gate can never key on different fields."""
out: set[str] = set()
for field in ("guest", "id", "vmid", "hostname", "name", "ip"):
for field in IDENTITY_FIELDS:
value = entry.get(field)
if value is not None and str(value).strip():
out.add(str(value).strip().lower())
@@ -92,12 +96,20 @@ def build_plan(scan: list[dict], report_only: list[dict]) -> list[dict]:
if level is None:
continue # GREEN: log only, no action
scan_keys = _keys(entry)
match = next((e for e, keys in excluded if keys & scan_keys), None)
target = next(
(entry.get(k) for k in ("id", "guest", "vmid", "hostname", "name", "ip")
if entry.get(k) not in (None, "")),
(entry.get(k) for k in IDENTITY_FIELDS if entry.get(k) not in (None, "")),
"?",
)
if not scan_keys:
plan.append({
"target": target,
"level": level,
"pct": float(pct),
"action": "report-only",
"reason": UNIDENTIFIED_REASON,
})
continue
match = next((e for e, keys in excluded if keys & scan_keys), None)
if match is not None:
plan.append({
"target": target,
@@ -119,7 +131,7 @@ def build_plan(scan: list[dict], report_only: list[dict]) -> list[dict]:
def main() -> int:
ap = argparse.ArgumentParser(description="Plan disk GC actions with the report-only gate.")
ap.add_argument("--scan", help="JSON file: list of {id|hostname|ip, usage_pct}")
ap.add_argument("--scan", help="JSON file: list of {id|ct|hostname|ip, usage_pct}")
ap.add_argument("--contract", default=str(DEFAULT_CONTRACT))
ap.add_argument("--json", action="store_true", help="emit the plan as JSON")
args = ap.parse_args()
+11 -1
View File
@@ -51,8 +51,10 @@ def test_excluded_guest_never_gets_gc_at_any_level(tmp_path):
def test_exclusion_matches_on_any_identity_key(tmp_path):
"""The gate is keyed on guest/host, so id, hostname or IP all match."""
"""The gate is keyed on guest/host, so id, ct, ctid, hostname or IP all match."""
for entry in ({"id": 111, "usage_pct": 95},
{"ct": 111, "usage_pct": 95},
{"ctid": 111, "usage_pct": 95},
{"hostname": "tdunna", "usage_pct": 95},
{"ip": "192.168.68.129", "usage_pct": 95}):
plan = _plan([entry], tmp_path)
@@ -78,6 +80,14 @@ def test_agent_name_alone_does_not_gate_a_guest(tmp_path):
assert plan and plan[0]["action"] == "gc-executor"
def test_unidentified_threat_fails_closed(tmp_path):
"""A threshold-crossing entry with no recognized identity must not schedule GC."""
plan = _plan([{"usage_pct": 97}], tmp_path)
assert plan, "an unidentified threat must still be reported"
assert plan[0]["action"] == "report-only", plan
assert plan[0]["reason"], plan
def _plan_with_contract(scan, contract_text, tmp_path, name):
contract = tmp_path / name
contract.write_text(contract_text)