Commit Graph

2 Commits

Author SHA1 Message Date
CIAgent 12b2300f6f fix(P07): final review — CORS PUT, WS origin gate, ingest leak+O(n²), symlink escape, retry leak, doc-reality gaps
---ci---
phase: 7
milestone: v0.3
status: review
lessons:
  - P0 CORS: allow_methods lacked PUT while the build surface writes files with PUT — every cross-origin Save failed preflight; pinned with tests/api/test_cors.py
  - P0 ingest leak: queue-overflow flood path returned without the disconnect sentinel, parking the drainer forever (one leaked task-set per flooded trace); sentinel now always enqueued, real-server regression test added
  - P1 perf: flood cap counted rows via len(get_trace(...)) — O(trace) per append, O(n²) per session; TraceStore.count() (COUNT(*)) added and wired
  - P0 security: file routes followed exec-planted symlinks out of the workspace bind; _resolve_in_workspace refuses escapes (422), read/write now 404 on unknown sandboxes (was 500)
  - P1 security: WS ingest accepted any browser Origin (CORS middleware does not cover WS); localhost dev origins + no-Origin (capture agent) allowed, others 1008
  - P1 correctness: use-sandbox-session leaked a created sandbox on any mid-start failure (per-learner cap 1 → all retries 429 forever); failed starts now destroy what they created
  - P2 testing: reconnect-flush test killed mid-burst (nondeterministic under load, reproduced on pre-change code); now waits for server-side observation of the pre-kill burst — the underlying one-line replay-margin/ACK gap is documented for v0.4
  - maintainability: grading-store/templates/grading.ts docstrings claimed grading is variant-blind (stale pre-P4 text) — updated; ARCHITECTURE.md referenced nonexistent voice/openai_audio.py; dead if TYPE_CHECKING: pass blocks removed
---/ci---
2026-09-12 20:02:10 +00:00
CIAgent b6850fc036 feat(P02): in-sandbox capture agent + websocket ingest (Wave 2)
Task 2-2-01: sandbox-agent.py stdlib-only (D-031) — shell capture (command/file_diff/
run_result/test_result/stdin/stdout), per-task monotonic seq, JSONL fsync spool (at-least-once,
D-026), raw-socket RFC6455 client (no websockets in-namespace), exponential-backoff reconnect,
SIGKILL-safe. Loopback tests: ordered emission, spool-on-disconnect, reconnect flush order,
stdlib-only AST scan.

Task 2-2-02: WS /v1/telemetry/ingest (D-026) — query-param identity (extra=forbid frames),
server-side dedup on (learner,task,seq), gap detection + warnings, ping keepalive. G-3 flood
control: overflow or >50000 events/task -> 1008 close + trace marked INCOMPLETE_FLOODED
(terminal, Proctor signal); no silent drop. GET traces + gaps endpoints. TraceIntegrityMap
(process-local, D-019 precedent) exposes is_incomplete for the Phase 3 grader gate (G-4).

214/214 + ruff clean.

---ci---
phase: 2
milestone: v0.3
status: execute
requirements: {covered: [REQ-3-003], partial: []}
---/ci---
2026-09-12 00:47:45 +00:00