artdag: job-as-post-object projection (post.sx) + 12 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 47s

lib/artdag/post.sx — the artdag-side projection for 'a job is a type of post' (per the
host loop). job->post-object: {:type artdag/job :id <output content-id> :wire <dag->wire>},
post-id = content-id = natural AP object id. post-object-verify binds the id to the payload
(record ids recompute + post id present), rejecting tampered params/bogus ids. String
transport for the feed/SXTP body; post-run lets a peer decode->run->result, content-address
cache-hitting. Activity wrapping stays host-side. post 12/12, total 225/225.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-28 18:38:34 +00:00
parent 550d0db5a5
commit 0b7b3b9efb
6 changed files with 208 additions and 9 deletions

View File

@@ -31,7 +31,7 @@ edges.
## Status (rolling)
`bash lib/artdag/conformance.sh`**213/213** (12 suites: dag, analyze, plan, execute, optimize, fed, cost, serialize, stats, fault, maude-optimize, schedule)
`bash lib/artdag/conformance.sh`**225/225** (13 suites: dag, analyze, plan, execute, optimize, fed, cost, serialize, stats, fault, post, maude-optimize, schedule)
Base roadmap (Phases 16) COMPLETE + Phase 7 (maude rule-based optimization) COMPLETE
(only optional miniKanren scheduling remains). Now hardening only.
@@ -117,10 +117,14 @@ loop's `GET/POST /feed`. The engine already has the primitives; the wrapping liv
- **federation already mirrors the feed** — `fed-export`/`fed-import` are trust-gated with
provenance; a re-posted job dedupes/cache-hits by global content-id.
Boundary: host loop owns the `dag ⇄ feed-object` adapter; `lib/artdag` stays the engine.
Candidate artdag-side affordance (only if wanted here): a thin `job->post-object` /
`post-object->job` projection so host never reaches into wire internals. Not yet built —
flagged, not scheduled.
Boundary: host loop owns the activity wrapping (actor/verb/at/tags); `lib/artdag` owns the
job⇄object projection. **BUILT — `lib/artdag/post.sx`** (post suite 12/12): a post object is
`{:type "artdag/job" :id <output content-id> :wire <dag->wire>}``job->post-object`,
`post-object->job`, `post-object-verify` (wire ids intact + the post id is produced by the
job; rejects tampered params and bogus ids), `job->post-string`/`post-string->object` for the
feed/SXTP body, and `post-run` (a peer decodes → runs → result at the post id, content-address
cache-hitting what it already has). The host loop drops the object into a feed activity's
`:object`; post-id = content-id = the AP object id.
## Phase 1 — DAG model + content addressing
@@ -237,6 +241,19 @@ be an op token.
## Progress log
- **2026-06-28 Forward — job as a feed post object** (post suite 12/12, total 225/225).
`lib/artdag/post.sx`: the artdag-side projection for "a job is a type of post" (per the
host loop). `job->post-object dag output-name``{:type "artdag/job" :id <content-id of
output> :wire <dag->wire>}` — the post/object id IS the output node's content-id (= the
natural AP object id), the body is serialize.sx's self-describing wire. `post-object-verify`
binds the claimed id to the payload (every record's id recomputes + the post id is present
among them) — rejects a param tampered under a stale id and a bogus post id.
`job->post-string`/`post-string->object` carry it in a feed activity / SXTP body;
`post-object->job` decodes; `post-run post runner cache` lets a peer decode → run → read the
result at the post id (content-addressed, so a warm peer cache-hits what it already holds).
The activity wrapper (actor/verb/at/tags) stays on the host/feed side — this is only
job⇄object. Reuses serialize.sx + execute.sx; no new substrate.
- **2026-06-28 Phase 3/7 — miniKanren CLP(FD) scheduler** (schedule suite 15/15, total
213/213). `lib/artdag/schedule.sx` on `lib/minikanren` (read-only substrate): each node
gets a slot var in `[1..max-slots]`, every edge `(input->node)` imposes `fd-lt