cloudApi v3.1: dial metadata + decide, aiPresets + mesh-job status line (1.15.1) - #231
Merged
Merged
Conversation
…vider.decide answers it
Roadmap 29, rooms access control (seam 1). A gated cloud room needs the host to see a
knock's name or a room-code proof BEFORE the conn opens - an unapproved conn is closed at
once, so the dial's PeerJS metadata is the only channel that arrives first.
- `cloudApi.connectToPeer(peerId, cloudMeta)` -> `requestConnect(peerId, cloudMeta)`: the
join dial's metadata gains `cloud: <plain JSON <= 1 KB>` (bounded in `boundCloudMeta`;
oversized or unserialisable data is dropped, not truncated), remembered per peer on the
PeerConnection (`dialCloud`) so a restore re-dial knocks with the same hand, forgotten by
the next plain dial. Absent = the dial is byte-identical (`{jr: 1}`).
- `authProvider.decide(peerId, cloudMeta)` REPLACES `authorize` when present: 'admit' (the
auto-approve path), 'deny' (refused with NO card; a joiner that advertised `jr` hears
`denied` through the 25-F refusal dial, an older one is closed silently), `{label}` (the
normal card carrying the label, capped at 120 chars, refreshed by a re-dial). Undefined
defers to `authorize`; a provider with only `authorize` is byte-unchanged; a throwing
`decide` falls back to the manual card and admits nobody.
- `Toasts.svelte` and the Connect drawer's Toasts tab render `approval.label`.
- `cloudApi.dialMeta = true` is the probe an older engine lacks (the cloud plugin fails
closed to the plain approval card without it). No CLOUD_HOOKS_VERSION bump: additive.
- `pendingApprovals` is typed `Writable<any[]>` (it inferred never[]), which removes five
pre-existing svelte-check errors; the patch's own JSDoc gaps (dialOptions/dial params,
the `dialCloud` field) are filled so the check adds nothing.
Suite `dial-metadata` (43): the joiner's dial (identical without metadata, carried on the
dial and its restore, bounded), every verdict branch against a stubbed peer, and two real
peers over signaling (label, deny, admit). The patch itself was written and proven by the
`29-rooms-access` lane; this lands it.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… seam)
Roadmap 29, G-3 hosted AI (seam 2). A signed-in cloud user should get the assistant with
no key, URL or model to type. The plugin cannot write core's aiProviders / meshProviders
itself - they are Svelte stores loaded from localStorage at module init, so a key written
after boot changes nothing until a reload - so core owns ONE plugin-managed preset per
domain and the plugin describes it.
- `api.aiPresets.userHas(tag)` -> `{ai, mesh}`: does the user have a provider of their
OWN (the tagged entry excluded).
- `api.aiPresets.seed(tag, {ai, mesh, activate, enable})`: create / update / remove the
managed entry in both lists (`null` removes). `tag` is `managedBy` on the config, so a
user-created provider - which carries no tag - is untouchable by construction; a config
cannot smuggle an `id` or a tag. ACTIVATION takes two guards, both required: the
caller's `activate.<domain>` AND the slot being empty or already ours. The trap the lane
brief named: `addAiProvider`/`addMeshProvider` activate a first provider on their own,
so a seed without permission restores the previous pointer, or guard 1 leaks through
the add (the suite's counterfactual). `enable` flips the master toggle only when our
entry became the active one.
- `providers.js` / `meshProviders.js`: optional `managedBy` on the config typedef (absent
= the user's own, no migration) and the add whitelists keep it.
- `api.setMeshJobStatus(fn)` + `cloudHooks.meshJobStatus`: one line under each RUNNING
mesh-job card ("You are #3 in queue"); `fn()` -> string | null, re-read on every set
(a function is never equal to itself in svelte's store check, so a set is the poke) and
on every job-list change; a throwing fn renders nothing and breaks nothing.
- `makeCloudApi` is exported so the debug hook can hand a suite the real api.
- No CLOUD_HOOKS_VERSION bump: every member is additive and typeof-probed (the plugin
stays compatibleHooks = 3; hostedAi.js already calls exactly this shape).
Suite `ai-presets` (45): the probe, create/update/remove, both activation guards with
their counterfactuals, enable-only-when-active, managedBy across the store and a reload,
and the status line's render/re-read/remove/throw.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d entries, baseline 336/47 - CHANGELOG: the 1.15.1 section (gated rooms end to end, the hosted-AI preset + queue line, cloudApi v3.1 for plugin authors). - CLAUDE.md: the cloudApi v3.1 architecture entry (both seams and their guards), the jsDelivr semver-tag gotcha (core #230), the round-2 status entry, and the stale `plans-core/` plan paths rewritten to `cloud/plans/core/` (51 mentions incl. the two prose lines the brief named). - e2e skill: the dial-metadata + ai-presets suites. - check-baseline.json ratcheted 341 -> 336 (typing `pendingApprovals` removed five errors). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap 29 round 2 — the two core seams the cloud lanes could not land themselves, released as 1.15.1 (patch: additive cloudApi members, no hooks-version bump, no format change). The
29-core-seamslane stalled at zero commits, so the integrator carried it.Seam 1 — rooms access control (
8e9fb5d)cloudApi.connectToPeer(peerId, cloudMeta)rides plain JSON (≤ 1 KB) on the join dial's PeerJS metadata, remembered per peer for restore re-dials;authProvider.decide(peerId, cloudMeta)replacesauthorizewhen present —'admit'/'deny'(no card; ajrjoiner hearsdenied) /{label}(the card carries it);cloudApi.dialMetais the probe. The rooms-access lane's proven patch, plus the JSDoc it lacked.pendingApprovalstyped → five baseline errors gone.Seam 2 — hosted AI (
311e184)api.aiPresets.userHas(tag)/seed(tag, {ai, mesh, activate, enable}): one plugin-managed provider preset per domain (managedByon the config, absent = the user's own), two activation guards (the trap: the stores auto-activate a first provider, so a seed without permission restores the pointer),enableonly when we became active.setMeshJobStatus(fn)+cloudHooks.meshJobStatus= the queue line under a running mesh-job card.Gates
dial-metadata(new)ai-presets(new)decide; G3 seeds throughapi.aiPresetsAlso in the docs commit: the stale
plans-core/paths in CLAUDE.md, and a gotcha for the finding on the way — jsDelivr parsesscenes@v2as a semver version and never re-resolves a retag (core #230).🤖 Generated with Claude Code