host: blog post CRUD (list/create/update/delete) + fail-loud test runner, 175/175
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 37s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 37s
CRUD on the durable content store, per-request IO:
GET /posts list (public) -> [{slug,title}]
GET /<slug>/ read (public) -> HTML / 404
POST /posts create (auth+ACL edit/blog) -> 201/400/409
PUT /posts/<slug> update title+body -> 200/400/404
DELETE /posts/<slug> delete (truncate) -> 200/404
Writes behind the auth+ACL pipeline; create=insert ops, update=op-updates,
delete=stream truncate. 16 new CRUD tests (full lifecycle + 401/403/409/404).
GOTCHA fixed: is a reserved CEK special form — a (let ((guard ...)))
helper was shadowed by it ((guard h) ran the guard special form -> 'first:
expected list'). Renamed to host/blog--protect; namespace-prefix all helpers.
HARDENING: conformance.sh now FAILS LOUD on load/eval errors. A test file that
errors mid-load silently truncates its suite and reports a false green (this hid
the CRUD failure as 'blog 13 passed, 0 failed'). The runner greps for error
markers and aborts. Documented the SX gotcha set + prevention ladder in the plan.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -288,6 +288,32 @@ lib/host/sxtp.sx subsystem APIs (feed/search/commerce/…
|
||||
(docker stack + Caddy) remains. NEXT: golden harness, internal-HMAC, then promote
|
||||
into the stack behind a fresh subdomain.
|
||||
|
||||
## SX gotchas + how this loop guards against them
|
||||
|
||||
The SX dev experience has real footguns. Most are statically detectable; the
|
||||
tools exist (`sx_validate`, `deps-check`, `sx_format_check`) but must be *gated*.
|
||||
Hit/relevant here:
|
||||
- **Reserved-name shadowing** — `guard`/`bind`/`conj`/`disj` are special forms or
|
||||
host primitives; a local binding of that name is silently shadowed by the form.
|
||||
(`(let ((guard ...)))` made `(guard handler)` invoke the R7RS `guard` special
|
||||
form → `first: expected list`.) Fix: namespace-prefix every helper
|
||||
(`host/blog--protect`, never `guard`).
|
||||
- **Silent test truncation** — a test file that errors mid-load returns only the
|
||||
tests that ran before the error, reporting a FALSE GREEN ("blog 13 passed, 0
|
||||
failed" while 16 CRUD tests never ran). **GUARDED**: `conformance.sh` now greps
|
||||
the run output for `Undefined symbol` / `Unhandled exception` / `expected list,
|
||||
got` / `[load] … error` and aborts loudly before the tally can hide it.
|
||||
- **`let` is parallel** (bindings can't see each other), **bodies need `(do …)`**
|
||||
(only the last expr evaluates), **`append!` no-ops on map/rest-derived lists**,
|
||||
**parsed keyword tokens ≠ string literals**. These produce wrong *results*, so
|
||||
test coverage catches them as red (not silent) — provided the runner is honest,
|
||||
which the truncation guard now ensures.
|
||||
|
||||
Prevention ladder: parse (`sx_validate` after every edit) → unresolved/shadowed
|
||||
symbols (`deps-check`, candidate pre-commit gate) → fail-loud runner (done) →
|
||||
behavioural tests. A `deps-check`-style "binding shadows a special form" lint
|
||||
would catch the reserved-name class before runtime — a worthwhile follow-up.
|
||||
|
||||
## Blockers
|
||||
|
||||
- **Live wiring to the native OCaml HTTP server** (Phase 3/4): the prod server in
|
||||
|
||||
Reference in New Issue
Block a user