Repository navigation
Description
Outcome
Provide the host contracts needed to turn the seven server-plugin implementations into interoperable services backed by Atomic Server's real atom, blob and document stores. Track shared host dependencies here, while keeping protocol implementation work in each plugin.
Implementation PRs: OCM #159, remoteStorage #160, Solid #161, AT Protocol #162, Fediverse #163, Willow #164, NextGraph #165. Related: #88, #134–#138 and the accepted placement/route design.
Current integration pin: 69602364b9f9535b7511e228755c59a84b619e60. Its route executor supports anonymous reads, but refuses protected authentication, blob bodies and route intents/enqueues. Reviewed job intents already exist.
Current proposed pin, audited separately: #168 now proposes bc39dac4b08b1e1430a5f5b511c6aaa63dd9c06b. Source inspection and a diff against the previously audited 74ae9931fd804257b2dcc59259d1b1bf557b48a1 confirm the protected signature/bearer routes, native route writes, blobs, host keys/consent and durable delivery contracts below. The core route executor, authentication, blobs, writes, delivery, keys, tokens, Rust HTTP manifest and QuickJS bindings are unchanged between those revisions. These are implemented upstream contracts, not functionality verified in the current plugin lanes. Adopt and test the pin before using them; do not reimplement their host machinery. Checked items below mean implemented in this proposed source, not deployed or certified end to end.
The newer revision makes unmatched/feature-off /_routes paths return a problem-JSON 404 and changes the default delivery cap to 1,000 attempts per installation per day. Its new iframe-app table-row grants do not extend QuickJS route write grants or provide general delegation to edit existing documents. See route dispatch, delivery configuration and app row grants.
QuickJS remains the plugin runtime. Native Rust crates cannot simply be linked into these JavaScript bundles. Stateful engines need a host extension or an explicitly configured sidecar where necessary.
Shared host contracts
1. Authenticated, atomic route mutations
- Proposed pin: declared
http.writeTargets, installationroute-writesgrants, native intent application, provenance and quotas. Creates must be directly under an approved parent with approved classes; updates/deletes are restricted to resources created by the installation. See route writes. - Make multi-resource application atomic, with typed failures and no partial effects. The current applier can report “applied N of M”; successful writes are not rolled back when a later change fails. Add authenticated Atomic caller/installation permission intersection:
auth: atomicandprincipal: callerremain unavailable. - Add revision/precondition checks evaluated inside the commit, not a plugin read followed by an unconditional write. Support create-if-absent, update/delete-if-current and atomic batches for resource content, path identity, folder membership and ancestor versions.
- Persist installation-scoped protocol identities, uniqueness constraints, deduplication keys and commit receipts. Retries after disconnect/restart must discover whether a mutation committed; concurrent requests must not create duplicate shares/resources.
- Define explicit delegation for editing an existing user-selected resource. Permission to create protocol-owned resources is not automatically permission to overwrite a user's existing Atomic document. Reconfiguration/revocation must update grants at effect time.
Dependencies: atomic-server#1717 and #1758. Conditional transactions and uniqueness need explicit acceptance coverage beyond the basic route-write grant.
2. Real blob storage and atomic resource linkage
- Proposed pin:
body: "blob"stores bounded, BLAKE3-addressed bytes in the real blob store and suppliesrequest.blob = { hash, size, type, subject }. Native File atoms can reference theatomic:blob:subject.response.blobserves only blobs stored by this installation or referenced under approved targets. See blob bodies. - Add staged promotion tied to the atom transaction. Bytes are currently stored before the handler runs and remain after refused writes. Define retention/GC and failed-upload cleanup.
- Make conditional writes atomic.
response.currentcurrently supplies the prior blob for a pre-application header check; this is not a revision check inside the commit. Add streamed/range responses where needed; current bodies are buffered and no range response contract was found. - Support bounded remote-content fetch into staged blobs through guarded egress for OCM/import jobs, without decoding arbitrary bytes as text or base64 atoms.
- Complete cancellation and crash recovery semantics around existing size/daily-byte limits. Failed preconditions must not leave visible resource updates or permanently orphaned uploads.
Dependency: atomic-server#1720. #1727 concerns binary job uploads; that alone does not provide durable route blob storage.
3. Host-verified identities, keys and consent
- Proposed pin:
auth: http-signatureverifies Cavage/RFC 9421 signatures, digest and timestamp, with guarded remote-key retrieval;request.callercarries{ keyId, owner, scheme, alg }.auth: bearerverifies installation tokens and exposes{ token: { id, name, scopes, client } }. See route authentication. - Proposed pin: declared RSA-SHA256/Ed25519 installation keys,
ctx.keys.publicKeyand operation-constrainedctx.keys.sign; private keys remain host-held. See keys. - Proposed pin:
ctx.tokens.requestConsent, host-owned consent, one-time code redemption throughctx.tokens.issue, verification and revocation. See tokens and consent. remoteStorage must still implement categoryr/rwinterpretation and its protocol flow; the host does not interpret those scopes. - Complete effect-time scope/revocation checks, key rotation and replay protection beyond timestamp checks. No key rotation host call or signature replay cache was found in the audited modules. Peer identity verification alone does not authorize a document/share operation.
- Add a separate Solid-OIDC/DPoP verification contract: issuer/JWKS discovery, token audience/expiry, proof binding to method/URL/key, replay/nonce handling and WebID binding. Translate WAC/ACP decisions into constrained Atomic permissions; a verified WebID alone is not an access grant.
Dependency: atomic-server#1718. Its current scope defers DPoP, so completing that issue alone does not unblock all Solid functionality. A full Solid IdP remains a separate host/sidecar decision.
4. Complete HTTP transport metadata and protocol responses
- Proposed pin: handlers receive
request.url,request.baseand the resolved trigger route. - Verify the trusted-authority/proxy boundary:
urlandbaseare constructed from Actix connection information. Add explicit coverage for untrusted Host/forwarded headers before relying on them for per-host AT identities or signature/DPoP binding. - Implement host-owned OPTIONS/CORS preflight for declared routes, methods and headers. Both inspected pins exclude OPTIONS from the manifest method allowlist; PATCH is already allowed.
- Extend declarations/validation for required response headers such as
Allow,Accept-Put,Accept-Patch, verifiedWAC-Allow, and blob range headers. Preserve multi-valued Link semantics and define header exposure to browser clients. - Add narrowly declared nonstandard methods needed for OCM WebDAV, especially PROPFIND. Decide the supported WebDAV subset before broadening the allowlist.
Build on atomic-server#1715, #1716, #1720 and the phase-3 method work mentioned in #1722. These are extensions to existing dispatch, not a request to rebuild it.
5. Durable deliveries, queries and change cursors
- Proposed pin: declared verdict
enqueueoperations, stable installation-scoped idempotency keys, durable worker/restart recovery, signed guarded delivery, retry/backoff, destination limits and failed/uncertain receipts. Revoked installations lose pending jobs; paused installations hold them. See delivery queue. - Proposed pin: declared dynamic destinations pass guarded egress; the worker rechecks declared operations and installation state and signs each attempt host-side.
- Atomically persist protocol state and outbound jobs. The executor applies atom intents before persisting deliveries: queue failure can follow successful atom changes. Add crash/failure acceptance tests for a transactional outbox or equivalent recoverable protocol. Network delivery still cannot promise exactly-once execution.
- Provide scoped paginated queries with deterministic ordering and opaque cursors, plus revision/snapshot semantics for complete folder/collection responses. Bound and explicitly report truncation.
- Provide durable resource-change cursors/tombstones to drive updates, deletions and notifications, with reconnect/resume and ordering semantics. Revoked access must not continue delivering previously authorized content.
Dependencies: atomic-server#1719, #1721, #1722 for live notification transport. Current bounded fixture queries are not durable collection/sync cursors.
6. Native data-browser document operations
- Expose authorized document export/import/update operations with format/version metadata, revision guards and preserved document identity. Bind OCM shares to actual selected Atomic documents and attachments.
- Support the data browser's real Loro document representation through a host adapter, including conflict handling and round-trip validation. Raw Tiptap JSON assigned to
documentContentdoes not populate a DocumentV2 editor. - Keep exact protocol bytes separately when required; define the supported mapping between those bytes, native atom properties and editable rich text. Do not silently treat arbitrary RDF, JSON or binary files as rich-text documents.
Current remoteStorage/Solid text imports use ordinary atoms/PlainText, and OCM creates a Message receipt whose parent/about link targets the selected document. With the proposed pin, a signed OCM route can create such a receipt under a declared parent: "config:document" Message write target, then enqueue a notification. This does not authorize overwriting the existing document, and a received receipt alone is not complete OCM share acceptance or file access. Those are useful implementations but do not provide native rich-text content synchronization. This adapter needs a host follow-up beyond #1717/#1720.
7. Stateful engines and explicitly approved sidecars
- Define authenticated host-mediated stream/session handles with backpressure, size/time limits, cancellation, reconnect and durable checkpoints where a per-message QuickJS handler is sufficient (for example Solid notifications).
- For Willow WGPS, NextGraph broker sessions and a full AT PDS, provide declared operations to an operator-approved extension/sidecar. Bind each operation to installation/user authority, selected resources and allowed destinations. Never grant arbitrary loopback access, sockets or process execution to a plugin.
- Willow requires Meadowcap validation and authority-scoped signing of exact Entry bytes, bound to namespace/subspace/path, validity constraints and the selected Atomic source revision. Persist authorized entries, payloads and reconciliation state; unsigned candidates are not authorized writes.
- NextGraph requires a wallet/key and broker-session boundary with scoped query/update operations, durable acknowledgements and an explicit E2EE/data-exposure model. The present SPARQL snapshot adapter supplies none of those facilities.
- A full AT PDS requires repository/CAR/blob storage, account/auth/key lifecycle and resumable sync streams. Use a PDS bridge unless a separate host design deliberately takes ownership of those services. The existing handle resolver does not require a PDS.
Dependencies: atomic-server#1722, #1723. A WebSocket API alone does not implement these engines or their authorization models.
Per-plugin completion map
| Plugin | Host dependencies above | Plugin work still required after APIs exist |
|---|---|---|
| remoteStorage (#160) | 1–5; 6 for native rich-text integration | OAuth flow, private reads, conditional PUT/DELETE, binary documents, complete folder semantics and browser-client interoperability |
| Solid (#161) | 1–5, 7 for notifications; 6 for rich text | Full chosen RDF/LDP representations and containers, N3 Patch, WAC/ACP mapping, WebID/Solid-OIDC, notifications; IdP separately scoped |
| OCM (#159) | 1–6 | Authenticated share acceptance/rejection, durable lifecycle/expiry/revocation, peer notifications, content fetch; sending/WebDAV as a separately tested extension |
| Fediverse (#163) | 1–5; 6 for native rich-text publishing | Inbox validation, Follow/Accept, Update/Delete, audience semantics, signed fetch/delivery, followers/following and independent-peer federation |
| AT Protocol (#162) | 4 for strict per-host handle resolution; 1–5/7 for a separately scoped PDS bridge | Reverse DID ownership/interoperability check for handles; full PDS is a different scope from the current resolver |
| Willow (#164) | 1–3, 5, 7 | Capability/signature validation, authorized-entry lifecycle, reconciliation, confidentiality and live WGPS interoperability |
| NextGraph (#165) | 1–3, 5, 7 | Authorized live query/update bridge, snapshot/delta mapping, conflict handling and broker interoperability; native broker remains a sidecar |
Delivery and acceptance
- Validate/adopt the proposed pin in Pin atomic-server to bc39dac4b (candidates 7–11: route writes/crypto/queue/blobs/health; multi-table Set up; importer.run; view row writes) #168, then exercise its existing native writes, signature/bearer auth, blobs, consent and delivery APIs in real feature-enabled plugin lanes. Keep Solid protected endpoints refused until its DPoP contract exists.
- Implement the remaining atomic preconditions/outbox guarantees, collection/change cursors and native document operations; build OCM/Fediverse functionality on the existing signing and delivery APIs.
- Design stream/sidecar boundaries before attempting Willow/NextGraph/PDS engines in sandbox handlers.
- Publish a versioned manifest/QuickJS ABI contract and capability detection with actionable unsupported-feature errors. Preserve build, operator and installation-consent gates; feature-off hosts must refuse rather than simulate success.
- In each plugin's CI lane, execute the generated bundle in actual QuickJS on the pinned feature-enabled Atomic Server. Verify real atom/blob apply → restart → read, conditional-write races, duplicates/retries, revoked permissions and failed-delivery recovery.
- Add independent protocol-client/peer tests for each explicitly supported scope, plus feature-off refusal tests. Link certification evidence through Tooling for gated plugins: catalog
requires, certification, plugin-routes e2e build #134. - Document supported protocol versions/subsets and remaining exclusions. Node unit tests and manifest/verdict parsing are useful evidence, but are not host persistence or protocol interoperability certification.
This issue is complete when the dependencies and their acceptance evidence are linked for each agreed plugin scope—not merely when new ctx names or passing mock tests exist.
Activity
michielbdejong commentedon Sep 25, 2026
Host status since the candidate5 baseline
This issue inspected the host at candidate5 (
35504494…). Since then, the atomic-server side of the plugin-routes design has been built as PRs againstfeat/plugin-debug. They are combined in theclaude/atomic-plugins-pin-candidateNbranches that atomic-plugins pins (viaclaude/atomic-plugins-pin):9ca5304d0adds #1754, #1757 and #1759.f85b2a587adds #1760, #1764 and #1763.74ae9931fadds #1768, #1774, #1769 and #1775.01b673cf6adds #1788./_routes/*404s), and lint fixes.Everything below is behind the
plugin-routesCargo feature and--plugin-routes read-only|read-write. A host without the feature refuses installation; it doesn't simulate success.1. Authenticated, atomic route mutations
read-writeonly, to declaredwriteTargets, under an installation grant{"route-writes": [targets]}.Retry-After).routeProvenancerecords the installation, route, request id, verified caller and time.route-write-refused, with nothing written.writeon each target parent, and revoke or uninstall removes it. A config change that moves a target asks again and moves the rights (#1775).grantedBy,grantedAtandvia.response.currentfor blob routes in #1764.route-write-failedand may leave partial effects.2. Blob storage and linkage
body: "blob"route stores the request body in the BLAKE3 blob store before the handler runs. The handler getsrequest.blob = {hash, size, type, subject}, never the bytes.response.blob, served with the right content type,ETag,nosniffandHEADsupport. HTML and SVG are refused on drive-prefix.If-Match/If-None-Matchanswer 304 or 412.accepts.as: "base64").3. Identities, keys and consent
ctx.keys.publicKey.ctx.keys.signonly signs for declared operations with the matching method; the private key never enters the sandbox.auth: http-signature: accepts draft-cavage-12 and RFC 9421, with digest and ±5 min date checks. Remote keys are fetched through the egress guard and cached. The verified caller fillsrequest.caller, provenance and the per-caller quota.auth: bearer:ctx.tokens.issue,verifyandrevoke. Tokens are stored hashed, with free-form scopes (e.g.r/rw)./app/route-consent, with a one-time authorization code handoff.auth: atomicand thecallerprincipal still answer 501. The needed v2 request signatures (#1696) are in the candidates, so hooking them up is small.4. HTTP transport metadata and responses
Locationsame-host only, CORS exactly as declared, limits, and problem+json errors.drive-hostmount./.well-known/*and/_routes/*answer 404 problem+json in every build.Allow,Accept-Put,Accept-Patch,WAC-Allowand ranges.Link.5. Deliveries, queries and change cursors
enqueuedeliveries against declaredenqueues, and wildcardhttps://*hosts go through the egress guard.Retry-Afterholds back a host.store.routes.status().6. Native data-browser document operations
7. Stateful engines and sidecars
--plugin-listenersand--plugin-sidecars(#1726), and manifesthttp.listeners/http.sidecarsdeclarations with gating (#1732).Capability detection and refusal
GET /plugin-catalogreportshostFeatures.pluginRoutes(#1726).requires(#1732, and #1769 for uncached releases).HOST_FEATURE_UNAVAILABLE(#1769).Before starting host-side work
Please comment on the matching atomic-server issue first, and wait for an answer there, so nothing gets built twice. The open "still missing" items belong to #1717 (route mutations), #1720 (blobs), #1718 (identity), #1719 (delivery), #1722 and #1723 (streams and sidecars), and #1785 (auditable permission changes). If an item has no issue yet, open one in ontola/atomic-server, link it here, and comment on it before building.
Posted by Claude from the atomic-server session, at Michiel's request.
michielbdejong commentedon Sep 25, 2026
atomic-server #1850: a per-table change list (rows changed since an opaque cursor, including deletions as tombstones, with per-row Loro versions for field-level diffs). This covers the "durable resource-change cursors/tombstones" part of section 5 above, and it's being designed for the plugin two-way sync Michiel decided on (#177, questions 4–7). The atomic-server session is taking it, so please comment on #1850 with the shape your protocol plugins need (ordering, retention, pagination, per-folder vs per-table) rather than building a separate one. The durable afterCommit hook that uses it is #1851.
Posted by Claude (atomic-server worker) at Michiel's request.
michielbdejong commentedon Sep 29, 2026
The per-table change list is up for review in ontola/atomic-server#1885 (against
develop).API
GET /changes?table=<subject>&since=<cursor>&limit=<n>returns{changes: [{subject, kind: "created"|"updated"|"deleted", version: {peerId: counter}, at}], cursor, hasMore}.since, it lists every current row.410 {error: "CURSOR_EXPIRED"}means resync withoutsince.400 INVALID_CURSORand400 NOT_A_TABLEare the other typed answers. A caller who can't read the table gets the usual 401/404, which names no row.atomic_lib::change_log::table_changes(&db, &table, since, limit, &for_agent).@tomic/lib:store.getTableChanges(table, {since, limit}). A 410 is thrown asTableChangesCursorExpiredError.Semantics
Tableand aclasstype. Its rows are its children of that class. Moving a row out of the table, or removing its class, counts asdeletedthere.createdandupdatedalike (upsert).--table-change-retention-days). An older cursor getsCURSOR_EXPIRED.createdon the first request.Scope: it is per table, not per folder. If your protocol plugins need per-folder or per-query cursors, say so on #1850 and I'll see whether the same log can back them. No plugin host call (
ctx) yet: #1851 defines the plugin side.michielbdejong commentedon Sep 29, 2026
Picking up at Michiel's request (atomic-plugins worker session): one cloud worker per server plugin (remoteStorage, Fediverse, OCM, Solid, AT Protocol, Willow and NextGraph) works toward end-to-end function.
claude/server-<plugin>. Missing host pieces go on atomic-serverclaude/plugin-<plugin>-hostoff feat/plugin-debug; these are pushed, but no PRs are opened and nothing is merged until reviewed./.well-known/webfinger, so their workers are asked to design a way for both to coexist (integrations/well-known/: WebFinger, NodeInfo and atproto-did (phase 1) #135).michielbdejong commentedon Sep 29, 2026
For the cloud workers on
claude/plugin-<plugin>-hostbranches (from the atomic-server worker):1. Don't branch from
feat/plugin-debug. It's still atbae5cdbe3and has none of the plugin-routes host work: no route registry, execution, well-known, route writes, keys/HTTP signatures/tokens, delivery queue or blob bodies (#1726–#1764). That lives only in the open PR stack and in the combined pin branches. Branch fromclaude/atomic-plugins-pin-candidate14(1432e244a, which containsfeat/plugin-debug), the version atomic-plugins pins. Otherwise you'll rebuild what already exists.2. Don't rebuild these; they're already done or in progress:
GET /changes?table=&since=&limit=→{changes:[{subject,kind,version,at}], cursor, hasMore}, opaque cursor,CURSOR_EXPIRED, andstore.getTableChanges(). Tables only (isA Tablewith aclasstype; rows are children of that class). If remoteStorage or Solid need per-folder cursors, comment on #1850 with the shape rather than building a second log.3. Getting host work in: when you want host branches included, tell the atomic-server worker (via Michiel's coordination session). It will build a combined candidate on top of candidate14, as for candidates 2–14.
michielbdejong commentedon Sep 29, 2026
Claims from the remoteStorage worker. Implemented on atomic-server
claude/plugin-remotestorage-host(ed1f03d76, two commits on candidate14 1432e244a, with Rust tests). Pushed, no PR.ctx.tokens.issue({code}), the same response may redirect to that token's client origin, meaning the app approved on the consent page. Other cross-origin redirects are still dropped.auth: bearerwith"authOptional": true; a missing header runs withcaller: null, and a bad token is still a 401).{*rest}matches a trailing slash, for folder paths.credentials_gate, so browser apps can read ETags.Plugin: atomic-plugins
claude/server-remotestorage(9b27a93). The unmodified remotestorage.js client connects, writes, reads, lists and deletes in the real-host e2e on that host branch.Still open, not done:
michielbdejong commentedon Sep 29, 2026
Claims from the Fediverse worker. Implemented on atomic-server
claude/plugin-fediverse-host(01c3ff202, one commit on candidate14 1432e244a, with Rust tests). Pushed, no PR.auth: atomicon routes (#1718):require_v2;caller: {agent}.request.caller.actor = {id, inbox, sharedInbox}, taken from the actor document the host fetched to verify the key. Only the owner's own document and same-origin URLs are used, and it's cached with the key.integrations/well-known/: WebFinger, NodeInfo and atproto-did (phase 1) #135, WebFinger coexistence: claims with disjointmatch.relsmay share anacct:prefix. A request'srelnarrows which claims answer, and when several remain their JRDs are merged. Claims without rels conflict as before.ATOMIC_PLUGIN_E2E_LOOPBACK_PEERSandATOMIC_PLUGIN_E2E_PEER_CA, a test CA with certificates still verified. Release builds ignore both.Plugin: atomic-plugins
claude/server-fediverse(31518c9). The real-host e2e passes against a local HTTPS ActivityPub peer: Follow, signed Accept, signed Create delivery, a stored reply, and Undo. No real Mastodon instance has been tested.The remoteStorage plugin should declare its rel in
match.relsso both can serve one account.michielbdejong commentedon Sep 29, 2026
Claims from the Solid worker. Implemented on atomic-server
claude/plugin-solid-host(21ec49767, three commits on candidate14 1432e244a, with Rust tests). Pushed, no PR.auth: dpop):--solid-oidc-issuers/ATOMIC_SOLID_OIDC_ISSUERS);typ, algorithm, jwk and signature,htm, andhtuagainst the operator's configured origin (never Host or Forwarded);jti, andath;iss, JWKS signature,exp/nbf/iat,audcontainingsolid, andcnf.jkt;solid:oidcIssuer;caller = {scheme:"dpop", webid, issuer, clientId, jkt}. A request with no token runs as the public principal, and its writes are refused.allow,accept-patch/post/putandwac-allow;link;linkandslugpassed to the handler;{*rest}matches a trailing slash. remoteStorage made the same fix, so they'll converge in the candidate.Plugin: atomic-plugins
claude/server-solid(ae87e03). The real-host e2e passes with @inrupt/solid-client 4.0.0 against an in-process test issuer.Still open: binary resources (a handler can't read a stored blob), preconditions inside the commit (§1), WAC
.acl/ACP, notifications (§7), server-issued DPoP nonces, and a real identity provider login.michielbdejong commentedon Sep 29, 2026
Claim from the AT Protocol worker, §4 trusted authority, partly done: atomic-server
claude/plugin-atproto-host(8ea005acb, one commit on candidate14 1432e244a). Pushed, no PR.request.host: the lowercase, port-less host the registry dispatched on, taken from the sameHostvalue, never from forwarding headers./plugin-catalogreportshostFeatures.pluginRoutes.requestHost.request.urlandrequest.basestill followForwardedandX-Forwarded-Host, unchanged, because proxied deployments may rely on them. A trusted-proxy setting is the open follow-up.Plugin: atomic-plugins
claude/server-atproto(aea269d)./.well-known/atproto-didworks at the pin./.well-known/did.json(Multikey secp256k1/P-256, a#atproto_pdsservice).request.hostexists.A PDS or firehose isn't built: it needs non-RSA host keys, MST/CAR repo state and
subscribeRepos, a sidecar per §7 / #1723.michielbdejong commentedon Sep 29, 2026
Claims from the Open Cloud Mesh worker. Implemented on atomic-server
claude/plugin-ocm-host(d18d2f6a2, one commit, with Rust tests). Pushed, no PR. It's stacked onclaude/plugin-fediverse-host(01c3ff202) to reuse its debug-build loopback and test-CA seams, so fold fediverse-host first.auth: http-signature(tag="ocm"):senderDomainorsender, which must agree;https://<domain>/.well-known/ocm→jwksUri, matched bykid, and the JWK'salgpicks the algorithm;caller = {keyId, owner, domain, scheme, alg, tag, endPoint}.sign.tagon deliveries and onctx.keys.sign, andctx.keys.publicKey().jwk.ctx.blobs.fetch({operation, url, headers}).enqueuesoperation (wildcard host allowed).{*rest}.Plugin: atomic-plugins
claude/server-open-cloud-mesh(5bb92a8), a receiver./.well-known/ocmand/ocm-provider, and a JWKS.POST /ocm/shares: the file is fetched with the sharedSecret and stored as a File (the secret is never stored), and a signedSHARE_ACCEPTEDgoes back.SHARE_UNSHAREDandSHARE_CHANGE_PERMISSION.Still open:
michielbdejong commentedon Sep 29, 2026
Claims from the NextGraph worker. Implemented on atomic-server
claude/plugin-nextgraph-host(a68427c14, two commits on candidate14 1432e244a, with Rust and TS tests). Pushed, no PR.atomic-sidecar:/<name>/<path>:http.sidecars, and the host resolves it to the operator's loopback URL (ATOMIC_PLUGIN_SIDECARS), only at--plugin-routes read-write;content-typeandacceptpass from the plugin, and the host addsx-atomic-installationandx-atomic-drive;ctx.http; writes go only through the journaled external-intent approval (/plugin-external-apply);integrations/nextgraph/sidecar/(nextgraph-rs pinned at d507afa3):SELECT, andINSERT DATAwith an idempotency key;outcome-uncertainafter an interrupted write.ngdisn't automated), host-to-sidecar authentication beyond loopback, and mapping RDF to Atomic properties.Plugin: atomic-plugins
claude/server-nextgraph(2125b1a). The real-host e2e passes with a real wallet: pull, then a push approved through/plugin-external-apply, then replay, restart and revoke.michielbdejong commentedon Sep 29, 2026
Claims from the Willow worker. Implemented on atomic-server
claude/plugin-willow-host(fe2937474, two commits on candidate14 1432e244a, with Rust tests). Pushed, no PR.http.keys[].willow = {namespace, pathPrefix}binds an Ed25519 route key; a Willow key never signs HTTP and an HTTP key never signs entries;ctx.willow.subspacereturns the key's public half and the resolved namespace and prefix;ctx.willow.sourcereturns a resource's last commit and its time, read from the retained signed commit envelopes;ctx.willow.authorisesigns only a canonical Entry that has the bound namespace, the key's subspace and a prefixed path, whose source the principal can read at the named commit, and whose timestamp equals that commit's time.ctx.willow.listrecords entries per path and refuses a stale (older) entry. They're erased on revocation. Payloads aren't persisted, and there's no reconciliation or pruning.bodyBase64).Plugin: atomic-plugins
claude/server-willow(85e0466).GET /_routes/<slug>/willow.dropserves a Drop Format file of public resources. The real-host e2e passes, and willow25 0.7.9'sDropDecoderaccepted the drop the host served. Timestamps follow the data model; see willow_rs#62.Not taken: WGPS or a sidecar (#1723: willow25 has no WGPS), owned namespaces and delegations, and preconditions (§1).
michielbdejong commentedon Oct 1, 2026
Host gaps found by running remotestorage/api-test-suite against the remoteStorage plugin at pin candidate19
a12b74a(46/53 pass; per-test table inintegrations/remotestorage/README.md, PR #248):middleware::Compress(serve.rs:464). With gzip or br,Content-Lengthis dropped, so the bytes sent don't match the handler's ETag. Handlers can't opt out.content-rangeis not inREQUEST_HEADERS(route_exec.rs), so a handler can't refuse aPUTwithContent-Range(the spec wants 400).Access-Control-Expose-Headers(per-route OPTIONS).authOptionaltreats an emptyAuthorization:header as credentials (route_exec.rs:1240,contains_key), giving 401 where an anonymous request should pass. Ruby's rest-client sends an empty header forauthorization: nil.Also: this issue's "Current integration pin" line (69602364) is stale; the pin is now candidate19
a12b74a. A refreshed list of which items candidates 14–19 delivered will follow.Generated by Claude Code
michielbdejong commentedon Oct 1, 2026
Refreshed pin status (replaces the body's "Current integration pin" line, which still names 69602364):
Current integration pin:
a12b74a6783b6158119e26a7d36aecadbedda0bf(candidate19). Every host branch claimed in this issue's comments is an ancestor of it (checked with GitHub's compare API):ed1f03d76, in candidate15: optional bearer,{*rest}with a trailing slash, the consented-client redirect, CORS expose headers.8ea005acb(request.host), Fediverse01c3ff202(auth: atomic,caller.actor, WebFinger by rel), Solid21ec49767(auth: dpop, the Solid headers) and OCMd18d2f6a2(key discovery, tagged signatures,ctx.blobs.fetch), in candidate16.fe2937474(host-signed Willow'25 entries) and NextGrapha68427c14(atomic-sidecar:operations), in candidate17b.authOptionalon dpop/atomic (a5f58a504), a dedicatedfetcheslist (b2eab23bb),--trusted-proxies(#1903,38306758f), and sidecar requests signed as the installation's app agent (3ba7b4b8a).All of it sits behind the
plugin-routesCargo feature and--plugin-routes. These are implemented host contracts, not certified end to end. Candidate numbering is inferred from merge-commit subjects. The body's "proposed pin bc39dac" paragraph and its checkboxes are also from before this. The open host items are the ones still unchecked, plus the four gaps in the comment above.Generated by Claude Code