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
@@ -7,6 +7,8 @@ home="$(mktemp -d)"
|
||||
port="${PORT:-8799}"
|
||||
export ELY_EYE_HOME="$home"
|
||||
export ELY_EYE_API="http://127.0.0.1:${port}"
|
||||
# The server decides who may write; the MCP child inherits this and sends it on every mutation.
|
||||
export ELY_EYE_AUTH_TOKEN="smoke-token"
|
||||
|
||||
python_bin="$root/.venv/bin/python"
|
||||
[ -x "$python_bin" ] || python_bin="python3"
|
||||
@@ -47,6 +49,22 @@ if [ "$ready" -ne 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The gate, proved before anything else: a query needs nothing, a write needs the token.
|
||||
status="$(curl -s -o "$home/refused.json" -w '%{http_code}' -X POST "http://127.0.0.1:${port}/api/memory" \
|
||||
-H 'content-type: application/json' -d '{"text":"a write with no token"}')"
|
||||
if [ "$status" != "401" ]; then
|
||||
echo "FAIL: an untokened write returned HTTP $status, want 401"
|
||||
cat "$home/refused.json"
|
||||
exit 1
|
||||
fi
|
||||
status="$(curl -s -o /dev/null -w '%{http_code}' -X POST "http://127.0.0.1:${port}/api/memory" \
|
||||
-H 'content-type: application/json' -H "Authorization: Bearer ${ELY_EYE_AUTH_TOKEN}" \
|
||||
-d '{"text":"a write with the token"}')"
|
||||
if [ "$status" != "200" ]; then
|
||||
echo "FAIL: a tokened write returned HTTP $status, want 200"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
(cd "$root/ely-eye-mcp" && go build -o "$home/ely-eye-mcp" ./cmd/ely-eye-mcp)
|
||||
|
||||
# A second principal on the same SQLite file. The server, not the client, decides who a memory
|
||||
@@ -66,12 +84,15 @@ if [ "$ready" -ne 1 ]; then
|
||||
fi
|
||||
secret="护照在书房第二个抽屉里"
|
||||
curl -sf -X POST "http://127.0.0.1:${wife_port}/api/memory" -H 'content-type: application/json' \
|
||||
-H "Authorization: Bearer ${ELY_EYE_AUTH_TOKEN}" \
|
||||
-d "{\"text\":\"${secret}\",\"scenario\":\"home\"}" >/dev/null
|
||||
curl -sf -X POST "http://127.0.0.1:${wife_port}/api/holders/wife" -H 'content-type: application/json' \
|
||||
-H "Authorization: Bearer ${ELY_EYE_AUTH_TOKEN}" \
|
||||
-d '{"name":"小美","kind":"person","knows_about":["护照"],"contact":{"channel":"signal","address":"+86-555"}}' >/dev/null
|
||||
|
||||
printf 'the pantry keeps flour\n' > "$home/pantry.txt"
|
||||
uploaded="$(curl -sf -X POST "http://127.0.0.1:${port}/api/ingest/upload?cartridge_name=home" \
|
||||
-H "Authorization: Bearer ${ELY_EYE_AUTH_TOKEN}" \
|
||||
-F "files=@${home}/pantry.txt;type=text/plain")"
|
||||
cartridge_id="$(printf '%s' "$uploaded" | "$python_bin" -c 'import json,sys; print(json.load(sys.stdin)["cartridge_id"])')"
|
||||
if [ -z "$cartridge_id" ] || [ "$cartridge_id" = "None" ]; then
|
||||
|
||||
Reference in new issue
Block a user