Require a token for writes and quarantine what nobody vouches for
Sixteen mutating routes now refuse a caller who cannot present the token the server started with; queries stay open, because a question is not a write. The environment variable is ELY_EYE_AUTH_TOKEN, following the repo's env_prefix convention — the shorter name I reached for first returned 403 where the smoke expected 401, and the server printed the reason. Words from a stranger are quarantined on the way in: an HTTP upload is third_party by definition, and a sentence carrying an instruction-shaped phrase is quarantined whoever wrote it. A quarantined atom stays findable and stays out of the compiled context until a second, live, unquarantined source agrees with its rarest words. Corroboration is computed at read time because it is a property of the corpus now, not of the moment a memory was written; it is term-level, and the docstring says so. forget now erases the source row and the compiled contexts beside the atoms, so a forgotten memory leaves nothing that can still speak. The semantic cache key carries a store revision, which fixes a real staleness: a context compiled before new evidence arrived kept its old quarantine decision forever. bench.audit --product still pointed at evals.py, which the p1-6 split moved into backend/src/ely_eye/proofs/. It failed fast, but the anti-self-justification rule had quietly stopped auditing the product; it now walks the package, and a test pins that the package exists and holds no re-roll. Gates: pytest 306 passed; ruff clean; mypy cold cache 24 errors in 9 files, the recorded baseline, net zero; pyright 0 errors on the 23 backend files and the 2 bench files; go build/vet/test and gofmt clean; npm run build 221.39 kB with eslint exit 0; bench/filesize_check clean; bench.audit --product clean over 31 harness files; scripts/mcp_write_smoke.sh PASS with the gate live across two servers and the MCP child.
This commit is contained in:
1 parent
8b974e6626
commit
9145a23f18
32 files changed
+750
-58
No files matched your search
@@ -17,8 +17,9 @@ class CacheFabric:
|
||||
self.settings = settings or get_settings()
|
||||
self.db = database or Database(self.settings)
|
||||
|
||||
def semantic_key(self, question: str, profile: str) -> str:
|
||||
return hashlib.sha256(f"compiler-v2\n{profile}\n{question}".encode()).hexdigest()
|
||||
def semantic_key(self, question: str, profile: str, store_revision: int) -> str:
|
||||
"""A compiled context is only true for the corpus it was compiled from, so the corpus is part of its name."""
|
||||
return hashlib.sha256(f"compiler-v2\n{profile}\n{store_revision}\n{question}".encode()).hexdigest()
|
||||
|
||||
def record_hit(self, layer: str, cache_key: str, bytes_estimate: int = 0, metadata: dict[str, Any] | None = None) -> None:
|
||||
self.db.log_cache_event(layer, cache_key, "hit", bytes_estimate, metadata)
|
||||
@@ -43,6 +44,16 @@ class CacheFabric:
|
||||
except (OSError, json.JSONDecodeError) as error:
|
||||
raise ValueError(f"{path}: the semantic cache entry is unreadable ({error})") from error
|
||||
|
||||
def drop_semantic_cache(self) -> int:
|
||||
"""Delete every compiled context: each one may quote a memory that no longer exists."""
|
||||
directory = self.settings.cache_dir / "semantic"
|
||||
if not directory.exists():
|
||||
return 0
|
||||
entries = list(directory.glob("*.json"))
|
||||
for path in entries:
|
||||
path.unlink()
|
||||
return len(entries)
|
||||
|
||||
def statuses(self) -> list[CacheLayerStatus]:
|
||||
rows = self.db.cache_layer_rows()
|
||||
statuses: list[CacheLayerStatus] = []
|
||||
|
||||
Reference in new issue
Block a user