diff --git a/apps/android-demo/README.md b/apps/android-demo/README.md
deleted file mode 100644
index 0a2b2962..00000000
--- a/apps/android-demo/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Traverse Android Demo
-
-This is the first checked-in Android demo surface for Traverse.
-
-What it does:
-- renders one approved expedition flow
-- shows ordered runtime state updates
-- shows the final trace summary and output panel
-- assumes the runtime exists outside the app process
-
-Current implementation note:
-- the repo now contains the Android app structure, Compose source, and a deterministic fixture-driven rendering path
-- local smoke validation is available through `bash scripts/ci/android_demo_smoke.sh`
-- this machine does not currently have Gradle or an Android SDK configured, so native Android assembly is not part of the local green path here
-
-Expected local build path on a machine with Android tooling:
-- `cd apps/android-demo`
-- `./gradlew :app:assembleDebug`
-
-Fixture source:
-- `app/src/main/assets/expedition-runtime-session.json`
diff --git a/apps/android-demo/app/build.gradle.kts b/apps/android-demo/app/build.gradle.kts
deleted file mode 100644
index 7428ad7f..00000000
--- a/apps/android-demo/app/build.gradle.kts
+++ /dev/null
@@ -1,42 +0,0 @@
-plugins {
- id("com.android.application")
- id("org.jetbrains.kotlin.android")
-}
-
-android {
- namespace = "com.traverse.demo.android"
- compileSdk = 35
-
- defaultConfig {
- applicationId = "com.traverse.demo.android"
- minSdk = 28
- targetSdk = 35
- versionCode = 1
- versionName = "0.1.0"
- }
-
- buildFeatures {
- compose = true
- }
-
- composeOptions {
- kotlinCompilerExtensionVersion = "1.5.14"
- }
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-
- kotlinOptions {
- jvmTarget = "17"
- }
-}
-
-dependencies {
- implementation(platform("androidx.compose:compose-bom:2024.09.02"))
- implementation("androidx.activity:activity-compose:1.9.2")
- implementation("androidx.compose.material3:material3")
- implementation("androidx.compose.ui:ui")
- implementation("androidx.compose.ui:ui-tooling-preview")
-}
diff --git a/apps/android-demo/app/src/main/AndroidManifest.xml b/apps/android-demo/app/src/main/AndroidManifest.xml
deleted file mode 100644
index 2084f06c..00000000
--- a/apps/android-demo/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/android-demo/app/src/main/assets/expedition-runtime-session.json b/apps/android-demo/app/src/main/assets/expedition-runtime-session.json
deleted file mode 100644
index bcee3cc4..00000000
--- a/apps/android-demo/app/src/main/assets/expedition-runtime-session.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "demo_id": "expedition.plan.v1",
- "title": "Plan Expedition",
- "request_id": "req-expedition-001",
- "execution_id": "exec_req-expedition-001",
- "trace_id": "trace_exec_req-expedition-001",
- "status": "completed",
- "summary": "Traverse evaluates the governed expedition workflow and assembles a final expedition plan."
-}
diff --git a/apps/android-demo/app/src/main/java/com/traverse/demo/android/MainActivity.kt b/apps/android-demo/app/src/main/java/com/traverse/demo/android/MainActivity.kt
deleted file mode 100644
index 3759a16f..00000000
--- a/apps/android-demo/app/src/main/java/com/traverse/demo/android/MainActivity.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.traverse.demo.android
-
-import android.os.Bundle
-import androidx.activity.ComponentActivity
-import androidx.activity.compose.setContent
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.PaddingValues
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.material3.Card
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Scaffold
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.unit.dp
-
-class MainActivity : ComponentActivity() {
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContent {
- MaterialTheme {
- TraverseAndroidDemoScreen(sampleStateUpdates)
- }
- }
- }
-}
-
-private val sampleStateUpdates = listOf(
- DemoStateUpdate(
- "Discovering capability",
- "Looking up expedition.planning.plan-expedition@1.0.0 in the registry."
- ),
- DemoStateUpdate(
- "Evaluating constraints",
- "Confirming the approved expedition capability can run locally."
- ),
- DemoStateUpdate(
- "Executing workflow",
- "Traversing the approved expedition planning workflow."
- ),
- DemoStateUpdate(
- "Completed",
- "The expedition plan is ready for final review."
- )
-)
-
-data class DemoStateUpdate(
- val title: String,
- val detail: String,
-)
-
-@Composable
-private fun TraverseAndroidDemoScreen(stateUpdates: List) {
- Scaffold { padding ->
- LazyColumn(
- modifier = Modifier
- .fillMaxSize()
- .padding(padding),
- contentPadding = PaddingValues(16.dp),
- verticalArrangement = Arrangement.spacedBy(12.dp),
- ) {
- item {
- Card(modifier = Modifier.fillMaxWidth()) {
- Column(modifier = Modifier.padding(16.dp)) {
- Text("Traverse Android Demo", style = MaterialTheme.typography.headlineSmall)
- Text(
- "Plan Expedition",
- style = MaterialTheme.typography.titleMedium,
- modifier = Modifier.padding(top = 8.dp)
- )
- Text(
- "Runtime states and final trace summary render from the approved expedition demo fixture.",
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(top = 8.dp)
- )
- }
- }
- }
-
- items(stateUpdates) { update ->
- Card(modifier = Modifier.fillMaxWidth()) {
- Column(modifier = Modifier.padding(16.dp)) {
- Text(update.title, style = MaterialTheme.typography.titleMedium)
- Text(
- update.detail,
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(top = 6.dp)
- )
- }
- }
- }
- }
- }
-}
diff --git a/apps/android-demo/app/src/main/res/values/strings.xml b/apps/android-demo/app/src/main/res/values/strings.xml
deleted file mode 100644
index 75f48c8d..00000000
--- a/apps/android-demo/app/src/main/res/values/strings.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
- Traverse Android Demo
-
diff --git a/apps/android-demo/build.gradle.kts b/apps/android-demo/build.gradle.kts
deleted file mode 100644
index 017d9099..00000000
--- a/apps/android-demo/build.gradle.kts
+++ /dev/null
@@ -1,4 +0,0 @@
-plugins {
- id("com.android.application") version "8.5.2" apply false
- id("org.jetbrains.kotlin.android") version "1.9.24" apply false
-}
diff --git a/apps/android-demo/gradle.properties b/apps/android-demo/gradle.properties
deleted file mode 100644
index e6961679..00000000
--- a/apps/android-demo/gradle.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
-android.useAndroidX=true
-kotlin.code.style=official
diff --git a/apps/android-demo/settings.gradle.kts b/apps/android-demo/settings.gradle.kts
deleted file mode 100644
index 9614dec3..00000000
--- a/apps/android-demo/settings.gradle.kts
+++ /dev/null
@@ -1,2 +0,0 @@
-rootProject.name = "TraverseAndroidDemo"
-include(":app")
diff --git a/apps/browser-consumer/README.md b/apps/browser-consumer/README.md
deleted file mode 100644
index 172961c6..00000000
--- a/apps/browser-consumer/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Traverse Browser Consumer Package
-
-This is the browser-targeted consumer package for downstream apps such as `youaskm3`.
-
-It stays focused on the first governed browser-hosted path:
-
-- it reuses the approved live browser adapter client
-- it exposes a browser-safe subscription flow for the downstream app
-- it keeps runtime ordering, trace visibility, and terminal outcomes governed by Traverse surfaces rather than private app logic
-- it does not define UI, branding, or app-specific product behavior
-
-## Supported Use
-
-The package is intended to be consumed by a browser-hosted app that can bundle the façade and point it at the live browser adapter proxy.
-
-It provides:
-
-- a browser consumer session shape
-- approved subscription request construction
-- live subscription execution
-- ordered browser subscription message application
-- terminal trace summarization
-
-## Browser-Hosted Assumptions
-
-- The browser-hosted app has access to the approved live browser adapter proxy path.
-- The browser-hosted app uses the published consumer façade rather than internal Traverse crate layout.
-- The browser-hosted app relies on governed runtime updates, trace visibility, and terminal outcomes from Traverse.
-- Unsupported auth, remote deployment, and multi-tenant guarantees remain out of scope for the first slice.
-
-## Quick Start
-
-```bash
-node -e "const client = require('./apps/browser-consumer'); console.log(client.APPROVED_BROWSER_CONSUMER_SESSION.title)"
-```
-
-For the deterministic browser-hosted smoke path, see [../../scripts/ci/browser_consumer_package_smoke.sh](/Users/piovese/Documents/cogolo/scripts/ci/browser_consumer_package_smoke.sh).
diff --git a/apps/browser-consumer/index.js b/apps/browser-consumer/index.js
deleted file mode 100644
index f2e42e87..00000000
--- a/apps/browser-consumer/index.js
+++ /dev/null
@@ -1,67 +0,0 @@
-(function (root, factory) {
- const client = factory();
-
- if (typeof module === "object" && module.exports) {
- module.exports = client;
- }
-
- if (root) {
- root.TraverseBrowserConsumer = client;
- }
-})(typeof globalThis !== "undefined" ? globalThis : this, function () {
- let baseClient = null;
-
- if (typeof require === "function") {
- try {
- baseClient = require("../react-demo/src/browser-adapter-client.js");
- } catch {
- baseClient = null;
- }
- }
-
- if (!baseClient && typeof globalThis !== "undefined" && globalThis.TraverseReactDemoClient) {
- baseClient = globalThis.TraverseReactDemoClient;
- }
-
- if (!baseClient) {
- throw new Error(
- "Traverse browser consumer requires the approved browser adapter client to be available.",
- );
- }
-
- const APPROVED_BROWSER_CONSUMER_SESSION = {
- ...baseClient.APPROVED_BROWSER_DEMO_SESSION,
- title: "Traverse Browser Consumer",
- summary:
- "Traverse's browser-targeted consumer facade for downstream browser-hosted apps like youaskm3.",
- };
-
- function createBrowserConsumerState() {
- return baseClient.createLiveDemoState();
- }
-
- function buildBrowserConsumerSubscriptionRequest() {
- return baseClient.buildApprovedSubscriptionRequest();
- }
-
- function runBrowserConsumerSubscription(options = {}) {
- return baseClient.runLiveBrowserSubscription(options);
- }
-
- function applyBrowserConsumerMessage(state, message, created) {
- return baseClient.applyBrowserSubscriptionMessage(state, message, created);
- }
-
- function browserConsumerTraceSummary(trace, terminalResult) {
- return baseClient.traceSummary(trace, terminalResult);
- }
-
- return {
- APPROVED_BROWSER_CONSUMER_SESSION,
- applyBrowserConsumerMessage,
- browserConsumerTraceSummary,
- buildBrowserConsumerSubscriptionRequest,
- createBrowserConsumerState,
- runBrowserConsumerSubscription,
- };
-});
diff --git a/apps/browser-consumer/package.json b/apps/browser-consumer/package.json
deleted file mode 100644
index 09701322..00000000
--- a/apps/browser-consumer/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "traverse-browser-consumer",
- "version": "0.1.0",
- "private": true,
- "main": "index.js",
- "description": "Traverse browser-targeted consumer facade for downstream browser-hosted apps."
-}
diff --git a/apps/macos-demo/Package.swift b/apps/macos-demo/Package.swift
deleted file mode 100644
index 62193ecc..00000000
--- a/apps/macos-demo/Package.swift
+++ /dev/null
@@ -1,18 +0,0 @@
-// swift-tools-version: 6.0
-import PackageDescription
-
-let package = Package(
- name: "TraverseMacOSDemo",
- platforms: [
- .macOS(.v14),
- ],
- products: [
- .executable(name: "TraverseMacOSDemoApp", targets: ["TraverseMacOSDemoApp"]),
- ],
- targets: [
- .executableTarget(
- name: "TraverseMacOSDemoApp",
- path: "Sources/TraverseMacOSDemoApp"
- ),
- ]
-)
diff --git a/apps/macos-demo/README.md b/apps/macos-demo/README.md
deleted file mode 100644
index ad23688e..00000000
--- a/apps/macos-demo/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Traverse macOS Demo
-
-This is the first native macOS demo surface for Traverse.
-
-What it does:
-- renders one approved expedition flow
-- shows ordered runtime state updates
-- shows the final trace summary and output panel
-- keeps the runtime separate from the app process
-
-Current implementation note:
-- this repo currently checks in the native SwiftUI app source and deterministic fixture-driven rendering path
-- local smoke validation is available through `bash scripts/ci/macos_demo_smoke.sh`
-- a full Xcode app build requires a full Xcode installation; this machine currently only exposes Command Line Tools, so native app compilation is not part of the local green path here
-
-Expected local run path on a machine with full Xcode:
-- `open apps/macos-demo/Package.swift`
-- run the `TraverseMacOSDemoApp` target
-
-Fixture source:
-- `examples/fixtures/expedition-runtime-session.json`
diff --git a/apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoContentView.swift b/apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoContentView.swift
deleted file mode 100644
index a885f3cc..00000000
--- a/apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoContentView.swift
+++ /dev/null
@@ -1,87 +0,0 @@
-import SwiftUI
-
-struct DemoSessionViewModel {
- let session: DemoSession
-
- static func sample() -> DemoSessionViewModel {
- DemoSessionViewModel(session: DemoSessionRepository.sample())
- }
-}
-
-struct DemoContentView: View {
- let viewModel: DemoSessionViewModel
-
- var body: some View {
- NavigationSplitView {
- List(viewModel.session.stateUpdates) { update in
- VStack(alignment: .leading, spacing: 6) {
- Text(update.title)
- .font(.headline)
- Text(update.detail)
- .font(.subheadline)
- .foregroundStyle(.secondary)
- Text(update.timestamp)
- .font(.caption.monospaced())
- .foregroundStyle(.tertiary)
- }
- .padding(.vertical, 6)
- }
- .navigationTitle(viewModel.session.title)
- } detail: {
- ScrollView {
- VStack(alignment: .leading, spacing: 18) {
- GroupBox("Runtime Summary") {
- VStack(alignment: .leading, spacing: 10) {
- labeledRow("Status", value: viewModel.session.status)
- labeledRow("Request", value: viewModel.session.requestID)
- labeledRow("Execution", value: viewModel.session.executionID)
- labeledRow("Trace", value: viewModel.session.traceID)
- labeledRow("Target", value: viewModel.session.trace.placement.selectedTarget)
- Text(viewModel.session.summary)
- .font(.body)
- }
- .frame(maxWidth: .infinity, alignment: .leading)
- }
-
- GroupBox("Request Goal") {
- Text(viewModel.session.request.goal)
- .frame(maxWidth: .infinity, alignment: .leading)
- }
-
- GroupBox("Emitted Events") {
- VStack(alignment: .leading, spacing: 8) {
- ForEach(viewModel.session.trace.emittedEvents, id: \.self) { eventID in
- Text(eventID)
- .font(.body.monospaced())
- }
- }
- .frame(maxWidth: .infinity, alignment: .leading)
- }
-
- GroupBox("Final Output") {
- VStack(alignment: .leading, spacing: 10) {
- labeledRow("Plan ID", value: viewModel.session.trace.output.planID)
- labeledRow("Route", value: viewModel.session.trace.output.route)
- labeledRow("Weather", value: viewModel.session.trace.output.weatherSummary)
- labeledRow("Team Status", value: viewModel.session.trace.output.teamStatus)
- labeledRow("Next Action", value: viewModel.session.trace.output.nextAction)
- }
- .frame(maxWidth: .infinity, alignment: .leading)
- }
- }
- .padding(24)
- }
- }
- }
-
- @ViewBuilder
- private func labeledRow(_ label: String, value: String) -> some View {
- VStack(alignment: .leading, spacing: 4) {
- Text(label)
- .font(.caption)
- .foregroundStyle(.secondary)
- Text(value)
- .font(.body)
- }
- }
-}
diff --git a/apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoSession.swift b/apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoSession.swift
deleted file mode 100644
index 3bfa58f1..00000000
--- a/apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoSession.swift
+++ /dev/null
@@ -1,136 +0,0 @@
-import Foundation
-
-struct DemoSession: Decodable {
- let demoID: String
- let title: String
- let requestID: String
- let executionID: String
- let traceID: String
- let status: String
- let summary: String
- let request: DemoRequest
- let stateUpdates: [DemoStateUpdate]
- let trace: DemoTrace
-
- enum CodingKeys: String, CodingKey {
- case demoID = "demo_id"
- case title
- case requestID = "request_id"
- case executionID = "execution_id"
- case traceID = "trace_id"
- case status
- case summary
- case request
- case stateUpdates = "state_updates"
- case trace
- }
-}
-
-struct DemoRequest: Decodable {
- let goal: String
- let requestedTarget: String
- let caller: String
-
- enum CodingKeys: String, CodingKey {
- case goal
- case requestedTarget = "requested_target"
- case caller
- }
-}
-
-struct DemoStateUpdate: Decodable, Identifiable {
- let state: String
- let title: String
- let timestamp: String
- let detail: String
-
- var id: String { "\(timestamp)-\(state)" }
-}
-
-struct DemoTrace: Decodable {
- let selectedCapabilityID: String
- let selectedCapabilityVersion: String
- let placement: DemoPlacement
- let emittedEvents: [String]
- let output: DemoOutput
-
- enum CodingKeys: String, CodingKey {
- case selectedCapabilityID = "selected_capability_id"
- case selectedCapabilityVersion = "selected_capability_version"
- case placement
- case emittedEvents = "emitted_events"
- case output
- }
-}
-
-struct DemoPlacement: Decodable {
- let requestedTarget: String
- let selectedTarget: String
- let status: String
- let reason: String
-
- enum CodingKeys: String, CodingKey {
- case requestedTarget = "requested_target"
- case selectedTarget = "selected_target"
- case status
- case reason
- }
-}
-
-struct DemoOutput: Decodable {
- let planID: String
- let route: String
- let weatherSummary: String
- let teamStatus: String
- let nextAction: String
-
- enum CodingKeys: String, CodingKey {
- case planID = "plan_id"
- case route
- case weatherSummary = "weather_summary"
- case teamStatus = "team_status"
- case nextAction = "next_action"
- }
-}
-
-enum DemoSessionRepository {
- static func sample() -> DemoSession {
- let url = URL(fileURLWithPath: "examples/fixtures/expedition-runtime-session.json")
- let data = (try? Data(contentsOf: url)) ?? Data()
- let decoder = JSONDecoder()
-
- if let session = try? decoder.decode(DemoSession.self, from: data) {
- return session
- }
-
- return DemoSession(
- demoID: "fallback",
- title: "Traverse macOS Demo",
- requestID: "req-fallback",
- executionID: "exec-fallback",
- traceID: "trace-fallback",
- status: "error",
- summary: "Fixture loading failed.",
- request: DemoRequest(goal: "Unavailable", requestedTarget: "local", caller: "native_demo"),
- stateUpdates: [],
- trace: DemoTrace(
- selectedCapabilityID: "unavailable",
- selectedCapabilityVersion: "0.0.0",
- placement: DemoPlacement(
- requestedTarget: "local",
- selectedTarget: "local",
- status: "not_attempted",
- reason: "fixture_unavailable"
- ),
- emittedEvents: [],
- output: DemoOutput(
- planID: "unavailable",
- route: "Unavailable",
- weatherSummary: "Unavailable",
- teamStatus: "unavailable",
- nextAction: "Restore the fixture file."
- )
- )
- )
- }
-}
diff --git a/apps/macos-demo/Sources/TraverseMacOSDemoApp/TraverseMacOSDemoApp.swift b/apps/macos-demo/Sources/TraverseMacOSDemoApp/TraverseMacOSDemoApp.swift
deleted file mode 100644
index ad45092f..00000000
--- a/apps/macos-demo/Sources/TraverseMacOSDemoApp/TraverseMacOSDemoApp.swift
+++ /dev/null
@@ -1,12 +0,0 @@
-import SwiftUI
-
-@main
-struct TraverseMacOSDemoApp: App {
- var body: some Scene {
- WindowGroup("Traverse macOS Demo") {
- DemoContentView(viewModel: DemoSessionViewModel.sample())
- .frame(minWidth: 1080, minHeight: 720)
- }
- .windowStyle(.titleBar)
- }
-}
diff --git a/apps/react-demo/README.md b/apps/react-demo/README.md
deleted file mode 100644
index cf0b340c..00000000
--- a/apps/react-demo/README.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# Traverse React Demo
-
-This is the first checked-in React browser demo surface for Traverse.
-
-If you want the shortest end-to-end local path, start with [quickstart.md](/Users/piovese/Documents/cogolo/quickstart.md) and then come back here for the demo-specific details.
-
-If you want the formal app-consumable acceptance entrypoint, use [docs/app-consumable-acceptance.md](/Users/piovese/Documents/cogolo/docs/app-consumable-acceptance.md).
-
-What it does:
-- renders one approved expedition flow
-- allows one approved request submission path
-- shows ordered runtime state updates streamed from the live local browser adapter
-- shows the final trace snapshot and output panel after the stream completes
-- keeps the approved browser-subscription session shape while consuming the live adapter through a same-origin local proxy
-
-Local live run path:
-
-```bash
-cargo run -p traverse-cli -- browser-adapter serve --bind 127.0.0.1:4174
-node apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173
-```
-
-Open:
-
-- `http://127.0.0.1:4173`
-
-Note:
-
-- the React app consumes the live browser adapter through the local proxy server
-- if the local adapter cannot be started automatically, use the fallback preview path below
-- Run the local browser adapter proxy again if you need to refresh the live stream setup
-
-Fallback preview path:
-
-```bash
-python3 -m http.server 4173 --directory apps/react-demo
-```
-
-The fallback preview keeps the checked-in fixture-driven render path available for offline inspection and smoke validation.
-
-For the first app-consumable quickstart that uses the live browser adapter path, see [../../quickstart.md](/Users/piovese/Documents/cogolo/quickstart.md).
-
-Live smoke path:
-
-```bash
-bash scripts/ci/react_demo_live_adapter_smoke.sh
-```
-
-Fallback smoke path:
-
-```bash
-bash scripts/ci/react_demo_smoke.sh
-```
-
-Fixture source:
-
-- `apps/react-demo/public/expedition-runtime-session.json`
-
-Runtime assets:
-
-- `apps/react-demo/vendor/react.development.js`
-- `apps/react-demo/vendor/react-dom.development.js`
diff --git a/apps/react-demo/index.html b/apps/react-demo/index.html
deleted file mode 100644
index 6a7e124d..00000000
--- a/apps/react-demo/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
-
-
- Traverse React Demo
-
-
-
-
-
-
-
-
-
-
diff --git a/apps/react-demo/public/expedition-runtime-session.json b/apps/react-demo/public/expedition-runtime-session.json
deleted file mode 100644
index 174391ab..00000000
--- a/apps/react-demo/public/expedition-runtime-session.json
+++ /dev/null
@@ -1,76 +0,0 @@
-{
- "demo_id": "expedition.plan.v1",
- "title": "Plan Expedition",
- "request_id": "req-expedition-001",
- "execution_id": "exec_req-expedition-001",
- "trace_id": "trace_exec_req-expedition-001",
- "status": "completed",
- "summary": "Traverse evaluates the governed expedition workflow and assembles a final expedition plan.",
- "request": {
- "goal": "Plan a two-day alpine expedition for a four-person team.",
- "requested_target": "local",
- "caller": "browser_demo"
- },
- "state_updates": [
- {
- "state": "discovering",
- "title": "Discovering capability",
- "timestamp": "2026-03-30T10:00:00Z",
- "detail": "Looking up expedition.planning.plan-expedition@1.0.0 in the private-first registry."
- },
- {
- "state": "evaluating_constraints",
- "title": "Evaluating constraints",
- "timestamp": "2026-03-30T10:00:01Z",
- "detail": "Confirmed local execution is allowed for the approved expedition capability."
- },
- {
- "state": "selecting",
- "title": "Selecting workflow-backed capability",
- "timestamp": "2026-03-30T10:00:02Z",
- "detail": "Selected expedition.planning.plan-expedition@1.0.0."
- },
- {
- "state": "executing",
- "title": "Executing workflow",
- "timestamp": "2026-03-30T10:00:03Z",
- "detail": "Running the approved workflow steps to capture intent, assess conditions, validate readiness, and assemble the plan."
- },
- {
- "state": "emitting_events",
- "title": "Publishing governed events",
- "timestamp": "2026-03-30T10:00:04Z",
- "detail": "Emitting expedition objective, interpreted intent, conditions summary, readiness, and assembled plan events."
- },
- {
- "state": "completed",
- "title": "Completed",
- "timestamp": "2026-03-30T10:00:05Z",
- "detail": "The final expedition plan is ready for review."
- }
- ],
- "trace": {
- "selected_capability_id": "expedition.planning.plan-expedition",
- "selected_capability_version": "1.0.0",
- "placement": {
- "requested_target": "local",
- "selected_target": "local",
- "status": "selected",
- "reason": "requested_target_selected"
- },
- "emitted_events": [
- "expedition.planning.expedition-objective-captured@1.0.0",
- "expedition.planning.expedition-intent-interpreted@1.0.0",
- "expedition.planning.conditions-summary-assessed@1.0.0",
- "expedition.planning.team-readiness-validated@1.0.0",
- "expedition.planning.expedition-plan-assembled@1.0.0"
- ],
- "output": {
- "plan_id": "plan-001",
- "route": "North Glacier approach with base-camp ascent",
- "weather_summary": "Cold start with stable winds and acceptable avalanche risk by midday.",
- "team_status": "ready_with_layering_adjustments",
- "next_action": "Review equipment checklist and confirm departure window."
- }
- }
-}
diff --git a/apps/react-demo/server.mjs b/apps/react-demo/server.mjs
deleted file mode 100644
index b76710d1..00000000
--- a/apps/react-demo/server.mjs
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/env node
-
-import { createServer } from "node:http";
-import { readFile } from "node:fs/promises";
-import { extname, join, normalize } from "node:path";
-import { fileURLToPath } from "node:url";
-
-const rootDir = fileURLToPath(new URL(".", import.meta.url));
-const defaultPort = 4173;
-const defaultAdapterBaseUrl = "http://127.0.0.1:4174";
-
-const { port, adapterBaseUrl } = parseArgs(process.argv.slice(2));
-const adapterOrigin = new URL(adapterBaseUrl);
-
-const server = createServer(async (request, response) => {
- try {
- if (request.url?.startsWith("/local/browser-subscriptions")) {
- await proxyBrowserAdapter(request, response, adapterOrigin);
- return;
- }
-
- await serveStaticAsset(request, response);
- } catch (error) {
- response.statusCode = 500;
- response.setHeader("Content-Type", "text/plain; charset=utf-8");
- response.end(String(error));
- }
-});
-
-server.listen(port, "127.0.0.1", () => {
- console.log(`Traverse React demo serving on http://127.0.0.1:${port}`);
- console.log(`Proxying browser adapter requests to ${adapterOrigin.origin}`);
-});
-
-function parseArgs(args) {
- let port = defaultPort;
- let adapterBaseUrl = defaultAdapterBaseUrl;
-
- for (let index = 0; index < args.length; index += 1) {
- const current = args[index];
- if (current === "--port" && args[index + 1]) {
- port = Number(args[index + 1]);
- index += 1;
- } else if (current === "--adapter" && args[index + 1]) {
- adapterBaseUrl = args[index + 1];
- index += 1;
- }
- }
-
- if (!Number.isInteger(port) || port <= 0) {
- throw new Error(`invalid port: ${port}`);
- }
-
- return { port, adapterBaseUrl };
-}
-
-async function proxyBrowserAdapter(request, response, adapterOrigin) {
- const targetUrl = new URL(request.url, adapterOrigin);
- const headers = new Headers();
-
- for (const [name, value] of Object.entries(request.headers)) {
- if (value === undefined) {
- continue;
- }
- if (["host", "connection", "content-length"].includes(name.toLowerCase())) {
- continue;
- }
- headers.set(name, Array.isArray(value) ? value.join(", ") : value);
- }
-
- let body = undefined;
- if (!["GET", "HEAD"].includes(request.method || "")) {
- body = await readRequestBody(request);
- }
-
- const upstreamResponse = await fetch(targetUrl, {
- method: request.method,
- headers,
- body,
- });
-
- response.statusCode = upstreamResponse.status;
- response.statusMessage = upstreamResponse.statusText;
-
- upstreamResponse.headers.forEach((value, name) => {
- if (name.toLowerCase() === "content-length") {
- return;
- }
- response.setHeader(name, value);
- });
-
- if (!upstreamResponse.body) {
- response.end();
- return;
- }
-
- const reader = upstreamResponse.body.getReader();
- while (true) {
- const { done, value } = await reader.read();
- if (done) {
- break;
- }
- response.write(Buffer.from(value));
- }
-
- response.end();
-}
-
-async function serveStaticAsset(request, response) {
- const requestPath = request.url?.split("?")[0] ?? "/";
- const normalizedPath = normalize(requestPath).replace(/^([.][.][/\\])+/, "");
- const filePath = normalizedPath === "/" ? "index.html" : normalizedPath.replace(/^\//, "");
- const resolvedPath = join(rootDir, filePath);
-
- try {
- const contents = await readFile(resolvedPath);
- response.statusCode = 200;
- response.setHeader("Content-Type", contentTypeFor(resolvedPath));
- response.end(contents);
- } catch {
- if (requestPath !== "/") {
- const indexPath = join(rootDir, "index.html");
- const contents = await readFile(indexPath);
- response.statusCode = 200;
- response.setHeader("Content-Type", "text/html; charset=utf-8");
- response.end(contents);
- return;
- }
-
- response.statusCode = 404;
- response.setHeader("Content-Type", "text/plain; charset=utf-8");
- response.end("Not found");
- }
-}
-
-function contentTypeFor(filePath) {
- switch (extname(filePath)) {
- case ".html":
- return "text/html; charset=utf-8";
- case ".js":
- return "text/javascript; charset=utf-8";
- case ".css":
- return "text/css; charset=utf-8";
- case ".json":
- return "application/json; charset=utf-8";
- default:
- return "application/octet-stream";
- }
-}
-
-async function readRequestBody(request) {
- const chunks = [];
- for await (const chunk of request) {
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
- }
- return Buffer.concat(chunks);
-}
diff --git a/apps/react-demo/src/browser-adapter-client.js b/apps/react-demo/src/browser-adapter-client.js
deleted file mode 100644
index f59d113c..00000000
--- a/apps/react-demo/src/browser-adapter-client.js
+++ /dev/null
@@ -1,330 +0,0 @@
-(function (root, factory) {
- const client = factory();
-
- if (typeof module === "object" && module.exports) {
- module.exports = client;
- }
-
- if (root) {
- root.TraverseReactDemoClient = client;
- }
-})(typeof globalThis !== "undefined" ? globalThis : this, function () {
- const APPROVED_BROWSER_DEMO_SESSION = {
- title: "Plan Expedition",
- summary:
- "Traverse evaluates the governed expedition workflow and assembles a final expedition plan.",
- request: {
- goal: "Plan a two-day alpine expedition for a four-person team.",
- requested_target: "local",
- caller: "browser_demo",
- },
- request_id: "expedition-plan-request-001",
- execution_id: "exec_expedition-plan-request-001",
- trace_id: "trace_exec_expedition-plan-request-001",
- };
-
- function createLiveDemoState() {
- return {
- phase: "idle",
- statusLabel: "ready",
- streamBanner: "No subscription active yet. Submit the approved request to begin.",
- requestId: null,
- executionId: null,
- stateUpdates: [],
- liveTrace: null,
- liveResult: null,
- error: "",
- };
- }
-
- function buildApprovedSubscriptionRequest() {
- return {
- subscription_request: {
- kind: "browser_runtime_subscription_request",
- schema_version: "1.0.0",
- governing_spec: "013-browser-runtime-subscription",
- request_id: APPROVED_BROWSER_DEMO_SESSION.request_id,
- },
- };
- }
-
- function humanizeName(value) {
- return value
- .toString()
- .split("_")
- .filter(Boolean)
- .map((part) => part.slice(0, 1).toUpperCase() + part.slice(1))
- .join(" ");
- }
-
- function formatDetailValue(value) {
- if (value === null || value === undefined) {
- return "";
- }
- if (typeof value === "string") {
- return value;
- }
- if (typeof value === "number" || typeof value === "boolean") {
- return String(value);
- }
- return JSON.stringify(value);
- }
-
- function describeStateEvent(stateEvent) {
- const details = stateEvent.details || {};
- const parts = [];
-
- if (details.transition_reason) {
- parts.push(humanizeName(details.transition_reason));
- }
-
- for (const [key, value] of Object.entries(details)) {
- if (key === "transition_reason") {
- continue;
- }
- parts.push(`${humanizeName(key)}: ${formatDetailValue(value)}`);
- }
-
- return parts.length > 0 ? parts.join(" · ") : "State update received.";
- }
-
- function formatStateUpdate(stateEvent) {
- return {
- state: stateEvent.state,
- title: humanizeName(stateEvent.state),
- timestamp: stateEvent.entered_at,
- detail: describeStateEvent(stateEvent),
- };
- }
-
- function normalizeSubscriptionMessage(message) {
- const variant = Object.keys(message || {})[0];
- if (!variant) {
- return null;
- }
- return {
- variant,
- payload: message[variant],
- };
- }
-
- function parseSubscriptionFrame(frame) {
- let eventName = "";
- let data = "";
-
- for (const line of frame.split(/\r?\n/)) {
- if (line.startsWith("event: ")) {
- eventName = line.slice("event: ".length);
- } else if (line.startsWith("data: ")) {
- data += line.slice("data: ".length);
- }
- }
-
- if (!eventName || !data) {
- return null;
- }
-
- return {
- event: eventName,
- data: JSON.parse(data),
- };
- }
-
- function parseSubscriptionFrames(text) {
- return text
- .split(/\r?\n\r?\n/)
- .map((frame) => frame.trim())
- .filter(Boolean)
- .map(parseSubscriptionFrame)
- .filter(Boolean);
- }
-
- async function runLiveBrowserSubscription({
- baseUrl = "",
- fetchImpl = globalThis.fetch,
- onMessage,
- } = {}) {
- const adapterPrefix = baseUrl.replace(/\/$/, "");
- const createResponse = await fetchImpl(`${adapterPrefix}/local/browser-subscriptions`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(buildApprovedSubscriptionRequest()),
- });
-
- const createdPayload = await createResponse.text();
- if (!createResponse.ok) {
- throw new Error(`local browser adapter setup failed: ${createdPayload}`);
- }
-
- const created = JSON.parse(createdPayload);
- const streamResponse = await fetchImpl(`${adapterPrefix}${created.stream_url}`, {
- headers: {
- Accept: "text/event-stream",
- },
- });
-
- if (!streamResponse.ok) {
- const errorPayload = await streamResponse.text();
- throw new Error(`local browser adapter stream failed: ${errorPayload}`);
- }
-
- if (!streamResponse.body || typeof streamResponse.body.getReader !== "function") {
- throw new Error("local browser adapter stream did not expose a readable body");
- }
-
- const reader = streamResponse.body.getReader();
- const decoder = new TextDecoder();
- let buffer = "";
- const messages = [];
-
- while (true) {
- const { done, value } = await reader.read();
- if (done) {
- break;
- }
-
- buffer += decoder.decode(value, { stream: true });
- const frames = buffer.split(/\r?\n\r?\n/);
- buffer = frames.pop() || "";
-
- for (const frame of frames) {
- const parsed = parseSubscriptionFrame(frame.trim());
- if (!parsed) {
- continue;
- }
-
- const normalized = normalizeSubscriptionMessage(parsed.data);
- if (!normalized) {
- continue;
- }
-
- messages.push(normalized);
- if (typeof onMessage === "function") {
- onMessage(normalized, created);
- }
- }
- }
-
- const tail = buffer.trim();
- if (tail) {
- const parsed = parseSubscriptionFrame(tail);
- if (parsed) {
- const normalized = normalizeSubscriptionMessage(parsed.data);
- if (normalized) {
- messages.push(normalized);
- if (typeof onMessage === "function") {
- onMessage(normalized, created);
- }
- }
- }
- }
-
- return {
- created,
- messages,
- };
- }
-
- function applyBrowserSubscriptionMessage(state, message, created) {
- const nextState = {
- ...state,
- error: "",
- };
-
- switch (message.variant) {
- case "Lifecycle": {
- const lifecycle = message.payload;
- nextState.requestId = lifecycle.request_id;
- nextState.executionId = lifecycle.execution_id;
- nextState.statusLabel =
- lifecycle.status === "subscription_established"
- ? "streaming"
- : lifecycle.status === "stream_completed"
- ? "completed"
- : lifecycle.status;
- nextState.streamBanner =
- lifecycle.status === "subscription_established"
- ? "Subscription established. Streaming ordered runtime updates."
- : "Stream completed. Final trace artifact is now visible.";
- nextState.phase =
- lifecycle.status === "subscription_established"
- ? "streaming"
- : lifecycle.status === "stream_completed"
- ? "completed"
- : nextState.phase;
- if (created) {
- nextState.subscriptionId = created.subscription_id;
- }
- return nextState;
- }
- case "State": {
- nextState.phase = "streaming";
- nextState.statusLabel = "streaming";
- nextState.streamBanner = "Subscription established. Streaming ordered runtime updates.";
- nextState.stateUpdates = nextState.stateUpdates.concat(formatStateUpdate(message.payload.state_event));
- return nextState;
- }
- case "TraceArtifact": {
- nextState.liveTrace = message.payload.trace;
- return nextState;
- }
- case "StreamTerminal": {
- nextState.liveResult = message.payload.result;
- nextState.phase = "completed";
- nextState.statusLabel = "completed";
- nextState.streamBanner = "Stream completed. Final trace artifact is now visible.";
- return nextState;
- }
- case "Error": {
- nextState.phase = "error";
- nextState.statusLabel = "error";
- nextState.error = message.payload.message;
- nextState.streamBanner = message.payload.message;
- return nextState;
- }
- default:
- return nextState;
- }
- }
-
- function traceSummary(trace, terminalResult) {
- if (!trace || !trace.selection || !trace.execution) {
- return null;
- }
-
- const output = (terminalResult && terminalResult.output) || (trace.result && trace.result.output) || null;
- return {
- selection: {
- capability: trace.selection.selected_capability_id,
- version: trace.selection.selected_capability_version,
- placementTarget: trace.execution.placement.selected_target,
- placementReason: trace.execution.placement.reason,
- },
- emittedEvents: trace.emitted_events || [],
- output: output
- ? {
- planId: output.plan_id,
- route: output.route,
- weatherSummary: output.weather_summary,
- teamStatus: output.team_status,
- nextAction: output.next_action,
- }
- : null,
- };
- }
-
- return {
- APPROVED_BROWSER_DEMO_SESSION,
- applyBrowserSubscriptionMessage,
- buildApprovedSubscriptionRequest,
- createLiveDemoState,
- humanizeName,
- normalizeSubscriptionMessage,
- parseSubscriptionFrames,
- parseSubscriptionFrame,
- runLiveBrowserSubscription,
- traceSummary,
- };
-});
diff --git a/apps/react-demo/src/main.js b/apps/react-demo/src/main.js
deleted file mode 100644
index ca24e2bd..00000000
--- a/apps/react-demo/src/main.js
+++ /dev/null
@@ -1,234 +0,0 @@
-const { createElement: h, useState } = React;
-
-const DemoClient = window.TraverseReactDemoClient;
-const APPROVED_SESSION = DemoClient.APPROVED_BROWSER_DEMO_SESSION;
-
-function labeledCard(label, value) {
- return h(
- "div",
- null,
- h("dt", null, label),
- h("dd", null, value),
- );
-}
-
-function timelineItem(update) {
- return h(
- "li",
- {
- key: `${update.timestamp}-${update.state}`,
- className: "timeline-item",
- },
- h("div", { className: "timeline-marker" }, update.state.slice(0, 1).toUpperCase()),
- h(
- "div",
- { className: "timeline-body" },
- h(
- "div",
- { className: "timeline-topline" },
- h("strong", null, update.title),
- h("span", null, update.timestamp),
- ),
- h("p", null, update.detail),
- ),
- );
-}
-
-function liveTraceSection(trace, terminalResult) {
- const summary = DemoClient.traceSummary(trace, terminalResult);
-
- if (!summary) {
- return h(
- "div",
- { className: "trace-placeholder" },
- "Terminal trace is withheld until the ordered state stream reaches completion.",
- );
- }
-
- return [
- h(
- "div",
- { className: "trace-block", key: "selection" },
- h("h3", null, "Selection"),
- h(
- "dl",
- { className: "trace-list" },
- labeledCard("Capability", summary.selection.capability),
- labeledCard("Version", summary.selection.version),
- labeledCard(
- "Placement",
- `${summary.selection.placementTarget} · ${summary.selection.placementReason}`,
- ),
- ),
- ),
- h(
- "div",
- { className: "trace-block", key: "events" },
- h("h3", null, "Emitted Events"),
- h(
- "ul",
- { className: "event-list" },
- summary.emittedEvents.map((eventId) => h("li", { key: eventId }, eventId)),
- ),
- ),
- h(
- "div",
- { className: "trace-block", key: "output" },
- h("h3", null, "Output"),
- h(
- "dl",
- { className: "trace-list" },
- labeledCard("Plan", summary.output.planId),
- labeledCard("Route", summary.output.route),
- labeledCard("Weather", summary.output.weatherSummary),
- labeledCard("Team Status", summary.output.teamStatus),
- labeledCard("Next Action", summary.output.nextAction),
- ),
- ),
- ];
-}
-
-function DemoApp() {
- const [sessionState, setSessionState] = useState(() => DemoClient.createLiveDemoState());
- const [error, setError] = useState("");
-
- async function handleSubmitRequest() {
- if (sessionState.phase === "streaming") {
- return;
- }
-
- setError("");
- setSessionState(DemoClient.createLiveDemoState());
-
- try {
- await DemoClient.runLiveBrowserSubscription({
- onMessage: (message, created) => {
- setSessionState((current) => DemoClient.applyBrowserSubscriptionMessage(current, message, created));
- },
- });
- } catch (reason) {
- const message = String(reason);
- setError(message);
- setSessionState((current) => ({
- ...current,
- phase: "error",
- statusLabel: "error",
- streamBanner: message,
- error: message,
- }));
- }
- }
-
- const statusLabel = sessionState.statusLabel;
- const hasTerminalTrace = sessionState.phase === "completed" && sessionState.liveTrace;
- const isStreaming = sessionState.phase === "streaming";
- const visibleUpdates = sessionState.stateUpdates;
-
- if (error) {
- return h(
- "main",
- { className: "page" },
- h(
- "section",
- { className: "hero" },
- h(
- "div",
- { className: "hero-copy" },
- h("p", { className: "eyebrow" }, "Traverse Browser Runtime"),
- h("h1", null, "Live adapter connection failed."),
- h("p", { className: "lede" }, error),
- h(
- "p",
- { className: "lede" },
- "Run the local browser adapter proxy again, or use the documented fixture preview fallback.",
- ),
- ),
- ),
- );
- }
-
- return h(
- "main",
- { className: "page" },
- h(
- "section",
- { className: "hero" },
- h(
- "div",
- { className: "hero-copy" },
- h("p", { className: "eyebrow" }, "Traverse Browser Runtime"),
- h("h1", null, APPROVED_SESSION.title),
- h("p", { className: "lede" }, APPROVED_SESSION.summary),
- h(
- "dl",
- { className: "request-meta" },
- labeledCard("Goal", APPROVED_SESSION.request.goal),
- labeledCard("Target", APPROVED_SESSION.request.requested_target),
- labeledCard("Trace", APPROVED_SESSION.trace_id),
- labeledCard("Request", APPROVED_SESSION.request_id),
- ),
- ),
- h("div", { className: "status-pill" }, statusLabel),
- ),
- h(
- "section",
- { className: "grid" },
- h(
- "article",
- { className: "panel" },
- h(
- "div",
- { className: "panel-header" },
- h("h2", null, "Request And Stream"),
- h(
- "p",
- null,
- "Submit the approved expedition request, then watch the governed browser subscription stream unfold in order.",
- ),
- ),
- h(
- "div",
- { className: "request-card" },
- h(
- "div",
- null,
- h("p", { className: "request-label" }, "Approved request"),
- h("h3", null, APPROVED_SESSION.title),
- h("p", null, APPROVED_SESSION.request.goal),
- ),
- h(
- "button",
- {
- className: "request-button",
- type: "button",
- onClick: handleSubmitRequest,
- disabled: isStreaming,
- },
- isStreaming ? "Streaming approved request..." : "Submit approved request",
- ),
- ),
- h("div", { className: "stream-banner" }, sessionState.streamBanner),
- h("ol", { className: "timeline" }, visibleUpdates.map(timelineItem)),
- ),
- h(
- "article",
- { className: "panel trace-panel" },
- h(
- "div",
- { className: "panel-header" },
- h("h2", null, "Terminal Trace"),
- h("p", null, "The final governed selection, placement, and output snapshot."),
- ),
- hasTerminalTrace
- ? liveTraceSection(sessionState.liveTrace, sessionState.liveResult)
- : h(
- "div",
- { className: "trace-placeholder" },
- "Terminal trace is withheld until the ordered state stream reaches completion.",
- ),
- ),
- ),
- );
-}
-
-ReactDOM.createRoot(document.getElementById("root")).render(h(DemoApp));
diff --git a/apps/react-demo/src/styles.css b/apps/react-demo/src/styles.css
deleted file mode 100644
index c1304732..00000000
--- a/apps/react-demo/src/styles.css
+++ /dev/null
@@ -1,296 +0,0 @@
-:root {
- color-scheme: light;
- --bg: #f7f0e6;
- --paper: rgba(255, 250, 243, 0.82);
- --ink: #1f1a17;
- --muted: #6d625a;
- --accent: #145b73;
- --accent-soft: #d8eef4;
- --line: rgba(31, 26, 23, 0.12);
- --shadow: 0 30px 60px rgba(39, 28, 20, 0.12);
-}
-
-* {
- box-sizing: border-box;
-}
-
-body {
- margin: 0;
- min-height: 100vh;
- font-family: "Avenir Next", "Segoe UI", sans-serif;
- color: var(--ink);
- background:
- radial-gradient(circle at top left, rgba(20, 91, 115, 0.18), transparent 30%),
- radial-gradient(circle at top right, rgba(193, 119, 61, 0.14), transparent 28%),
- linear-gradient(180deg, #fffaf4 0%, var(--bg) 100%);
-}
-
-.page {
- max-width: 1180px;
- margin: 0 auto;
- padding: 48px 20px 64px;
-}
-
-.hero {
- display: flex;
- justify-content: space-between;
- gap: 24px;
- align-items: flex-start;
- margin-bottom: 28px;
- padding: 32px;
- border: 1px solid var(--line);
- border-radius: 28px;
- background: var(--paper);
- backdrop-filter: blur(14px);
- box-shadow: var(--shadow);
-}
-
-.hero h1 {
- margin: 8px 0 12px;
- font-size: clamp(2.4rem, 6vw, 4.8rem);
- line-height: 0.98;
- letter-spacing: -0.05em;
-}
-
-.eyebrow {
- margin: 0;
- font-size: 0.82rem;
- letter-spacing: 0.2em;
- text-transform: uppercase;
- color: var(--accent);
- font-weight: 700;
-}
-
-.lede {
- max-width: 60ch;
- margin: 0;
- color: var(--muted);
- font-size: 1.05rem;
- line-height: 1.55;
-}
-
-.status-pill {
- flex-shrink: 0;
- padding: 10px 14px;
- border-radius: 999px;
- background: var(--accent-soft);
- color: var(--accent);
- text-transform: uppercase;
- letter-spacing: 0.12em;
- font-size: 0.76rem;
- font-weight: 700;
-}
-
-.request-meta,
-.trace-list {
- display: grid;
- gap: 12px;
- margin: 20px 0 0;
-}
-
-.request-meta {
- grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
-}
-
-.request-meta div,
-.trace-list div {
- padding: 12px 14px;
- border-radius: 18px;
- background: rgba(255, 255, 255, 0.72);
- border: 1px solid var(--line);
-}
-
-dt {
- margin-bottom: 6px;
- color: var(--muted);
- font-size: 0.8rem;
- text-transform: uppercase;
- letter-spacing: 0.08em;
-}
-
-dd {
- margin: 0;
- line-height: 1.45;
-}
-
-.grid {
- display: grid;
- grid-template-columns: 1.2fr 0.8fr;
- gap: 22px;
-}
-
-.panel {
- padding: 24px;
- border-radius: 28px;
- border: 1px solid var(--line);
- background: rgba(255, 253, 249, 0.9);
- box-shadow: var(--shadow);
-}
-
-.panel-header h2,
-.trace-block h3 {
- margin: 0 0 8px;
-}
-
-.panel-header p {
- margin: 0 0 18px;
- color: var(--muted);
-}
-
-.request-card,
-.stream-banner,
-.trace-placeholder {
- border: 1px solid var(--line);
- background: white;
-}
-
-.request-card {
- display: flex;
- justify-content: space-between;
- gap: 18px;
- align-items: center;
- margin-bottom: 18px;
- padding: 18px 20px;
- border-radius: 22px;
-}
-
-.request-label {
- margin: 0 0 8px;
- color: var(--accent);
- font-size: 0.8rem;
- letter-spacing: 0.12em;
- text-transform: uppercase;
- font-weight: 700;
-}
-
-.request-card h3,
-.request-card p {
- margin: 0;
-}
-
-.request-card p:last-child {
- margin-top: 8px;
- color: var(--muted);
- line-height: 1.45;
-}
-
-.request-button {
- border: 0;
- border-radius: 999px;
- padding: 14px 20px;
- background: var(--accent);
- color: white;
- font: inherit;
- font-weight: 700;
- cursor: pointer;
- box-shadow: 0 14px 28px rgba(20, 91, 115, 0.18);
-}
-
-.request-button:disabled {
- cursor: wait;
- opacity: 0.72;
-}
-
-.stream-banner,
-.trace-placeholder {
- margin-bottom: 18px;
- padding: 14px 16px;
- border-radius: 18px;
- color: var(--muted);
- line-height: 1.45;
-}
-
-.timeline {
- list-style: none;
- padding: 0;
- margin: 0;
- display: grid;
- gap: 14px;
-}
-
-.timeline-item {
- display: grid;
- grid-template-columns: 44px 1fr;
- gap: 14px;
- align-items: flex-start;
-}
-
-.timeline-marker {
- display: grid;
- place-items: center;
- width: 44px;
- height: 44px;
- border-radius: 14px;
- background: var(--accent);
- color: white;
- font-weight: 700;
-}
-
-.timeline-body {
- padding: 14px 16px;
- border-radius: 18px;
- background: white;
- border: 1px solid var(--line);
-}
-
-.timeline-topline {
- display: flex;
- justify-content: space-between;
- gap: 12px;
- align-items: baseline;
-}
-
-.timeline-topline span {
- color: var(--muted);
- font-size: 0.84rem;
-}
-
-.timeline-body p {
- margin: 10px 0 0;
- color: var(--muted);
- line-height: 1.45;
-}
-
-.trace-panel {
- display: grid;
- gap: 18px;
-}
-
-.trace-block {
- padding: 16px 18px;
- border-radius: 20px;
- background: white;
- border: 1px solid var(--line);
-}
-
-.event-list {
- margin: 0;
- padding-left: 18px;
- display: grid;
- gap: 8px;
-}
-
-.event-list li {
- color: var(--muted);
- line-height: 1.45;
-}
-
-@media (max-width: 900px) {
- .hero,
- .grid {
- grid-template-columns: 1fr;
- }
-
- .hero {
- flex-direction: column;
- }
-
- .timeline-topline {
- flex-direction: column;
- }
-
- .request-card {
- flex-direction: column;
- align-items: flex-start;
- }
-}
diff --git a/apps/youaskm3-starter-kit/README.md b/apps/youaskm3-starter-kit/README.md
deleted file mode 100644
index 1c234cae..00000000
--- a/apps/youaskm3-starter-kit/README.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# youaskm3 Traverse Starter Kit
-
-This starter kit is a reference integration package for browser-hosted downstream apps that want to adopt Traverse without repo archaeology.
-
-It is intentionally small:
-
-- it points to the versioned Traverse consumer bundle
-- it points to the browser-targeted consumer package
-- it points to the MCP consumption and compatibility validation paths
-- it leaves downstream UI and product behavior to the consuming app
-
-## What It Is For
-
-Use this starter kit as the first place a downstream app developer looks when wiring Traverse into a browser-hosted app such as `youaskm3`.
-
-It is not a replacement for the app-consumable docs.
-
-## Included References
-
-- [docs/app-consumable-consumer-bundle.md](/Users/piovese/Documents/cogolo/docs/app-consumable-consumer-bundle.md)
-- [docs/youaskm3-starter-kit.md](/Users/piovese/Documents/cogolo/docs/youaskm3-starter-kit.md)
-- [docs/youaskm3-integration-validation.md](/Users/piovese/Documents/cogolo/docs/youaskm3-integration-validation.md)
-- [docs/youaskm3-compatibility-conformance-suite.md](/Users/piovese/Documents/cogolo/docs/youaskm3-compatibility-conformance-suite.md)
-
-## Supported Assumptions
-
-- The consuming app is browser-hosted.
-- The consuming app uses the published Traverse consumer bundle.
-- The consuming app depends on the browser-targeted consumer package rather than Traverse internals.
-- The consuming app validates the browser-hosted and MCP-facing paths using the documented repo-local commands.
-
diff --git a/apps/youaskm3-starter-kit/package.json b/apps/youaskm3-starter-kit/package.json
deleted file mode 100644
index 5fe95f5d..00000000
--- a/apps/youaskm3-starter-kit/package.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "name": "youaskm3-traverse-starter-kit",
- "version": "0.1.0",
- "private": true,
- "description": "Reference starter kit for browser-hosted downstream apps adopting Traverse."
-}
-
diff --git a/docs/app-consumable-acceptance.md b/docs/app-consumable-acceptance.md
index 9b3b8101..1adeb6b5 100644
--- a/docs/app-consumable-acceptance.md
+++ b/docs/app-consumable-acceptance.md
@@ -41,5 +41,5 @@ The acceptance path fails deterministically when:
## Related Docs
- [quickstart.md](../quickstart.md)
-- [apps/react-demo/README.md](../apps/react-demo/README.md)
+- [https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/README.md)
- [docs/expedition-example-smoke.md](expedition-example-smoke.md)
diff --git a/docs/app-consumable-consumer-bundle.md b/docs/app-consumable-consumer-bundle.md
index 09e52423..044405fa 100644
--- a/docs/app-consumable-consumer-bundle.md
+++ b/docs/app-consumable-consumer-bundle.md
@@ -17,7 +17,7 @@ It is a versioned compatibility record, not a new runtime behavior layer.
For the first app-consumable release, the supported bundle points to:
-- the browser-targeted consumer package at [apps/browser-consumer/README.md](../apps/browser-consumer/README.md)
+- the browser-targeted consumer package at [https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md)
- the dedicated MCP stdio server package at [docs/mcp-stdio-server.md](mcp-stdio-server.md)
- the live browser adapter path described in [quickstart.md](../quickstart.md)
- the downstream integration and validation docs for `youaskm3`
diff --git a/docs/app-consumable-entry-path.md b/docs/app-consumable-entry-path.md
index bcaf645d..66f0b7bd 100644
--- a/docs/app-consumable-entry-path.md
+++ b/docs/app-consumable-entry-path.md
@@ -19,7 +19,7 @@ This is the canonical documentation path for humans and coding agents working on
- [docs/youaskm3-published-artifact-validation.md](youaskm3-published-artifact-validation.md)
- [docs/youaskm3-compatibility-conformance-suite.md](youaskm3-compatibility-conformance-suite.md)
- [docs/youaskm3-real-shell-validation.md](youaskm3-real-shell-validation.md)
- - [apps/browser-consumer/README.md](../apps/browser-consumer/README.md)
+ - [https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md)
## Canonical Rule
diff --git a/docs/app-consumable-release-checklist.md b/docs/app-consumable-release-checklist.md
index ed425348..aac0abf0 100644
--- a/docs/app-consumable-release-checklist.md
+++ b/docs/app-consumable-release-checklist.md
@@ -21,7 +21,7 @@ Traverse MUST NOT claim `app-consumable v0.1` unless all of the following are sa
- [ ] The governed browser consumer path exists and is documented in [quickstart.md](../quickstart.md).
- [ ] The live local browser adapter path passes [scripts/ci/react_demo_live_adapter_smoke.sh](../scripts/ci/react_demo_live_adapter_smoke.sh).
-- [ ] The browser demo path is documented as a real live adapter consumer in [apps/react-demo/README.md](../apps/react-demo/README.md).
+- [ ] The browser demo path is documented as a real live adapter consumer in [https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/README.md).
- [ ] The first versioned Traverse consumer bundle is documented in [docs/app-consumable-consumer-bundle.md](app-consumable-consumer-bundle.md).
- [ ] The downstream MCP consumption path exists and passes [scripts/ci/mcp_consumption_validation.sh](../scripts/ci/mcp_consumption_validation.sh).
- [ ] The first real `youaskm3` integration path exists and passes [scripts/ci/youaskm3_integration_validation.sh](../scripts/ci/youaskm3_integration_validation.sh).
diff --git a/docs/browser-adapter.md b/docs/browser-adapter.md
index b3d05df6..605a8bee 100644
--- a/docs/browser-adapter.md
+++ b/docs/browser-adapter.md
@@ -19,7 +19,7 @@ Relevant docs:
- [quickstart.md](../quickstart.md)
- [docs/youaskm3-canonical-app-http-path.md](youaskm3-canonical-app-http-path.md)
- [docs/app-consumable-entry-path.md](app-consumable-entry-path.md)
-- [apps/browser-consumer/README.md](../apps/browser-consumer/README.md)
+- [https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md)
- [docs/adapter-boundaries.md](adapter-boundaries.md)
## What The Browser Adapter Is Not
diff --git a/docs/decision-log.md b/docs/decision-log.md
index b7e2b935..75d031ae 100644
--- a/docs/decision-log.md
+++ b/docs/decision-log.md
@@ -486,11 +486,11 @@ Those artifacts live under `examples/`, never `apps/`.
| Current path | Owner | Destination |
| --- | --- | --- |
-| `apps/android-demo/` | Reference Apps | `reference-apps/android-demo/` |
-| `apps/browser-consumer/` | Reference Apps | `reference-apps/browser-consumer/` |
-| `apps/macos-demo/` | Reference Apps | `reference-apps/macos-demo/` |
-| `apps/react-demo/` | Reference Apps | `reference-apps/react-demo/` |
-| `apps/youaskm3-starter-kit/` | Reference Apps | `reference-apps/youaskm3-starter-kit/` |
+| `https://github.com/traverse-framework/reference-apps/tree/main/apps/android-demo/` | Reference Apps | `reference-https://github.com/traverse-framework/reference-apps/tree/main/apps/android-demo/` |
+| `https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/` | Reference Apps | `reference-https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/` |
+| `https://github.com/traverse-framework/reference-apps/tree/main/apps/macos-demo/` | Reference Apps | `reference-https://github.com/traverse-framework/reference-apps/tree/main/apps/macos-demo/` |
+| `https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/` | Reference Apps | `reference-https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/` |
+| `https://github.com/traverse-framework/reference-apps/tree/main/apps/youaskm3-starter-kit/` | Reference Apps | `reference-https://github.com/traverse-framework/reference-apps/tree/main/apps/youaskm3-starter-kit/` |
| `apps/demo-fixtures/expedition-runtime-session.json` | Traverse fixture | `examples/fixtures/expedition-runtime-session.json` |
| `apps/meeting-notes/` | Traverse fixture | `examples/applications/meeting-notes/` |
| `apps/traverse-starter/` | Traverse fixture | `examples/applications/traverse-starter/` |
diff --git a/docs/mcp-consumption-validation.md b/docs/mcp-consumption-validation.md
index d801db03..e3eaf980 100644
--- a/docs/mcp-consumption-validation.md
+++ b/docs/mcp-consumption-validation.md
@@ -16,7 +16,7 @@ This validation path is governed by:
- `specs/020-downstream-integration-validation/spec.md`
- `specs/021-app-facing-operational-constraints/spec.md`
-For the first real downstream browser + MCP integration path, also see [docs/youaskm3-integration-validation.md](youaskm3-integration-validation.md), [docs/youaskm3-compatibility-conformance-suite.md](youaskm3-compatibility-conformance-suite.md), and the browser-targeted consumer package at [apps/browser-consumer/README.md](../apps/browser-consumer/README.md).
+For the first real downstream browser + MCP integration path, also see [docs/youaskm3-integration-validation.md](youaskm3-integration-validation.md), [docs/youaskm3-compatibility-conformance-suite.md](youaskm3-compatibility-conformance-suite.md), and the browser-targeted consumer package at [https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md).
For the real-agent exercise against the same MCP substrate, also see [docs/mcp-real-agent-exercise.md](mcp-real-agent-exercise.md).
diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md
index b2fc3199..f1e5f627 100644
--- a/docs/troubleshooting.md
+++ b/docs/troubleshooting.md
@@ -228,7 +228,7 @@ cargo run -p traverse-cli -- browser-adapter serve --bind 127.0.0.1:4174
2. Confirm the React demo command still works:
```bash
-node apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173
+node https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173
```
3. Re-read:
diff --git a/docs/what-can-i-build.md b/docs/what-can-i-build.md
index 2b913f0d..5ec680eb 100644
--- a/docs/what-can-i-build.md
+++ b/docs/what-can-i-build.md
@@ -21,7 +21,7 @@ Relevant docs:
- [quickstart.md](../quickstart.md)
- [docs/app-consumable-entry-path.md](app-consumable-entry-path.md)
-- [apps/browser-consumer/README.md](../apps/browser-consumer/README.md)
+- [https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md)
- [docs/youaskm3-integration-validation.md](youaskm3-integration-validation.md)
Good fit:
diff --git a/docs/youaskm3-integration-validation.md b/docs/youaskm3-integration-validation.md
index 6dabd76c..86efbaaf 100644
--- a/docs/youaskm3-integration-validation.md
+++ b/docs/youaskm3-integration-validation.md
@@ -59,7 +59,7 @@ Use one deterministic repo-local validation flow to prove that `youaskm3` can co
Run the browser and MCP validation smoke checks in order:
```bash
-bash scripts/ci/react_demo_live_adapter_smoke.sh
+bash Reference Apps smoke workflow
bash scripts/ci/mcp_consumption_validation.sh
```
@@ -132,7 +132,7 @@ The path is expected to fail deterministically when:
## Validation
-- `bash scripts/ci/react_demo_live_adapter_smoke.sh`
+- `bash Reference Apps smoke workflow`
- `bash scripts/ci/mcp_consumption_validation.sh`
- `bash scripts/ci/mcp_real_agent_exercise_smoke.sh`
- `bash scripts/ci/downstream_public_app_registration_smoke.sh`
diff --git a/docs/youaskm3-starter-kit.md b/docs/youaskm3-starter-kit.md
index e6adda36..703e6153 100644
--- a/docs/youaskm3-starter-kit.md
+++ b/docs/youaskm3-starter-kit.md
@@ -2,7 +2,7 @@
This document is the first integration guide for browser-hosted downstream apps such as `youaskm3`.
-It pairs with the reference starter kit at [apps/youaskm3-starter-kit/README.md](../apps/youaskm3-starter-kit/README.md).
+It pairs with the reference starter kit at [https://github.com/traverse-framework/reference-apps/tree/main/apps/youaskm3-starter-kit/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/youaskm3-starter-kit/README.md).
This youaskm3 starter kit and integration guide is the canonical browser-hosted adoption path for the downstream app.
@@ -15,7 +15,7 @@ The goal is to give a downstream app team one clear adoption path for Traverse w
Downstream apps should adopt the versioned Traverse consumer bundle and the browser-targeted consumer package documented in:
- [docs/app-consumable-consumer-bundle.md](app-consumable-consumer-bundle.md)
-- [apps/browser-consumer/README.md](../apps/browser-consumer/README.md)
+- [https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md](../https://github.com/traverse-framework/reference-apps/tree/main/apps/browser-consumer/README.md)
## Setup
diff --git a/packages/web/TraverseEmbedder/examples/react-integration/README.md b/packages/web/TraverseEmbedder/examples/react-integration/README.md
index ea0b330e..1fcea572 100644
--- a/packages/web/TraverseEmbedder/examples/react-integration/README.md
+++ b/packages/web/TraverseEmbedder/examples/react-integration/README.md
@@ -11,7 +11,7 @@ a sidecar").
1. `server.mjs` is a plain static file server (not a Traverse sidecar) that
serves three things over HTTP: the built `traverse-embedder-web` package
(`/pkg/`), the existing React UMD vendor bundles already checked in under
- `apps/react-demo/vendor` (`/vendor/`), and the repository root itself
+ `packages/web/TraverseEmbedder/examples/react-integration/vendor` (`/vendor/`), and the repository root itself
(`/repo/`) so the browser can `fetch` the real
`examples/applications/traverse-starter/app.manifest.json` bundle and every file it
references (component manifest, workflow definition, compiled WASM
diff --git a/packages/web/TraverseEmbedder/examples/react-integration/server.mjs b/packages/web/TraverseEmbedder/examples/react-integration/server.mjs
index d501f578..f6bd92dd 100644
--- a/packages/web/TraverseEmbedder/examples/react-integration/server.mjs
+++ b/packages/web/TraverseEmbedder/examples/react-integration/server.mjs
@@ -14,7 +14,7 @@ import { fileURLToPath } from "node:url";
const exampleRoot = fileURLToPath(new URL(".", import.meta.url));
const repoRoot = fileURLToPath(new URL("../../../../../", import.meta.url));
const pkgDist = join(repoRoot, "packages/web/TraverseEmbedder/dist");
-const vendorRoot = join(repoRoot, "apps/react-demo/vendor");
+const vendorRoot = join(repoRoot, "packages/web/TraverseEmbedder/examples/react-integration/vendor");
const defaultPort = 4175;
const routes = [
diff --git a/apps/react-demo/vendor/react-dom.development.js b/packages/web/TraverseEmbedder/examples/react-integration/vendor/react-dom.development.js
similarity index 100%
rename from apps/react-demo/vendor/react-dom.development.js
rename to packages/web/TraverseEmbedder/examples/react-integration/vendor/react-dom.development.js
diff --git a/apps/react-demo/vendor/react.development.js b/packages/web/TraverseEmbedder/examples/react-integration/vendor/react.development.js
similarity index 100%
rename from apps/react-demo/vendor/react.development.js
rename to packages/web/TraverseEmbedder/examples/react-integration/vendor/react.development.js
diff --git a/quickstart.md b/quickstart.md
index 97af6abd..3278b34c 100644
--- a/quickstart.md
+++ b/quickstart.md
@@ -40,7 +40,7 @@ Keep this terminal open. The React demo proxies browser-subscription traffic thr
In a second terminal from the repository root:
```bash
-node apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173
+node https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173
```
Open:
@@ -74,7 +74,7 @@ The expected final consumer outcome is a completed expedition plan with the gove
- This is the first supported consumer path, not a production deployment guide.
- The browser app must proxy through the local browser adapter to use the live path.
-- The fallback static preview path in `apps/react-demo/README.md` is useful for offline inspection, but it is not the app-consumable v0.1 path.
+- The fallback static preview path in `https://github.com/traverse-framework/reference-apps/tree/main/apps/react-demo/README.md` is useful for offline inspection, but it is not the app-consumable v0.1 path.
- This quickstart does not redefine Traverse internals; it only documents the governed consumer flow that is already checked in.
## Validation
diff --git a/scripts/ci/android_demo_smoke.sh b/scripts/ci/android_demo_smoke.sh
deleted file mode 100644
index fd0440ee..00000000
--- a/scripts/ci/android_demo_smoke.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-repo_root="${TRAVERSE_REPO_ROOT:-$(pwd)}"
-
-required_files=(
- "apps/android-demo/README.md"
- "apps/android-demo/settings.gradle.kts"
- "apps/android-demo/build.gradle.kts"
- "apps/android-demo/app/build.gradle.kts"
- "apps/android-demo/app/src/main/AndroidManifest.xml"
- "apps/android-demo/app/src/main/java/com/traverse/demo/android/MainActivity.kt"
- "apps/android-demo/app/src/main/res/values/strings.xml"
- "apps/android-demo/app/src/main/assets/expedition-runtime-session.json"
-)
-
-for file in "${required_files[@]}"; do
- if [[ ! -f "${repo_root}/${file}" ]]; then
- echo "missing Android demo artifact: ${file}" >&2
- exit 1
- fi
-done
-
-grep -q 'setContent' "${repo_root}/apps/android-demo/app/src/main/java/com/traverse/demo/android/MainActivity.kt"
-grep -q 'Traverse Android Demo' "${repo_root}/apps/android-demo/app/src/main/res/values/strings.xml"
-grep -q '"status": "completed"' "${repo_root}/apps/android-demo/app/src/main/assets/expedition-runtime-session.json"
-
-echo "Android demo smoke passed"
diff --git a/scripts/ci/app_consumable_acceptance.sh b/scripts/ci/app_consumable_acceptance.sh
index 8f096906..b5924a8a 100644
--- a/scripts/ci/app_consumable_acceptance.sh
+++ b/scripts/ci/app_consumable_acceptance.sh
@@ -4,6 +4,6 @@ set -euo pipefail
# scripts/ci/app_consumable_acceptance.sh is the authoritative app-consumable acceptance entrypoint.
-bash scripts/ci/react_demo_live_adapter_smoke.sh
+echo "Reference app smoke lives in traverse-framework/reference-apps"
echo "App-consumable acceptance passed."
diff --git a/scripts/ci/app_ownership_boundary_smoke.sh b/scripts/ci/app_ownership_boundary_smoke.sh
index b344d872..b36c9979 100644
--- a/scripts/ci/app_ownership_boundary_smoke.sh
+++ b/scripts/ci/app_ownership_boundary_smoke.sh
@@ -4,6 +4,11 @@ set -euo pipefail
repo_root="${TRAVERSE_REPO_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
+if [[ -d "${repo_root}/apps" ]]; then
+ echo "Application source must live in traverse-framework/reference-apps, not apps/" >&2
+ exit 1
+fi
+
for forbidden_path in \
"apps/demo-fixtures" \
"apps/meeting-notes" \
@@ -28,18 +33,8 @@ for required_path in "${required_paths[@]}"; do
test -s "${repo_root}/${required_path}"
done
-for app_path in \
- "apps/android-demo/" \
- "apps/browser-consumer/" \
- "apps/macos-demo/" \
- "apps/react-demo/" \
- "apps/youaskm3-starter-kit/" \
- "apps/demo-fixtures/expedition-runtime-session.json" \
- "apps/meeting-notes/" \
- "apps/traverse-starter/"
-do
- grep -Fq "\`${app_path}\`" "${repo_root}/docs/decision-log.md"
-done
+grep -Fq "Decision 22: Keep Application Source Out of the Traverse Runtime Repository" \
+ "${repo_root}/docs/decision-log.md"
for app_id in traverse-starter meeting-notes; do
validate_output="$(
diff --git a/scripts/ci/browser_consumer_package_smoke.sh b/scripts/ci/browser_consumer_package_smoke.sh
deleted file mode 100644
index f3cd7a08..00000000
--- a/scripts/ci/browser_consumer_package_smoke.sh
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-repo_root="${TRAVERSE_REPO_ROOT:-$(pwd)}"
-tmpdir="$(mktemp -d)"
-adapter_log="${tmpdir}/browser-adapter.log"
-demo_log="${tmpdir}/react-demo.log"
-adapter_pid=""
-demo_pid=""
-
-cleanup() {
- if [[ -n "${demo_pid}" ]] && kill -0 "${demo_pid}" 2>/dev/null; then
- kill "${demo_pid}" 2>/dev/null || true
- wait "${demo_pid}" 2>/dev/null || true
- fi
- if [[ -n "${adapter_pid}" ]] && kill -0 "${adapter_pid}" 2>/dev/null; then
- kill "${adapter_pid}" 2>/dev/null || true
- wait "${adapter_pid}" 2>/dev/null || true
- fi
- rm -rf "${tmpdir}"
-}
-trap cleanup EXIT
-
-pushd "${repo_root}" >/dev/null
-
-cargo run -p traverse-cli -- browser-adapter serve --bind 127.0.0.1:4174 >"${adapter_log}" 2>&1 &
-adapter_pid=$!
-
-for _ in $(seq 1 200); do
- if grep -q "local browser adapter listening on " "${adapter_log}" 2>/dev/null; then
- break
- fi
- if ! kill -0 "${adapter_pid}" 2>/dev/null; then
- cat "${adapter_log}" >&2
- echo "browser adapter exited before it reported a listening address" >&2
- exit 1
- fi
- sleep 0.05
-done
-
-node apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173 >"${demo_log}" 2>&1 &
-demo_pid=$!
-
-for _ in $(seq 1 200); do
- if grep -q "Traverse React demo serving on http://127.0.0.1:4173" "${demo_log}" 2>/dev/null; then
- break
- fi
- if ! kill -0 "${demo_pid}" 2>/dev/null; then
- cat "${demo_log}" >&2
- echo "react demo server exited before it reported a listening address" >&2
- exit 1
- fi
- sleep 0.05
-done
-
-node <<'NODE'
-const assert = require('node:assert/strict');
-const consumer = require('./apps/browser-consumer');
-
-(async () => {
- assert.equal(
- consumer.APPROVED_BROWSER_CONSUMER_SESSION.title,
- 'Traverse Browser Consumer',
- );
-
- const createAndStream = await consumer.runBrowserConsumerSubscription({
- baseUrl: 'http://127.0.0.1:4173',
- });
-
- assert.ok(createAndStream.created.subscription_id);
- assert.ok(createAndStream.messages.length > 0);
- assert.equal(createAndStream.messages[0].variant, 'Lifecycle');
- assert.equal(
- createAndStream.messages[createAndStream.messages.length - 1].variant,
- 'Lifecycle',
- );
- assert.ok(createAndStream.messages.some((message) => message.variant === 'State'));
- assert.ok(createAndStream.messages.some((message) => message.variant === 'TraceArtifact'));
- assert.ok(createAndStream.messages.some((message) => message.variant === 'StreamTerminal'));
-
- const terminalMessage = createAndStream.messages.find((message) => message.variant === 'StreamTerminal');
- assert.ok(terminalMessage);
- assert.equal(terminalMessage.payload.result.status, 'completed');
-
- const traceMessage = createAndStream.messages.find((message) => message.variant === 'TraceArtifact');
- assert.ok(traceMessage);
-
- const summary = consumer.browserConsumerTraceSummary(
- traceMessage.payload.trace,
- terminalMessage.payload.result,
- );
- assert.ok(summary);
- assert.equal(summary.selection.capability, 'expedition.planning.plan-expedition');
- assert.equal(summary.output.planId, 'plan-objective-skypilot');
-})().catch((error) => {
- console.error(error);
- process.exit(1);
-});
-NODE
-
-popd >/dev/null
diff --git a/scripts/ci/macos_demo_smoke.sh b/scripts/ci/macos_demo_smoke.sh
deleted file mode 100644
index 9b564423..00000000
--- a/scripts/ci/macos_demo_smoke.sh
+++ /dev/null
@@ -1,27 +0,0 @@
-#!/usr/bin/env bash
-set -euo pipefail
-
-repo_root="${TRAVERSE_REPO_ROOT:-$(pwd)}"
-
-required_files=(
- "examples/fixtures/expedition-runtime-session.json"
- "apps/macos-demo/Package.swift"
- "apps/macos-demo/README.md"
- "apps/macos-demo/Sources/TraverseMacOSDemoApp/TraverseMacOSDemoApp.swift"
- "apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoSession.swift"
- "apps/macos-demo/Sources/TraverseMacOSDemoApp/DemoContentView.swift"
-)
-
-for file in "${required_files[@]}"; do
- if [[ ! -f "${repo_root}/${file}" ]]; then
- echo "missing macOS demo artifact: ${file}" >&2
- exit 1
- fi
-done
-
-grep -q 'import SwiftUI' "${repo_root}/apps/macos-demo/Sources/TraverseMacOSDemoApp/TraverseMacOSDemoApp.swift"
-grep -q 'WindowGroup' "${repo_root}/apps/macos-demo/Sources/TraverseMacOSDemoApp/TraverseMacOSDemoApp.swift"
-grep -q '"status": "completed"' "${repo_root}/examples/fixtures/expedition-runtime-session.json"
-grep -q '"state_updates"' "${repo_root}/examples/fixtures/expedition-runtime-session.json"
-
-echo "macOS demo smoke passed"
diff --git a/scripts/ci/react_demo_live_adapter_smoke.sh b/scripts/ci/react_demo_live_adapter_smoke.sh
deleted file mode 100755
index a696cc0e..00000000
--- a/scripts/ci/react_demo_live_adapter_smoke.sh
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-# scripts/ci/react_demo_live_adapter_smoke.sh verifies the live browser adapter path end to end.
-
-repo_root="${TRAVERSE_REPO_ROOT:-$(pwd)}"
-tmpdir="$(mktemp -d)"
-adapter_log="${tmpdir}/browser-adapter.log"
-demo_log="${tmpdir}/react-demo.log"
-adapter_pid=""
-demo_pid=""
-
-cleanup() {
- if [[ -n "${demo_pid}" ]] && kill -0 "${demo_pid}" 2>/dev/null; then
- kill "${demo_pid}" 2>/dev/null || true
- wait "${demo_pid}" 2>/dev/null || true
- fi
- if [[ -n "${adapter_pid}" ]] && kill -0 "${adapter_pid}" 2>/dev/null; then
- kill "${adapter_pid}" 2>/dev/null || true
- wait "${adapter_pid}" 2>/dev/null || true
- fi
- rm -rf "${tmpdir}"
-}
-trap cleanup EXIT
-
-pushd "${repo_root}" >/dev/null
-
-cargo run -p traverse-cli -- browser-adapter serve --bind 127.0.0.1:4174 >"${adapter_log}" 2>&1 &
-adapter_pid=$!
-
-for _ in $(seq 1 200); do
- if grep -q "local browser adapter listening on " "${adapter_log}" 2>/dev/null; then
- break
- fi
- if ! kill -0 "${adapter_pid}" 2>/dev/null; then
- cat "${adapter_log}" >&2
- echo "browser adapter exited before it reported a listening address" >&2
- exit 1
- fi
- sleep 0.05
-done
-
-node apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173 >"${demo_log}" 2>&1 &
-demo_pid=$!
-
-for _ in $(seq 1 200); do
- if grep -q "Traverse React demo serving on http://127.0.0.1:4173" "${demo_log}" 2>/dev/null; then
- break
- fi
- if ! kill -0 "${demo_pid}" 2>/dev/null; then
- cat "${demo_log}" >&2
- echo "react demo server exited before it reported a listening address" >&2
- exit 1
- fi
- sleep 0.05
-done
-
-node <<'NODE'
-const assert = require('node:assert/strict');
-const client = require('./apps/react-demo/src/browser-adapter-client.js');
-
-(async () => {
- const root = await fetch('http://127.0.0.1:4173/');
- assert.equal(root.status, 200);
- const html = await root.text();
- assert.match(html, /Traverse React Demo/);
-
- const createAndStream = await client.runLiveBrowserSubscription({
- baseUrl: 'http://127.0.0.1:4173',
- });
-
- assert.ok(createAndStream.created.subscription_id);
- assert.ok(createAndStream.messages.length > 0);
- assert.equal(createAndStream.messages[0].variant, 'Lifecycle');
- assert.equal(
- createAndStream.messages[createAndStream.messages.length - 1].variant,
- 'Lifecycle',
- );
- assert.ok(createAndStream.messages.some((message) => message.variant === 'State'));
- assert.ok(createAndStream.messages.some((message) => message.variant === 'TraceArtifact'));
- assert.ok(createAndStream.messages.some((message) => message.variant === 'StreamTerminal'));
-
- const traceMessage = createAndStream.messages.find((message) => message.variant === 'TraceArtifact');
- assert.ok(traceMessage);
-
- const terminalMessage = createAndStream.messages.find((message) => message.variant === 'StreamTerminal');
- assert.ok(terminalMessage);
- assert.equal(terminalMessage.payload.result.status, 'completed');
- assert.equal(terminalMessage.payload.result.output.plan_id, 'plan-objective-skypilot');
-
- const trace = traceMessage.payload.trace;
- const summary = client.traceSummary(traceMessage.payload.trace, terminalMessage.payload.result);
- assert.ok(summary);
- assert.equal(summary.selection.capability, 'expedition.planning.plan-expedition');
- assert.equal(summary.output.planId, 'plan-objective-skypilot');
-
- const invalidResponse = await fetch('http://127.0.0.1:4173/local/browser-subscriptions', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify({
- subscription_request: {
- kind: 'browser_runtime_subscription_request',
- schema_version: '1.0.0',
- governing_spec: '013-browser-runtime-subscription',
- },
- }),
- });
- assert.equal(invalidResponse.status, 400);
- const invalidPayload = await invalidResponse.json();
- assert.equal(invalidPayload.kind, 'local_browser_subscription_setup_error');
- assert.equal(invalidPayload.code, 'invalid_request');
-
- const missingStream = await fetch('http://127.0.0.1:4173/local/browser-subscriptions/lbs_9999/stream', {
- headers: {
- Accept: 'text/event-stream',
- },
- });
- assert.equal(missingStream.status, 404);
- const missingPayload = await missingStream.json();
- assert.equal(missingPayload.kind, 'local_browser_subscription_stream_error');
- assert.equal(missingPayload.code, 'not_found');
-})().catch((error) => {
- console.error(error);
- process.exit(1);
-});
-NODE
-
-popd >/dev/null
diff --git a/scripts/ci/react_demo_smoke.sh b/scripts/ci/react_demo_smoke.sh
deleted file mode 100644
index fb502430..00000000
--- a/scripts/ci/react_demo_smoke.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-repo_root="${TRAVERSE_REPO_ROOT:-$(pwd)}"
-app_dir="$repo_root/apps/react-demo"
-
-test -f "${app_dir}/index.html"
-test -f "${app_dir}/public/expedition-runtime-session.json"
-test -f "${app_dir}/src/main.js"
-test -f "${app_dir}/src/styles.css"
-test -f "${app_dir}/vendor/react.development.js"
-test -f "${app_dir}/vendor/react-dom.development.js"
-
-grep -q "Traverse React Demo" "${app_dir}/index.html"
-grep -q '"status": "completed"' "${app_dir}/public/expedition-runtime-session.json"
-grep -q "Submit approved request" "${app_dir}/src/main.js"
-grep -q "react.development.js" "${app_dir}/index.html"
-grep -q "react-dom.development.js" "${app_dir}/index.html"
-node --check "${app_dir}/src/main.js"
-
-printf 'React demo smoke passed.\n'
diff --git a/scripts/ci/repository_checks.sh b/scripts/ci/repository_checks.sh
index eca5e48f..4aeb9e6c 100644
--- a/scripts/ci/repository_checks.sh
+++ b/scripts/ci/repository_checks.sh
@@ -47,10 +47,6 @@ required_files=(
"specs/023-downstream-publication-strategy/spec.md"
"specs/023-downstream-publication-strategy/data-model.md"
"specs/023-downstream-publication-strategy/checklists/requirements.md"
- "apps/browser-consumer/README.md"
- "apps/browser-consumer/package.json"
- "apps/youaskm3-starter-kit/README.md"
- "apps/youaskm3-starter-kit/package.json"
"docs/wasm-agent-team-readiness-example.md"
"docs/app-consumable-acceptance.md"
"docs/app-consumable-entry-path.md"
@@ -87,9 +83,6 @@ required_files=(
"docs/adr/README.md"
"docs/adr/0001-rust-wasm-foundation.md"
"scripts/ci/browser_adapter_smoke.sh"
- "apps/react-demo/server.mjs"
- "apps/react-demo/src/browser-adapter-client.js"
- "scripts/ci/react_demo_live_adapter_smoke.sh"
"scripts/ci/mcp_stdio_server_execution_report_smoke.sh"
"scripts/ci/youaskm3_compatibility_conformance.sh"
"scripts/ci/downstream_app_mvp_conformance.sh"
@@ -99,7 +92,6 @@ required_files=(
"scripts/ci/downstream_model_dependency_smoke.sh"
"scripts/ci/downstream_http_json_smoke.sh"
"scripts/ci/downstream_mcp_smoke.sh"
- "scripts/ci/browser_consumer_package_smoke.sh"
"scripts/ci/youaskm3_integration_validation.sh"
"scripts/ci/youaskm3_published_artifact_validation.sh"
"scripts/ci/youaskm3_real_shell_validation.sh"
@@ -258,7 +250,6 @@ grep -q "render_execution_report" docs/mcp-real-agent-exercise.md
bash scripts/ci/openapi_structural_validation.sh
bash scripts/ci/spec_context_check.sh
grep -q "scripts/smoke.sh" docs/youaskm3-real-shell-validation.md
-grep -q "apps/browser-consumer/README.md" docs/mcp-consumption-validation.md
grep -q "docs/app-consumable-consumer-bundle.md" README.md
grep -q "docs/app-consumable-package-release-pointer.md" README.md
grep -q "docs/packaged-traverse-mcp-server-artifact.md" README.md
@@ -273,7 +264,6 @@ grep -q "docs/youaskm3-published-artifact-validation.md" docs/app-consumable-rel
grep -q "versioned Traverse consumer bundle" docs/app-consumable-consumer-bundle.md
grep -q "supported version selection" docs/app-consumable-consumer-bundle.md
grep -q "installation steps" docs/app-consumable-consumer-bundle.md
-grep -q "apps/browser-consumer/README.md" docs/app-consumable-consumer-bundle.md
grep -q "docs/mcp-stdio-server.md" docs/app-consumable-consumer-bundle.md
grep -q "docs/packaged-traverse-runtime-artifact.md" docs/app-consumable-consumer-bundle.md
grep -q "bash scripts/ci/app_consumable_release_prep.sh" docs/app-consumable-consumer-bundle.md
@@ -350,24 +340,12 @@ grep -q "specs/013-browser-runtime-subscription/spec.md" docs/adapter-boundaries
grep -q "specs/014-mcp-surface/spec.md" docs/adapter-boundaries.md
grep -q "mandatory sidecar topology" docs/adapter-boundaries.md
grep -q "optional adapter choices" docs/adapter-boundaries.md
-grep -q "browser-adapter serve" apps/react-demo/README.md
-grep -q "react_demo_live_adapter_smoke.sh" apps/react-demo/README.md
-grep -q "same-origin local proxy" apps/react-demo/README.md
-grep -q "app-consumable acceptance" apps/react-demo/README.md
-grep -q "Run the local browser adapter proxy again" apps/react-demo/README.md
grep -q "browser-targeted consumer package" docs/app-consumable-consumer-bundle.md
grep -q "consumer bundle" docs/app-consumable-consumer-bundle.md
grep -q "docs/app-consumable-package-release-pointer.md" docs/app-consumable-consumer-bundle.md
grep -q "youaskm3 integration validation" README.md
-grep -q "Traverse React demo serving on" apps/react-demo/server.mjs
-grep -q "runLiveBrowserSubscription" apps/react-demo/src/browser-adapter-client.js
-grep -q "applyBrowserSubscriptionMessage" apps/react-demo/src/browser-adapter-client.js
-grep -q "App" apps/react-demo/src/main.js
-grep -q "react_demo_live_adapter_smoke.sh" scripts/ci/react_demo_live_adapter_smoke.sh
grep -q "## Prerequisites" quickstart.md
grep -q "browser-adapter serve --bind 127.0.0.1:4174" quickstart.md
-grep -q "node apps/react-demo/server.mjs --adapter http://127.0.0.1:4174 --port 4173" quickstart.md
-grep -q "apps/browser-consumer/README.md" docs/app-consumable-entry-path.md
grep -q "git checkout v0.3.0" docs/v0.3.0-public-surface-compatibility.md
grep -q "docs/youaskm3-canonical-app-http-path.md" docs/v0.3.0-public-surface-compatibility.md
grep -q "docs/youaskm3-canonical-mcp-client-path.md" docs/v0.3.0-public-surface-compatibility.md
@@ -459,11 +437,6 @@ grep -q "POST /v1/workspaces/{workspace_id}/capabilities" docs/youaskm3-canonica
grep -q "POST /v1/workspaces/{workspace_id}/execute" docs/youaskm3-canonical-app-http-path.md
grep -q "GET /v1/workspaces/{workspace_id}/traces/{execution_id}" docs/youaskm3-canonical-app-http-path.md
grep -q "bash scripts/ci/app_consumable_acceptance.sh" docs/youaskm3-canonical-app-http-path.md
-grep -q "browser-targeted consumer package" apps/browser-consumer/README.md
-grep -q "browser_consumer_package_smoke.sh" apps/browser-consumer/README.md
-grep -q "browser-hosted app" apps/browser-consumer/README.md
-grep -q "bash scripts/ci/react_demo_live_adapter_smoke.sh" quickstart.md
-grep -q "bash scripts/ci/react_demo_smoke.sh" quickstart.md
grep -q "## Known Limitations" quickstart.md
grep -q "bash scripts/ci/youaskm3_integration_validation.sh" docs/youaskm3-integration-validation.md
grep -q "cargo run -p traverse-mcp -- stdio" docs/mcp-stdio-server.md
diff --git a/scripts/ci/youaskm3_integration_validation.sh b/scripts/ci/youaskm3_integration_validation.sh
index e20f38f3..8338b9d6 100755
--- a/scripts/ci/youaskm3_integration_validation.sh
+++ b/scripts/ci/youaskm3_integration_validation.sh
@@ -16,14 +16,14 @@ for file in "${required_files[@]}"; do
done
grep -q "youaskm3" docs/youaskm3-integration-validation.md
-grep -q "bash scripts/ci/react_demo_live_adapter_smoke.sh" docs/youaskm3-integration-validation.md
+grep -q "echo "Reference app smoke lives in traverse-framework/reference-apps"" docs/youaskm3-integration-validation.md
grep -q "bash scripts/ci/mcp_consumption_validation.sh" docs/youaskm3-integration-validation.md
grep -q "bash scripts/ci/youaskm3_integration_validation.sh" docs/youaskm3-integration-validation.md
grep -q "quickstart.md" docs/youaskm3-integration-validation.md
grep -q "consumer_name: youaskm3" docs/mcp-consumption-validation.md
grep -q "validated_flow_id: youaskm3_mcp_validation" docs/mcp-consumption-validation.md
-bash scripts/ci/react_demo_live_adapter_smoke.sh
+echo "Reference app smoke lives in traverse-framework/reference-apps"
bash scripts/ci/mcp_consumption_validation.sh
if [[ -n "${YOUASKM3_REPO_ROOT:-}" ]]; then
diff --git a/scripts/ci/youaskm3_starter_kit_smoke.sh b/scripts/ci/youaskm3_starter_kit_smoke.sh
deleted file mode 100755
index 05891ef9..00000000
--- a/scripts/ci/youaskm3_starter_kit_smoke.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env bash
-
-set -euo pipefail
-
-repo_root=$(git rev-parse --show-toplevel)
-
-test -s "${repo_root}/apps/youaskm3-starter-kit/README.md"
-test -s "${repo_root}/apps/youaskm3-starter-kit/package.json"
-test -s "${repo_root}/docs/youaskm3-starter-kit.md"
-grep -q "youaskm3 Traverse Starter Kit" "${repo_root}/apps/youaskm3-starter-kit/README.md"
-grep -q "versioned Traverse consumer bundle" "${repo_root}/apps/youaskm3-starter-kit/README.md"
-grep -q "browser-targeted consumer package" "${repo_root}/apps/youaskm3-starter-kit/README.md"
-grep -q "youaskm3 Starter Kit and Integration Guide" "${repo_root}/docs/youaskm3-starter-kit.md"
-grep -q "starter kit and integration guide" "${repo_root}/docs/youaskm3-starter-kit.md"
-grep -q "bash scripts/ci/youaskm3_integration_validation.sh" "${repo_root}/docs/youaskm3-starter-kit.md"
-
-echo "youaskm3 starter kit smoke passed."
diff --git a/scripts/ci/zero_to_hero_acceptance.sh b/scripts/ci/zero_to_hero_acceptance.sh
index 4060846f..63d27e87 100755
--- a/scripts/ci/zero_to_hero_acceptance.sh
+++ b/scripts/ci/zero_to_hero_acceptance.sh
@@ -11,7 +11,7 @@ echo "Running local hello-world CLI path..."
bash scripts/ci/hello_world_example_smoke.sh
echo "Running browser host app-consumable path..."
-bash scripts/ci/react_demo_live_adapter_smoke.sh
+echo "Reference app smoke lives in traverse-framework/reference-apps"
echo "Zero-to-hero acceptance passed."