Skip to content

feat: chat channel routing for broker plugins#114

Closed
scion-gteam[bot] wants to merge 12 commits into
mainfrom
scion/chatchannel
Closed

feat: chat channel routing for broker plugins#114
scion-gteam[bot] wants to merge 12 commits into
mainfrom
scion/chatchannel

Conversation

@scion-gteam
Copy link
Copy Markdown

@scion-gteam scion-gteam Bot commented May 31, 2026

Summary

Implements chat channel routing for the message broker system, allowing messages to be directed to specific broker plugins instead of fan-out to all. Closes #113.

  • Core schema: Added Channel and ThreadID fields to StructuredMessage, deliveryMessage, and store.Message with validation (channel format, thread requires channel)
  • Channel-aware routing: FanOutBroker.Publish() now routes to the matching broker plugin when Channel is set, while preserving fan-out behavior when empty. InProcessBroker always receives for local dispatch. Errors on unmatched channels.
  • Inbound tagging: Telegram plugin sets Channel: "telegram" and ThreadID from forum topics. Chat-app sets Channel: "gchat". Web UI defaults to Channel: "web". Broker-log logs channel/thread fields.
  • CLI & API: Added --channel and --thread-id flags to scion message. Added scion message channels subcommand and GET /api/v1/message-channels endpoint for channel discovery.

Design doc

See .design/chat-channel-routing.md for full design rationale and phased implementation plan.

Commits

  1. ae49d05 — Core message schema (Channel/ThreadID fields + validation + tests)
  2. 8c6e467 — Channel-aware routing in FanOutBroker (+ 4 routing tests)
  3. 1e7e1f0 — Inbound channel tagging (telegram, gchat, web, broker-log)
  4. cb0952b — CLI flags, message-channels API, channels subcommand

Test plan

  • Unit tests for Channel/ThreadID validation (9 cases)
  • Unit tests for FanOutBroker channel routing (4 cases: targeted, fan-out, unmatched, publish error)
  • All existing tests pass (pkg/messages, pkg/broker, pkg/hub, pkg/store, pkg/hubclient)
  • go build ./... compiles cleanly
  • Manual: scion message channels lists registered broker plugins
  • Manual: scion message agent:x "msg" --channel telegram routes only to telegram plugin
  • Manual: Inbound telegram messages show channel: "telegram" in delivery

@ptone ptone closed this Jun 1, 2026
@ptone
Copy link
Copy Markdown
Owner

ptone commented Jun 1, 2026

This pull request has been recreated on the target repository as GoogleCloudPlatform#283.

@scion-gteam scion-gteam Bot reopened this Jun 1, 2026
ptone added 5 commits May 31, 2026 17:43
…leCloudPlatform#286)

* Update docs-site landing page with Scion explainer deck content

Incorporate key messaging from the Scion intro slides into the landing
page. Adds a new "Scion Core" pipeline section showing the five-part
orchestration flow (Define, Run, Spawn, Notify, Sync) and expands the
feature cards with detailed descriptions from each slide topic (Agent
Definition, Runtime, Collaborators, Notifications, Shared Filesystem).

Other changes:
- Replace "Boot" with "Run" per requested terminology change
- Update "grove" to "project" in the how-it-works steps
- Replace Google Slides embed with the HTML slides deck URL
- Reorder sections: pipeline → features → video → slides → quickstart

* Add project log entry for docs landing page update
…Platform#270)

Add circuit breaker pattern to Cloud Logging integration:
- ResilientCloudHandler wraps CloudHandler with three-state circuit
  breaker (closed/open/half-open) and background health checks
- flushInFlight atomic prevents goroutine leaks from concurrent flushes
- circuitGatedHandler gates request/message loggers through the circuit
  breaker so all log streams benefit from protection
- CloudHandler gets BufferedByteLimit (8MiB) and ClientTimeout (15s)
- Cleanup ordering ensures health check goroutine stops before client
- Mutex-protected logging moved outside locks to prevent deadlocks
…ogleCloudPlatform#271)

* Fix resume creating new agents instead of restarting stopped ones (#61)

The Hub server's CreateAgentRequest struct was missing the Resume field
that the CLI client sends, causing all stopped agents to be treated as
stale and deleted+recreated rather than restarted in-place.

Add the Resume field to the Hub's CreateAgentRequest and handle the
stopped+resume case in handleExistingAgent: when Resume=true and the
agent is in PhaseStopped, restart it in-place (preserving agent ID,
metadata, and template association) rather than deleting and recreating.

When Resume is not set (i.e. scion start), the existing delete+recreate
behavior is preserved unchanged.

* Add project log for issue #61 resume fix

* Address PR review: nil-guard AppliedConfig on resume, fix TS unused var

- Defensively initialize existingAgent.AppliedConfig when nil before
  applying task/attach params during resume, preventing potential nil
  pointer dereference (review feedback).
- Fix profile-telegram.ts TS6133 error: _linkedTelegramId was declared
  but never read, causing CI Build & Test failure.
…#284)

* Add engineering glossary (GLOSSARY.md) with canonical terms and cleanup tracker

Add a root-level GLOSSARY.md capturing canonical Scion terminology in the
ubiquitous-language format (preferred term + synonyms to avoid), grouped by
domain cluster, plus an Exceptions & Future Cleanup section tracking known
naming-convergence work. Link it from agents.md as the canonical engineering
glossary.

* Revise glossary: broker reframe, Event Bus, Hub-managed, and term refinements

Refine entries from review: redefine Message Broker as the pluggable
messaging-integration system (add Broker plugin, Built-in broker); add Event
Bus for the NATS real-time/event capability; collapse hub-native/Hub Workspace
into Hub-managed project/workspace; tighten Template (harness-agnostic, optional
default harness-config), Skill (template-only, Agent Skills link), Profile
(named runtime-broker settings bundle), Harness/Harness-config; reframe Hub as
the control plane in both modes; add Group and Message Group. Expand Exceptions
& Future Cleanup to nine tracked items.

* Glossary: restructure headings, add cross-refs, modes table, and new terms

- Retitle to "Scion Glossary"; drop the "Language" wrapper and promote
  the thematic categories to top-level sections
- Add an Operations section (Attach, Dispatch) and move Profile next to
  Runtime Broker
- Add a Local/Workstation/Hosted comparison table and "See also"
  cross-refs across the main confusable term clusters
- Reframe the intro around the three-way broker collision (incl. Event
  Bus) and defer to the disambiguation rule; sentence-case "Shared
  directory"
- Add canonical entries for Secret, Notification, and Schedule
- Add a "Potential Future Additions" section cataloguing candidate terms

* Glossary: remove Exceptions & Future Cleanup tracker

The cleanup items are now tracked by dedicated agents that open GitHub
issues and implementation PRs, so the staged tracker no longer lives in
the glossary. Reword the two intro/disambiguation references that pointed
at the removed section to point at GitHub issues instead.

* docs: fix glossary typo, remove outdated shorthand terms, fix workstation state

- agents.md: fix 'gossary' typo in section header; remove shorthand
  definitions (hub-native, hub-project, linked-project, agent-home,
  hub-broker) that contradicted the canonical GLOSSARY.md
- GLOSSARY.md: clarify Workstation mode State & isolation column
* refactor(hub): consolidate content-hash onto canonical transfer impl

The hub's computeContentHash (template_handlers.go) was a separate hand-rolled
implementation of the same sorted-file-hash aggregation as the canonical
transfer.ComputeContentHash used by the broker-side hydrator, the transfer
collector, and the hubclient manifest builder. The two diverged on empty input
(the hub hashed an empty byte stream; transfer returns ""), exactly the silent
hub/broker drift risk that would break cache-key lookups.

Make the hub function a thin adapter that converts []store.TemplateFile to
[]transfer.FileInfo and delegates to transfer.ComputeContentHash, so every call
site shares one implementation. Add content_hash_test.go pinning the adapter to
transfer and the empty-input contract.

This is the §7.3 'pull-forward' from .design/hosted/resource-storage-refactor.md
and resolves the hash-canonicalization open question (§9). No behavior change
except empty file sets now hash to "" (one harmless re-sync for any degenerate
zero-file resource on next bootstrap).

* refactor(broker): single read path + thin content-addressed cache (7.1, 7.2a)

Implements sections 7.1 and 7.2a of the resource-storage refactor design. These
landed together with templates as the proving ground but were left uncommitted;
this captures them on the branch.

7.1 — single read path, remove co-located live-edit shortcut:
- hydrateTemplate no longer reads the import-source dir. It resolves through the
  connection's storage backend in every topology. New resolveLocalTemplate reads
  directly from the local backend's on-disk location when the backend is local
  (co-located workstation mode), otherwise hydrates from remote storage.
- Replace HubConnection.TemplatesDir with HubConnection.LocalStorage
  (storage.Storage), set only for a co-located connection whose backend is local
  FS. IsColocated is kept (still used by the heartbeat loop).
- Add storage.LocalStorage.ObjectFSPath, reached via a localObjectResolver
  interface assertion in the broker (placeholder for the 7.3 LocalDirBackend).
- Plumb runtimebroker.ServerConfig.ColocatedStorage from hubSrv.GetStorage() in
  cmd/server_foreground.go, only in co-located mode.

7.2a — collapse the cache to a thin content-addressed store:
- templatecache.Cache is keyed solely by content hash: Get(hash)/Put(hash,files)
  with a size-bounded LRU. Removed the templateID→hash index, GetByHash,
  GetAnyVersion, GetFileHashes, per-file incremental download, the
  store-nil-under-second-ID path, and shared-hash eviction refcounting.
- Hydrator simplified to: metadata -> cache.Get(hash) -> download-whole-on-miss
  -> verify each file hash -> cache.Put(hash, files).
- Cache is only exercised on the remote/GCS path; the local direct-read path
  never constructs a hydrator call.

* style: gofmt struct alignment in extras and pkg/messages

Pure gofmt formatting (struct field/tag alignment) on pre-existing files that
were failing the repo-wide fmt-check gate. No semantic changes.

* test: use project_id key in hub secret/sync test fixtures

Two tests asserted resolution of a project's ID from a legacy top-level
grove_id key in settings files (settings.json / settings.yaml), but the
grove->project rename only wired up project_id resolution for that key path —
top-level legacy grove_id no longer maps to project_id, so the fixtures
produced an empty ProjectID and the tests failed:
  - cmd: TestResolveSecretScope_ProjectFallbackToProjectID
  - hubsync: TestEnsureHubReady_EndpointOverrideBeatsSettings

Switch the fixtures to the modern project_id key, completing the rename for
these fixtures and restoring green CI. The tests still exercise their actual
assertions (scope fallback to ProjectID; endpoint override beating settings).

* style: gofmt rename-induced struct misalignment (heartbeat, chatapp)

The grove->project rename widened struct fields (ProjectID, projectFilter)
without re-running gofmt, leaving neighboring fields misaligned. Pure gofmt;
no semantic changes.

* docs(agents): add sandbox git/CI gotchas and memory-persistence policy

Capture operational learnings for future agent sessions in the root agents.md
(symlinked as CLAUDE.md/claude.md/gemini.md, so it applies to all harnesses):

- New 'Sandbox gotchas' subsection in the Git Workflow Protocol: Go version
  skew vs the go.mod/CI-pinned gofmt, go build -buildvcs=false in worktrees,
  inspecting main via a detached worktree (can't worktree-add the main branch),
  golangci-lint OOM mitigation (scope + --new-from-rev=main), leaked SCION_*
  env vars in tests, and how 'latest main' reaches a worktree without fetch.
- New 'Agent memory & durable notes' section: the harness built-in/native
  memory dir is ephemeral (not persisted across container restarts), so durable
  guidance must live in committed project files only. Migrates the two prior
  ephemeral notes (lean forward on 'project' over 'grove'; proactively raise
  adjacent cleanup) into agents.md.

* build: upgrade root module to Go 1.26.1

Bump the go directive in the root go.mod from 1.25.4 to 1.26.1, aligning it with
the core-base build image (image-build/core-base/Dockerfile already ships
GO_VERSION=1.26.1) and the runtime/sandbox toolchain. CI installs Go via
go-version-file: go.mod, so this also moves CI onto 1.26.1 and eliminates the
prior toolchain/CI skew (go.mod 1.25.4 vs image 1.26.1).

Update the agents.md sandbox-gotchas note accordingly. Builds, vet, and the full
'make ci' pass under 1.26.1.

The extras/* submodules are separate Go modules still on older go directives and
golang:1.25.x Dockerfile pins; they are left unchanged (bumping them needs
coordinated Dockerfile base-image/digest updates) and noted as a follow-up.

* refactor(hub): extract shared resource bootstrap mechanics (7.3 first step)

Mechanics-first first step toward the §7.3 ResourceStore/ResourceResolver
abstraction in the resource-storage refactor. No behavior change.

- storage: add ResourceKind + kind-keyed ResourceStoragePath/ResourceStorageURI
  as the single source of truth for the scope layout; reduce the legacy
  Template*/HarnessConfig* path/URI functions to thin wrappers.
- hub: add uploadResourceFiles + reconcileResourceStorage in storage_helpers.go
  (the doc's named 'seed of the generalization') and route all four
  bootstrap/sync call sites (template + harness-config) through them. Templates
  keep their stale-object reconcile; harness-configs do not (unchanged).
- tests: cover ResourceStoragePath per kind x scope and pin the legacy wrappers
  to the shared implementation so the storage layout can't silently drift.
- doc: update Status block + §7.3/§8 to reflect content-hash consolidation
  landed and mechanics extraction in progress.

Note: the template reconcile warn lines now key the resource name as
"resource" instead of "template" (generic helper); warn-only, cosmetic.

* refactor(hub): dedupe FileInfo->manifest conversion; mark 7.3 mechanics done

Adjacent simplification on top of the 7.3 mechanics extraction:

- hub: add toResourceFiles(files) helper in storage_helpers.go and use it for
  the content-hash preview build in syncExistingTemplate and the newHash build
  in syncExistingHarnessConfig, replacing two more copies of the inline
  []transfer.FileInfo -> []store.TemplateFile loop. (The upload helper still
  builds its manifest incrementally, appending only uploaded files, so it keeps
  its own per-file build.)
- doc: mark the shared bootstrap mechanics (and earlier content-hash
  consolidation) as done sub-items of §7.3; split §8 step 3 into 3a (done
  mechanics) and 3b (remaining interfaces), noting 3b's broker-side
  ResourceResolver is coupled with step 4 (harness-config onboarding) and may
  land together. Fix stale 'sequencing step 3' cross-ref to step 4.

* refactor(hub): introduce ResourceStore over shared bootstrap primitives (7.3 step 3b, hub side)

Collapse the parallel template and harness-config import/sync routines onto one
kind-generic ResourceStore.Bootstrap that wraps the already-shared 3a mechanics
(uploadResourceFiles, reconcileResourceStorage, toResourceFiles,
computeContentHash, storage.ResourceStoragePath). A shared ResourceRecord is a
view over the common fields; a per-kind resourcePersistence bridges it to the
concrete store model, mutating the loaded model in place so the typed Config
payload (TemplateConfig / HarnessConfigData) survives a sync.

Behavior-preserving for templates. Harness-config sync now also reconciles
stale storage objects (a removed-file cleanup it previously lacked).

Guards added: typed-Config survival on sync (both kinds), harness-config
stale-object reconcile.

* refactor(broker): generalize Hydrator into a kind-generic Resolver (7.3 step 3b, broker side)

Extract the download-and-cache algorithm into a kind-agnostic templatecache.Resolver
parameterized by a resourceFetcher (Get metadata / RequestDownloadURLs /
DownloadFile), with adapters over hubclient.Templates() and hubclient.HarnessConfigs().
Hydrator is now a thin template-kind wrapper preserving its public API.

Fold the 7.1 localObjectResolver seam into a kind-aware resolveLocalResource +
resourceObjectPath in the broker, computing object paths via the kind-keyed
storage.ResourceStoragePath. One ObjectFSPath assertion serves every kind.

Behavior-preserving for templates; lays the resolver groundwork for the
harness-config consume path (step 4).

* feat(resources): hydrate harness-configs on the broker from the Hub (7.3 step 4)

Harness-configs were write-only to the storage backend: a broker that lacked the
harness-config on its local filesystem could not provision an agent that needed
it. Close that gap by giving harness-configs the same Hub-hydration path
templates already have.

Hub: populateAgentConfig resolves the harness-config name (or the template's
DefaultHarnessConfig) to a Hub record and stamps HarnessConfigID/Hash onto
AppliedConfig; the dispatcher threads them to the broker.

Broker: a per-kind harness-config cache + Resolver (NewHarnessConfigResolver),
and hydrateHarnessConfig (mirroring hydrateTemplate) resolves the config to a
local dir — via the co-located local backend or by downloading+caching from the
storage backend — and sets StartOptions.HarnessConfigPath.

Agent: provisioning honors HarnessConfigPath (threaded via context) and loads
the hydrated dir directly, bypassing the on-disk FindHarnessConfigDir search.
Name selection is unchanged; only the file source moves to the storage backend.

Adds HarnessConfigID/Hash to AgentAppliedConfig, RemoteAgentConfig, and
CreateAgentConfig; HarnessConfigPath to api.StartOptions.

Tests: hub ID/hash stamping (explicit + template-default), provision bypass of
disk search, broker hydrate fall-back guards.

* docs(resource-storage-refactor): mark 7.3 (3b) and step 4 as landed

* docs(resource-storage-refactor): record open follow-ups (errcheck lint + ci-full, hc resolver test)

* test(resources): harness-config Resolver test + errcheck fix (7.3 follow-ups)

Close the two open follow-ups from §7.3 of the resource-storage-refactor:

- Fix the carried-over errcheck on the unchecked f.Close() in
  uploadResourceFiles (pkg/hub/storage_helpers.go) -> `_ = f.Close()`.
  Scoped golangci-lint over pkg/hub and pkg/templatecache is now clean.
- Add a dedicated harness-config Resolver unit test
  (pkg/templatecache/resolver_test.go) with a mock HarnessConfigService,
  exercising the end-to-end download path (metadata -> signed URLs ->
  download+verify -> cache), the content-addressed cache hit on
  re-resolve, ResolveWithHash fast path, not-found, hash-mismatch, and
  nil-hub-client cases. Wires a harnessConfigs field into the shared
  mockHubClient.

make ci is green. (make ci-full still fails only on a pre-existing,
unrelated web-typecheck error in profile-telegram.ts, identical to main.)

* docs(resource-storage-refactor): consolidate to a single work progression

The doc had grown three parallel status trackers (the top Status paragraph,
per-subsection Status blockquotes in 7.1-7.4, and the Section 8 sequencing
list), with the same work double-numbered (e.g. 7.3 vs step 3) and drifting.

Collapse to one: Section 8 ('Work plan & status') is now the single ordered
progression and the only status tracker. Sections 7.1-7.4 become pure design
rationale with a one-line pointer to their step in Section 8; 7.3's as-built
detail moves into an 'Implementation notes (as landed)' block. The top Status
paragraph shrinks to a 'we are here' pointer. No work-state changes.

* docs(resource-storage-refactor): defer step 5 (skills) to skill-bank feature

* feat(hub): harness-config capability parity + project-scope list filter fix

Add capability annotations for harness-configs to match templates so the web
UI can gate editing consistently:
- register "harness_config" in ResourceActions/ScopeActions and add a
  harnessConfigResource helper (project-scoped configs parent to their project)
- getHarnessConfig and the list handler now return _capabilities
  (new HarnessConfigWithCapabilities), mirroring TemplateWithCapabilities

Also fix a harness-config store-filter gap: scope=project combined with a
projectId now narrows to that single project (previously matched every
project's configs, unlike the template filter). Covered by new tests.

* feat(web): harness-config editing, hub-scope resource editors, issue #80

Close the web UI gap for the resource-storage refactor:
- harness-config file browsing/editing: HarnessConfig{FileBrowser,FileEditor}
  data sources + a harness-config-detail page reusing the shared
  file-browser/editor (mirrors template-detail)
- new shared <scion-resource-list> component lists templates or
  harness-configs for a scope and links to their detail pages; used by both
  project settings and the hub page so they render identically
- Project Settings -> Resources gains a Harness Configs tab (list + edit); the
  Templates list now uses the shared component
- rename "Hub Settings" -> "Hub Resources" and restructure /settings into a
  project-settings-style Resources tab group (env vars, secrets, templates,
  harness configs at global scope), with /settings/{templates,harness-configs}/{id}
  detail routes
- issue #80: scope-aware back navigation adds a "Templates" link (deep-links
  to the Templates tab via ?tab=); detail pages back-link to project settings
  or Hub Resources depending on scope

* docs(resource-storage-refactor): record web UI (4b) and deferred import (4c)

Document the harness-config web UI + capability/store-filter parity that landed
this session (step 4b), and add step 4c: an import-harness-configs endpoint +
import UI mirroring templates, deferred to a future session. Update the
"We are here" status accordingly.

* feat(hub): harness-config import endpoint + web UI (step 4c)

Closes the last template/harness-config parity gap from the
resource-storage-refactor. Harness-configs can now be imported into the
Hub from a Git URL or workspace path, mirroring import-templates.

- Hub: handleProjectImportHarnessConfigs + import-harness-configs route;
  importHarnessConfigsFromRemote/importHarnessConfigsFromWorkspace reuse
  the shared harnessConfigStore Bootstrap. syncExistingHarnessConfig
  gains a force param for reconcile-on-import.
- Web: Harness Configs tab in Project Settings gains the same
  URL/workspace import controls as templates.
- Tests: workspace-import unit tests in harness_config_bootstrap_test.go.
- Docs: mark step 4c done in resource-storage-refactor.md.

* style: gofmt alignment after pkg/broker→pkg/eventbus rename

Pure gofmt (struct-tag/map alignment + import ordering) for files left
unformatted by the pkg/broker→pkg/eventbus rename on main (GoogleCloudPlatform#277). No
logic changes; restores a green fmt-check after rebasing onto main.

* fix: address PR GoogleCloudPlatform#285 review feedback

- Fix path traversal vulnerability in workspace validation using
  filepath.Rel instead of strings.HasPrefix (security-high)
- Add mutual exclusion check for sourceUrl/workspacePath in import API
- Add nil checks for storage backend, downloadResp, cfg, harnessConfig,
  template, and harnessConfigToRecord to prevent nil pointer panics
- Fix cache Get to require index entry, preventing untracked cache hits
  and disk space leaks from eviction bypass
- Write cached templates atomically via tmp+rename for crash safety
- Restrict ProjectID SQLite filter to project/grove scopes only

* fix(lint): check os.RemoveAll errors flagged by errcheck

ci-full's golangci-lint surfaced unchecked os.RemoveAll returns:
- atomic-write cleanup paths in templatecache cache.Store (from the
  PR GoogleCloudPlatform#285 review-feedback cherry-pick)
- defer os.RemoveAll(cachePath) in the remote import paths for both
  templates and harness-configs

Cleanup-on-error sites where the original error is the one returned;
ignore explicitly to satisfy errcheck. No behavior change.
@scion-gteam scion-gteam Bot force-pushed the scion/chatchannel branch from 39847ca to cddae16 Compare June 1, 2026 02:39
chiefkarlin and others added 7 commits May 31, 2026 19:58
…ports (GoogleCloudPlatform#260)

* fix(hub): support project GITHUB_TOKEN secret fallback for remote template imports

* address PR review feedback: drop redundant db fallback, simplify tests, and scope constants

---------

Co-authored-by: Preston Holmes <ptone@google.com>
…dPlatform#244)

Bumps [astro](https://github.com/withastro/astro/tree/HEAD/packages/astro) from 6.1.8 to 6.3.2.
- [Release notes](https://github.com/withastro/astro/releases)
- [Changelog](https://github.com/withastro/astro/blob/main/packages/astro/CHANGELOG.md)
- [Commits](https://github.com/withastro/astro/commits/astro@6.3.2/packages/astro)

---
updated-dependencies:
- dependency-name: astro
  dependency-version: 6.3.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…oudPlatform#246)

Bumps [devalue](https://github.com/sveltejs/devalue) from 5.6.4 to 5.8.1.
- [Release notes](https://github.com/sveltejs/devalue/releases)
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md)
- [Commits](sveltejs/devalue@v5.6.4...v5.8.1)

---
updated-dependencies:
- dependency-name: devalue
  dependency-version: 5.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…oogleCloudPlatform#287)

* Integrate Scion explainer slideshow directly into landing page

Replace the iframe-embedded slide deck with a fully inline, interactive
slideshow component. All 7 slides from the hosted deck are now rendered
directly in the landing page with scoped CSS and inline JavaScript.

Key changes:
- Full slideshow with keyboard/touch/click navigation, progress dots,
  and animated transitions
- All interactive widgets recreated inline: State Model Simulator,
  Collaborators Graph (with dynamic spawn/delete loop), Reactive
  Notification Wakeup flow, and Shared Filesystem Simulator
- Replace "Boot" with "Run" throughout all slide content
- Remove Overview Deck iframe section; add "technical deep dive" link
  to the Google Slides deck below the inline slideshow
- Move "How it works" quickstart section below "See it in Action" video
- Scope all slideshow CSS under .scion-deck to avoid style conflicts
  with the landing page

* Update project log for inline slideshow integration
Add channel-aware message routing so broker plugins (Telegram, Google
Chat, etc.) can tag messages with a channel name and optional thread ID.
The FanOutEventBus routes channel-tagged messages only to the matching
bus and the in-process bus, while untagged messages fan out to all buses
as before. Includes CLI --channel/--thread-id flags, a /message-channels
API endpoint, and client library support.
…rocess channel

- Channel-targeted messages now publish to InProcessBus and the matched
  channel concurrently (via goroutines), preventing slow external RPC
  calls from blocking HTTP handlers
- Reject msg.Channel="inprocess" with a clear error — inprocess is a
  reserved internal bus, not a user-visible channel
- Unmatched channels now fail fast before publishing to any bus
- Add test for reserved inprocess channel rejection
…utbound messages

- Channel-targeted publish now checks target.Observer: observer channel
  errors are logged but not returned, consistent with the fan-out path
- Add StructuredMessage.Validate() call in handleAgentOutboundMessage
  before publishing, catching invalid Channel/ThreadID combinations
- Add test for observer error suppression in channel-targeted path
@ptone ptone force-pushed the scion/chatchannel branch from c624f58 to 7c57fac Compare June 1, 2026 03:34
@scion-gteam scion-gteam Bot closed this Jun 1, 2026
@scion-gteam scion-gteam Bot deleted the scion/chatchannel branch June 1, 2026 12:22
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.

Feature: Chat channel integration

2 participants