Skip to content

Release 1.15.1 - #232

Merged
AlexZ005 merged 4 commits into
mainfrom
release/next
Sep 20, 2026
Merged

AlexZ005 merged 4 commits into
mainfrom
release/next

Conversation

@AlexZ005

Copy link
Copy Markdown
Collaborator

release/next → main for 1.15.1 "Knock, and a key you never typed": PR #231 (cloudApi v3.1 — dial metadata + authProvider.decide, api.aiPresets + setMeshJobStatus). Gates in #231.

🤖 Generated with Claude Code

AlexZ005 and others added 4 commits September 20, 2026 03:48
…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>
cloudApi v3.1: dial metadata + decide, aiPresets + mesh-job status line (1.15.1)
@AlexZ005
AlexZ005 merged commit 75b5a5a into main Sep 20, 2026
8 checks passed
@AlexZ005
AlexZ005 deleted the release/next branch September 20, 2026 01:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant