Projection Subscription Roadmap
This roadmap is the detailed delivery checklist for moving AdaOS runtime interaction, browser-facing skills, and scenarios from monolithic Yjs snapshots and ad hoc refresh logic to demand-driven projections.
It is intentionally narrower than the broader target-state architecture documents so implementation work has a focused checklist.
The target architecture is defined in Operational Event Model. The master implementation order across all adjacent workstreams is defined in Operational Event Model Roadmap. The skill-facing SDK/core rails are defined in Skill Projection Runtime SDK.
Ownership Rule
Snapshot date: 2026-05-15.
This document no longer owns an independent priority order. It expands the projection-specific parts of the master Operational Event Model Roadmap.
Use it as the detailed checklist for:
- Phase 3: projection record shape, client subscription shape, node-aware Yjs envelope, and compatibility rules
- Phase 4: browser projection subscription runtime and client adapter
- Phase 5: shared dispatcher behavior
- Phase 7: Infrascope migration slice
- Phase 8: follow-up pilots
- Phase 9: cross-skill rollout and cleanup
Before adding more large scenario snapshots, new widget-specific caches, or more ad hoc event debouncing, AdaOS should establish the shared projection/subscription runtime contract described here. However, this work should be started only when it is the next active slice in the master roadmap or when it removes a blocker for that slice.
This contract is intended as an architectural layer above the communication model, not as a one-off adaptation for one skill.
If this checklist and the master roadmap disagree, the master roadmap wins. Update this document instead of creating a second delivery track.
Goals
- make projection demand explicit
- materialize projections per webspace, not globally
- allow page, widget, modal, and panel consumers to coexist
- reduce Yjs write noise and broad client invalidation
- keep richer semantic state in skill memory while publishing only demanded views
- treat platform diagnostics, system messages, and browser/runtime errors as first-class emitted projections where appropriate
- reuse the same contract across skills and scenarios
Non-Goals for MVP
- per-user payload forks inside the same webspace
- mandatory deletion of inactive projections
- universal generic renderer semantics for every possible UI surface
- replacing the existing domain event bus
Checklist
0. Communication and Runtime Ordering
- [x]
ordering.fixed: place this projection/event work explicitly after node-browser and runtime communication hardening - [x]
ordering.runtime_first: treat the new model as a core/skill/platform interaction contract first, and a browser materialization contract second - [x]
ordering.aligned_with_comm_phases: align the implementation order with the communication phases described in the runtime reliability roadmap
Current status:
- the communication prerequisite ordering is closed in the master roadmap
- deeper sidecar continuity and media work remain follow-on reliability work, not hidden blockers for the current projection ABI slice
1. Architectural Fixation
- [x]
arch.event_model_published: publishOperational Event Modelas the shared target-state contract for runtime and browser projection work - [x]
arch.event_taxonomy_fixed: define the canonical distinction betweendomain events,core-skill interaction events,projection demand,projection lifecycle,ui intent, andplatform operational events - [x]
arch.webspace_scope_fixed: defineprojection scopeasper-webspace - [x]
arch.node_scope_reserved: define room fornode scopeinside shared Yjs state - [x]
arch.audience_contract_fixed: define the MVP access/audience metadata contract withshared,owner,guest, anddev - [x]
arch.shared_payload_rule_fixed: explicitly freeze the MVP rule that owner and guest do not get separate payload branches
Current status:
- architectural fixation is complete for this checklist
- unresolved work now belongs to ABI and implementation phases, not to vocabulary debate
2. Core and Shared Runtime ABI
- [ ]
runtime.event_envelope_abi: align with the master roadmap's shared event envelope before adding projection-specific metadata - [ ]
runtime.core_skill_contract: define the core-to-skill invalidation and refresh contract before browser-specific consumption logic - [ ]
runtime.ownership_split: define which runtime transitions are core-owned and which projection rebuilds are skill-owned - [ ]
runtime.platform_emitters_defined: define platform-emitted projections for notifications, warnings, diagnostics, and system errors - [ ]
runtime.restore_demand_from_yjs: define startup restoration rules for core and skills reading active demand from Yjs
Current status:
- named-entity ABI is already implemented enough to serve as a model for contract-first runtime work
- eventbus backpressure exists for selected hot paths, but does not replace the event envelope or dispatcher ABI
- status-card ABI should be treated as the first platform-emitter family and kept aligned with this projection contract
3. Projection ABI
- [ ]
abi.projection_record_shape: define the canonical projection record shape:status,data,meta,error - [ ]
abi.projection_keys_fixed: define deterministicprojection_keyrules for page, widget, modal, panel, platform-emitted, and node-scoped projections - [ ]
abi.client_subscription_shape: define the browser-written client subscription record shape - [ ]
abi.node_aware_yjs_envelope: define the node-scoped top-level Yjs envelope so shared subnet state can preserve multiple node emitters - [ ]
abi.pinned_consumer_semantics: definepinnedconsumer semantics
Next active projection task:
- lock
abi.projection_record_shapeandabi.client_subscription_shapetogether; either shape without the other will recreate the current compatibility drift - include platform status cards and named-entity registry as reference examples, not only skill-owned projections
4. Client Subscription Runtime
- [ ]
client.subscription_registry: add browser-side projection subscription registry support - [ ]
client.full_subscription_overwrite: make each client write its full active subscription set on change - [ ]
client.surface_lifecycle_to_subscriptions: ensure modal open/close, widget mount/unmount, and visibility changes update the client subscription record - [ ]
client.multi_projection_support: add support for multiple active projections in one webspace - [ ]
client.node_multiplicity_ready: prepare the browser to consume node multiplicity from shared Yjs instead of assuming one anonymous node view - [ ]
client.soft_session_sanitation: keep stale-client cleanup as a soft client/session sanitation mechanism, not as projection activity logic
Current status:
- node-aware stream receiver hints and compatibility-era node ownership metadata already exist in the browser/runtime path
- a general browser-written subscription registry is still not implemented
- avoid adding another browser-local cache or modal-specific registry before the shared subscription shape is locked
5. Skill, Scenario, and Platform Dispatcher
- [ ]
dispatcher.shared_pattern: add a shared dispatcher pattern fordomain/core/platform event -> in-memory update -> demanded projection refresh - [ ]
dispatcher.skill_projection_sdk: implement the shared skill-facing projection runtime SDK so skills do not open-code projection executors, stream receiver routing, fingerprint maps, or dirty-section dispatch - [ ]
dispatcher.per_webspace_refresh: make demanded projection refresh run per webspace - [ ]
dispatcher.no_cross_webspace_churn: prevent one webspace from forcing writes into unrelated webspaces - [ ]
dispatcher.memory_richer_than_yjs: allow skills and platform services to keep richer semantic caches in memory than they publish into Yjs - [ ]
dispatcher.lifecycle_exposed: expose projection lifecycle transitions through the shared projection record - [ ]
dispatcher.pressure_observable: preserve eventbus/rebuild/stream pressure counters when dispatcher coalesces or suppresses work
Current status:
- selected eventbus hot topics are already bounded/coalesced as incident guardrails
- the dispatcher still needs to own demanded projection refresh, not merely reduce duplicate async work
6. Yjs Granularity and Client Adapter
- [ ]
yjs.adapter_projection_records: update the client-side Yjs adapter to read projection records instead of one giant scenario snapshot - [ ]
yjs.cache_by_projection_key: cache projection payloads byprojection_key - [ ]
yjs.reuse_cached_views: reuse cached payloads when switching back to recently materialized views - [ ]
yjs.reduce_broad_observers: avoid broadobserveDeep(data)patterns where a stable nested projection path is available - [ ]
yjs.legacy_compat_rules: document the compatibility rules for legacy plain-JSON projection branches during migration - [ ]
yjs.named_entity_registry_reference: useregistry.named_entitiesas an implemented read-only compatibility reference for projection fingerprinting and privacy limits
7. Early Pilot Sequence
- [ ]
pilot.status_cards_first: implement status cards as the first small platform-emitter projection family - [ ]
pilot.platform_surfaces_first: prepareweb_desktopand the shared platform surfaces first: notifications, diagnostics, workspace manager, and related modals - [ ]
pilot.platform_emitter_validated: validate platform-as-emitter semantics before migrating one heavy skill - [ ]
pilot.infrascope_after_prereqs: migrateInfrascopeonly after the core/runtime and client projection contracts are in place - [ ]
pilot.infrastate_aligned: aligninfrastate-style shared operational overlays with the same contract - [ ]
pilot.dev_scenario_followup: choose one dev-oriented scenario such asprompt_engineer_scenarioas the first non-operator follow-up - [ ]
pilot.simple_skills_deferred: postpone low-churn simple skills until the core contract and adapter behavior are stable
8. Infrascope Migration Slice
- [ ]
infrascope.split_projection_families: splitoverview,inventory,inspector,topology, and modal/widget payloads into separate projections - [ ]
infrascope.stop_full_inspector_snapshot: stop pre-materializing all inspectors into one Yjs snapshot - [ ]
infrascope.demanded_only_per_webspace: publish only the projections actively demanded by each webspace - [ ]
infrascope.shared_payload_access_metadata: verify that owner and guest use the same payload but can still receive different display/action treatment through access metadata - [ ]
infrascope.platform_errors_separate: publish platform-originated warnings and materialization errors as separate operator-facing projections instead of hiding them inside one skill snapshot
9. Cross-Skill Rollout
- [ ]
rollout.monolith_inventory: identify other browser-facing skills that currently publish monolithic Yjs JSON subtrees - [ ]
rollout.migrate_to_shared_contract: migrate them onto the shared projection/subscription contract - [ ]
rollout.shared_helpers: provide a common helper layer so each skill does not reimplement subscription parsing and dispatch logic - [ ]
rollout.manifest_rules: document how scenario manifests and skill manifests declare projection roots without inventing incompatible shapes
10. Cleanup and Hardening
- [ ]
cleanup.remove_monolith_paths: remove monolithic snapshot paths where the new projection contract fully replaces them - [ ]
cleanup.remove_inline_debounce: remove event-specific inline debounce logic that the dispatcher now supersedes - [ ]
cleanup.operator_projection_diagnostics: add operator diagnostics for active projections per webspace - [ ]
cleanup.test_multi_webspace_and_consumers: add tests for multi-webspace demand routing and multiple simultaneous consumers - [ ]
cleanup.test_access_metadata_and_dev: add tests for guest-visible access metadata anddevaudience handling - [ ]
cleanup.test_platform_emitters: add tests for platform-emitted diagnostics and error projections
Priority Candidates and Critical Assessment
The new model is best used first where all of the following are true:
- the UI has multiple independently visible surfaces
- updates are frequent or bursty
- more than one webspace may demand different projections
- the current implementation uses large plain-JSON Yjs branches
Recommended order:
- core/runtime plus client preparation The architectural contract should exist before one heavy skill becomes the pilot.
web_desktopplatform surfaces Best place to validate platform-as-emitter semantics for system messages, diagnostics, and shared browser/runtime failures.InfrascopeStrongest heavy-skill pressure test after the shared architecture exists.infrastateand similar operational overlays Good follow-up once operator-facing demand dispatch is proven.- one dev-oriented scenario
Good for testing
devaudience behavior and more panel-heavy view switching. - voice/media or other bursty interactive surfaces Valuable after the core dispatcher and client adapter are stable.
For the browser-client semantic ABI work that should precede broader renderer expansion, see Web UI Architecture. The first concrete validation target should be a demo scenario and demo skill with a table-oriented view, a chart-oriented view, and one shared selection/filter model rather than a broad speculative visualization catalog.
Current status of that validation target:
- the repository now contains
demo_metrics_skillandtaiga_ui_demo_scenario - the browser runtime can already materialize the demo table/chart/event slice through the current compatibility bridge
- first-environment stand verification is the next milestone before broader projection-oriented renderer work
Counter-example:
- simple low-churn skills with one small projection do not need to be forced onto this model immediately
Execution note:
- preparatory inventory for Infrascope is allowed before the platform pilot
- Infrascope must not introduce its own projection ABI, subscription record, or lifecycle contract ahead of phases 3-6 in the master roadmap
Acceptance Criteria
This roadmap is successful when:
- at least one complex operator scenario uses demand-driven projections instead of one monolithic snapshot
- multiple browser consumers in one webspace can demand different projections concurrently
- multiple webspaces can receive different projection refreshes from the same domain and platform event streams
- skills and platform services no longer need to publish their whole UI model into Yjs to keep the browser working
- the browser can switch back to a recently opened view without forcing a full rebuild every time