Skip to content

feat(demo): chapter-1 vertical + bridge swap (Pillar-1 slice 1.2b)#150

Merged
Luis85 merged 6 commits into
developfrom
feat/tour-chapter-1-2b
Apr 26, 2026
Merged

feat(demo): chapter-1 vertical + bridge swap (Pillar-1 slice 1.2b)#150
Luis85 merged 6 commits into
developfrom
feat/tour-chapter-1-2b

Conversation

@Luis85
Copy link
Copy Markdown
Owner

@Luis85 Luis85 commented Apr 26, 2026

Summary

  • Pillar-1 slice 1.2b of the pre-v1 demo evolution increment.
  • Swaps the Wave-0 bridge in examples/product-demo/src/app/main.ts for a real Vue mount (createApp(App).use(pinia).use(router).mount('#app')) and deletes the four legacy DOM-mount files (src/{ui,traceView,seed,main}.ts). index.html is restructured to a <div id="app"> mount target.
  • Ports the legacy mounts into Vue SFCs: <HudPanel>, <SpeedPicker>, <ResetButton>, <ExportImportPanel>, <TracePanel>. Adds <TourOverlay> + <StepHighlight> against a useSelectorRegistry view-store stub (full registry lands in slice 1.3).
  • Adds the useTourProgress view store + chapter-1 (autonomy) step content. Predicate combines tickAtLeast(3) with eventEmittedSince(AGENT_TICKED, 0). Tour copy tone (OQ-P1) is settled to friendly-informal.
  • Extends useAgentSession with tickIndex / recentEvents / lastTrace / lastTickNumber / sessionSnapshot projections. Implements the snapshot-restore branch of replayFromSnapshot(snapshot) for <ExportImportPanel>.
  • Wires @vitejs/plugin-vue@^6 for the demo build + the root vitest test runtime (Vue 3.5 + Vite 8). Component tests run under // @vitest-environment jsdom per file.
  • Pre-v1 storage clean break: legacy agentonomous/* and whiskers* keys are NOT migrated. Wiped at first mount via the existing STO-3 purge (extended to cover the agentonomous/ namespace). New shell uses demo.v2.session.speed, demo.v2.trace.visible, demo.v2.tour.progress exclusively.

Tracks: #132

Test plan

  • npm run verify (format:check + lint + lint:demo + typecheck + 611 tests + lib build + typedoc) green.
  • examples/product-demo Vite production build green.
  • Component + view-store tests cover: HudPanel render + interaction wiring + selector-handle registration; SpeedPicker render + persistence + pause + no-migration of legacy key; ResetButton confirm/cancel paths; ExportImportPanel render + export Blob lifecycle; TracePanel toggle persistence; TourOverlay render + skip + predicate-driven completion; useTourProgress cold-start cursor + advancement + skip + persistence + restart + re-mount resume; useAgentSession snapshot-restore happy path + AGENT_TICKED projections.
  • Manual: load the demo, watch chapter-1 advance after a few ticks, verify Reset / Export-Import / SpeedPicker / TracePanel still function (Playwright happy-path lands in slice 1.4).

🤖 Generated with Claude Code

Symprowire and others added 2 commits April 26, 2026 22:01
Pillar-1 slice 1.2b of the pre-v1 demo evolution increment.

- Wires `@vitejs/plugin-vue` (build + vitest test runtime).
- Swaps `app/main.ts` from the Wave-0 `await import('../main.js')` bridge
  to `createApp(App).use(pinia).use(router).mount('#app')`. STO-3
  legacy-key purge stays as the first action and now wipes the
  `agentonomous/*` namespace too (pre-v1 clean break per design).
- Restructures `index.html` to a `<div id="app">` mount target — the
  legacy DOM scaffold (#bars, #buttons, #seed, #pet, #decision-trace,
  #species-config) is gone; SFCs build their own markup.
- Deletes legacy `src/{ui,traceView,seed,main}.ts`. `cognitionSwitcher.ts`,
  `lossSparkline.ts`, `predictionStrip.ts`, `speciesConfig.ts` stay
  (Pillar 2 slice 2.5 + Pillar 4 slice 4.3 own their deletion).
- Ports the legacy `mountHud` / `mountSpeedPicker` / `mountResetButton` /
  `mountExportImport` / `mountTraceView` into Vue SFCs:
  `<HudPanel>`, `<SpeedPicker>`, `<ResetButton>`, `<ExportImportPanel>`,
  `<TracePanel>`. Reuses the `INTERACTION_BUTTONS` / `STAGE_LABELS` /
  `NEEDS` data tables verbatim.
- Adds `<TourOverlay>` + `<StepHighlight>` against a `useSelectorRegistry`
  view-store stub (full registry lands in slice 1.3).
- Adds `useTourProgress` view store with cursor / completedAt / skipped
  + persistence under `demo.v2.tour.progress`. Reads
  `useAgentSession.sessionSnapshot` projection + the active route.
- Authors chapter-1 (autonomy) step content in
  `demo-domain/walkthrough/chapters/1.ts`. Predicate combines
  `tickAtLeast(3)` with `eventEmittedSince(AGENT_TICKED, 0)`.
- Settles OQ-P1: tour copy tone is **friendly-informal** (recorded in
  the slice plan's Done log + applied to the chapter-1 hint).
- Extends `useAgentSession` with `tickIndex` / `recentEvents` /
  `lastTrace` / `lastTickNumber` / `sessionSnapshot` projections so
  the view layer never re-subscribes to AGENT_TICKED. Implements the
  snapshot-restore branch of `replayFromSnapshot(snapshot)` —
  `<ExportImportPanel>` calls it directly.
- Updates `eslint.config.js` ignores (drops the four deleted files)
  and relaxes `no-restricted-imports` for `components/views/stores/view`
  to permit `import type` from `agentonomous` and `demo-domain/**`
  (runtime imports stay forbidden per design's DDD layering).

Storage-key clean break (per pre-v1 policy, not migrated): legacy
`agentonomous/seed`, `agentonomous/speed`, `agentonomous/trace-visible`,
`agentonomous/species-config`, `whiskers`, `whiskers:speed`. The new
shell uses `demo.v2.session.speed`, `demo.v2.trace.visible`, and
`demo.v2.tour.progress` exclusively.

Tracks: #132

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pillar-1 plan tracker: row 1.2b → ✅ shipped, linked to PR #150. Done log
captures the OQ-P1 decision (friendly-informal tour copy) plus the four
non-obvious mechanics that future-you / Codex will want to find quickly:

- `@vitejs/plugin-vue@^6` wired with `isProduction: false` for vitest so
  template directives bind under @vue/test-utils;
- `useAgentSession` projections (`tickIndex`, `recentEvents`, `lastTrace`,
  `lastTickNumber`, `sessionSnapshot`) keep view-layer SFCs subscription-
  free + the snapshot-restore branch of `replayFromSnapshot` actually
  restores now;
- demo `no-restricted-imports` was relaxed to permit `import type` from
  `agentonomous` + `demo-domain/**` (runtime stays forbidden);
- legacy `agentonomous/*` keys are wiped at first mount via the existing
  STO-3 purge; new shell uses the `demo.v2.*` namespace exclusively.

Tracks: #132

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Luis85
Copy link
Copy Markdown
Owner Author

Luis85 commented Apr 26, 2026

@codex review

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 26, 2026

Coverage report

Metric This PR vs base Floor Status
statements 86.67% ⬆️ +8.98pp 74% ⚠️ 12.7pp above floor — consider re-baselining
branches 77.05% ⬆️ +9.12pp 64% ⚠️ 13.0pp above floor — consider re-baselining
functions 90.41% ⬆️ +4.79pp 83% ⚠️ 7.4pp above floor — consider re-baselining
lines 88.89% ⬆️ +9.64pp 75% ⚠️ 13.9pp above floor — consider re-baselining

Floors live in scripts/coverageThresholds.mjs (drift envelope 5pp). Re-baseline by editing that file when ⚠️ appears above; cite the new measured value + commit SHA.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 26, 2026

size-limit report 📦

Path Size
dist/index.js (gzip) 37.86 KB (0%)
dist/integrations/excalibur/index.js (gzip) 1.4 KB (0%)
dist/cognition/adapters/mistreevous/index.js (gzip) 1.14 KB (0%)
dist/cognition/adapters/js-son/index.js (gzip) 1.36 KB (0%)
dist/cognition/adapters/tfjs/index.js (gzip) 8.74 KB (0%)

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aaea2bb3af

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +50 to +53
onMounted(() => {
const seed = readPersistedSeed() ?? generateSeed();
session.init({ seed });
raf = globalThis.requestAnimationFrame((t) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Initialize session before mounting speed controls

Move session.init(...) earlier in the render lifecycle (or re-apply the saved speed after init), because Vue runs child onMounted hooks before the parent. SpeedPicker reads demo.v2.session.speed and applies it in its own onMounted, but this parent hook then calls session.init, which resets speedMultiplier to 1 and running to true; as a result, persisted speed (including persisted pause) is silently lost on every page load.

Useful? React with 👍 / 👎.

Vue runs child onMounted before parent. SpeedPicker.onMounted reads the
persisted demo.v2.session.speed and applied it via session.pause()/setSpeed,
but PlayView's onMounted then called session.init(...) — which resets
speedMultiplier to 1 and running to true — silently discarding the saved
pause/speed on every page load. Move session.init out of onMounted into
the top-level <script setup> so it runs before any child component
instantiates; the rAF loop stays in onMounted because it doesn't want to
fire during SSR-style synchronous setup. Adds test/views/PlayView.test.ts
covering pause / numeric / no-persisted cases.

Codex P1 review on aaea2bb.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Luis85
Copy link
Copy Markdown
Owner Author

Luis85 commented Apr 26, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1342dee19a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +135 to +137
if (event.type === AGENT_TICKED) {
tickIndex.value += 1;
const ticked = event as AgentTickedEvent;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude paused ticks from tour progression counter

tickIndex is incremented for every AGENT_TICKED event, but the play loop still calls session.tick() while paused and Agent.tick() emits AGENT_TICKED even at timeScale=0. That means chapter-1’s tickAtLeast(3) predicate can be satisfied while the simulation is paused, so the tour can auto-complete without real autonomous progression. Please gate this counter on non-paused/positive virtual-dt ticks (or derive from an already gated signal).

Useful? React with 👍 / 👎.

`Reset ${petName.value}? Lifetime stats and current state will be lost.`,
);
if (ok !== true) return;
void session.replayFromSnapshot(null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear HUD lifetime counters when reset is confirmed

This reset path only rebuilds the agent session; it does not clear the HUD’s in-component lifetime counters, which are only reset in HudPanel.newPet(). After using this button, the next death summary can include stats from the previous pet, contradicting the confirmation text that “lifetime stats … will be lost.” Reset should also clear those counters (or route through a shared reset action that does both).

Useful? React with 👍 / 👎.

…on reset

Two Codex P2 findings on 1342dee:

1. useAgentSession: Agent.tick still emits AGENT_TICKED at timeScale=0
   so trace panels can keep observing paused frames, but
   `tickIndex` was incremented on every emission — chapter-1's
   `tickAtLeast(N)` predicate could therefore satisfy while paused,
   silently auto-completing the tour without real progression. Gate
   the increment on `event.virtualDtSeconds > 0` (the agent's already-
   computed "did virtual time advance this tick" signal). Trace +
   tickNumber projections still update so TracePanel stays live.
   step() — which temporarily unpauses for one virtual tick — keeps
   counting, as it should.

2. HudPanel: ResetButton.reset → session.replayFromSnapshot(null)
   rebuilds the agent but did not clear the HUD's in-component
   lifetime counters (only HudPanel.newPet() did). After clicking
   Reset, the next death summary leaked counters from the previous
   pet, contradicting the confirmation prompt's "lifetime stats …
   will be lost." Add a watch on `session.agent` that clears
   counters + lifeSummary whenever the ref swaps, so any rebuild
   path (ResetButton, newPet, future scenario switches) routes
   through one place. newPet's manual clear becomes redundant
   and is removed.

Adds regression coverage:
- useAgentSession: tickIndex frozen across paused tick(0.1) calls,
  advances by 1 on step().
- HudPanel: counters + lifeSummary reset after replayFromSnapshot(null).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Luis85
Copy link
Copy Markdown
Owner Author

Luis85 commented Apr 26, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a9030a6d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 272 to 273
agent.value = fresh;
setLearningAgent(fresh);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Defer session swap until snapshot restore succeeds

replayFromSnapshot replaces agent.value and rebinds listeners before awaiting fresh.restore(...). When an imported snapshot is syntactically valid JSON but semantically invalid, restore rejects and <ExportImportPanel> reports an import failure, yet the previous in-memory pet has already been discarded and replaced by a fresh one. This makes a failed import destructive; keep the current agent until restore succeeds (or rollback on failure).

Useful? React with 👍 / 👎.

Comment on lines +63 to +67
onMounted(() => {
const saved = readSaved();
const valid = saved !== null && CHOICES.some((c) => c.mult === saved);
const initial: number | 'pause' = valid ? (saved as number | 'pause') : 1;
active.value = initial;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Resync speed picker after replay resets speed state

The speed picker's active state is initialized on mount and updated on button clicks only, but session replays (Reset and import) force the store back to speedMultiplier = 1/running = true without remounting this component. After replay, the UI can still show "pause" or "4×" while the simulation is actually running at 1×, which is misleading and can cause incorrect follow-up actions. Add a watcher on session speed/running (or equivalent sync hook) to keep active accurate.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a9030a6d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 276 to 277
speedMultiplier.value = 1;
running.value = true;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve speed state when replaying/resetting the session

replayFromSnapshot() now unconditionally sets speedMultiplier to 1 and running to true, so Reset/New-pet/import flows silently discard the user’s current speed (including pause) and can leave the speed UI out of sync with the actual simulation rate until remount. This is a behavioral regression from the previous reset/import path, where speed preference was preserved across resets and imports.

Useful? React with 👍 / 👎.

`Reset ${petName.value}? Lifetime stats and current state will be lost.`,
);
if (ok !== true) return;
void session.replayFromSnapshot(null);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear persisted tfjs network on Reset

The reset button now only calls session.replayFromSnapshot(null) and no longer removes agentonomous/<agentId>/tfjs-network. Because learning-mode hydration reads that key (loadPersistedSnapshot in learning.ts), a user who trained the model and then presses Reset can still get the previously trained weights on the next learning-mode construct, which contradicts reset semantics of starting fresh.

Useful? React with 👍 / 👎.

…ve speed + clear tfjs network

Four Codex review findings on 5a9030a, all rooted in
useAgentSession.replayFromSnapshot:

P1 #3144119465 — defer agent swap until restore succeeds. The previous
shape replaced agent.value + rebound listeners BEFORE awaiting
fresh.restore(snapshot). A semantically broken (but JSON-valid) import
made restore reject AFTER the live pet had already been thrown out, so
ExportImportPanel's "import failed" alert silently destroyed the user's
session. Now the restore is awaited on the fresh agent first; on
rejection the fresh instance is dropped and the live agent stays put,
matching the legacy mountExportImport semantics.

P1 #3144120027 — preserve speedMultiplier + running across replay. The
previous code unconditionally reset both to 1/true, so Reset / New-pet /
import flows clobbered the user's pause or 4× choice. They reflect UI
state, not snapshot contents — keep them, and apply them to the fresh
agent's setTimeScale right after the swap so the rebuilt agent runs at
the same scale the picker is showing.

P2 #3144119466 — speed picker resync after replay. With P1 #3144120027
fixed, the store no longer drifts during replay, so SpeedPicker's
mount-time-initialized active ref stays correct without an explicit
sync hook. The defense-in-depth shape (storeToRefs + computed/watch on
running + speedMultiplier) was tried but trips a duplicate-Vue
duplication issue in the test runner — root vite.config.ts has no
`dedupe: ['vue', 'pinia']` for the test block, so the picker's
in-component reactive scope and the test's session mutations live in
different Vue copies; the watch fires (setupState.active mutates) but
the renderer never repaints. Out of scope for this PR — left a comment
in SpeedPicker.vue documenting the intended switch once the dedupe
config lands.

P2 #3144120028 — clear persisted tfjs network on Reset. Reset must
mean "fresh start": move the agentonomous/<agentId>/tfjs-network
localStorage clear into replayFromSnapshot's null/reset branch
(NOT the import branch — imported state is intentionally inheriting).
Same key the cognition switcher's Train and Untrain paths already use.

Adds regression coverage in useAgentSession.test.ts:
- speedMultiplier preserved across replayFromSnapshot(null)
- running=false preserved across replayFromSnapshot(null)
- tfjs-network localStorage key cleared by replayFromSnapshot(null)
- replayFromSnapshot(snapshot) leaves the live agent untouched when
  restore rejects (vi.spyOn on Agent.prototype.restore)

And a SpeedPicker test asserting the store contract (preserve speed)
holds end-to-end through a click → replay sequence.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Luis85
Copy link
Copy Markdown
Owner Author

Luis85 commented Apr 26, 2026

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 828f23dfee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +85 to +87
const lastStep = ref<WalkthroughStepId>(
(persisted?.lastStep as WalkthroughStepId | undefined) ?? graph.firstStepId,
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fallback to first step when persisted cursor is unknown

lastStep is restored from localStorage with a blind cast, so if a previously persisted step id is no longer present in graph.stepsById (for example after a step-id rename between releases), currentStep becomes null while completedAt remains null. In that state the overlay never renders and IntroView.startTour() won't call restart(), so users cannot re-enter the guided tour without manually clearing storage. Validate persisted.lastStep against the graph and default to firstStepId when missing.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 828f23dfee

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +85 to +87
const lastStep = ref<WalkthroughStepId>(
(persisted?.lastStep as WalkthroughStepId | undefined) ?? graph.firstStepId,
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fall back when persisted step id is unknown

Validate persisted.lastStep against graph.stepsById before restoring it. As written, any stale/corrupted value in demo.v2.tour.progress (for example after step-id changes between releases) leaves lastStep pointing to a missing node, so currentStep becomes null while completedAt is still null; then next()/skip() no-op and the guided flow can appear permanently stuck until storage is manually cleared.

Useful? React with 👍 / 👎.

Codex P2 #3144164103 / #3144166101 on 828f23d — useTourProgress was
restoring `lastStep` from `demo.v2.tour.progress` with a blind cast.
After a step-id rename between releases (or any other corrupted
payload), the cursor resolved to `currentStep === null` while
`completedAt` stayed null; the overlay then never rendered and
`next()` / `skip()` no-op'd, leaving users with no in-app way to
re-enter the guided tour short of clearing localStorage by hand.

Validate `persisted.lastStep` against `graph.stepsById.has(...)` and
fall back to `graph.firstStepId` when missing. Adds a regression test
covering the stale-id payload path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Luis85
Copy link
Copy Markdown
Owner Author

Luis85 commented Apr 26, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Breezy!

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Luis85 Luis85 merged commit bf74eeb into develop Apr 26, 2026
25 checks passed
@Luis85 Luis85 deleted the feat/tour-chapter-1-2b branch April 26, 2026 21:22
Luis85 added a commit that referenced this pull request Apr 27, 2026
…3) (#153)

## Summary

- Pillar-1 slice 1.3 of the pre-v1 demo evolution increment.
- Wires chapters 2-5 end-to-end on top of the chapter-1 vertical landed
in #150: `<TracePanel>`, cognition picker in `<HudPanel>`, JSON-preview
placeholder, and `<ExportImportPanel>` all emit the synthetic UI events
that drive their chapter predicates. The composed graph
(`petCareWalkthroughGraph`) now runs all five chapters in sequence;
`defineWalkthroughGraph(...)` validation catches typos in
`nextOnComplete` chains at module-load time.
- Closes the selector-handle union (spec **P1-FR-4**):
`RegisteredHandle` in
`examples/product-demo/src/stores/view/selectorHandles.ts` is now the
single source of truth. `useSelectorRegistry` is generic over it and the
new `useRegisterSelector(handle)` composable wraps the data-attribute
lookup pattern. A renamed literal in `selectorHandles.ts` becomes a
`tsc` error at every chapter + component referencing it (manually
verified by spot-renaming `'hud.needs'` → typecheck flagged 10 sites;
reverted).
- Adds **`/tour/:step`** routing (P1-FR-6): a slim `TourView.vue` wraps
`PlayView` and reconciles the URL with `useTourProgress.lastStep` via
new `currentStepRoutePath` / `syncRoute(router)` /
`resumeFromRoute(stepId)` actions. `resumeFromRoute` is forward-only — a
hard reload at `/tour/<earlier-step>` does not rewind past the persisted
cursor.
- New predicate primitives (P1-FR-3 follow-on):
`eventEmittedSinceStep(type)` and `ticksSinceStepAtLeast(n)` read a new
`stepBaselineTick` field on `TourCtx` populated by `useTourProgress`.
The baseline rebases to 0 when `session.tickIndex` resets, so chapter-5
import reliably fires on the post-rebuild event buffer (export → import
→ snapshot rebuild → predicate fires).
- Reset hygiene (**P1-FR-7**):
`useAgentSession.replayFromSnapshot(null)` now provably leaves
`useTourProgress.lastStep` / `completedAt` / `skipped` untouched.
Covered by a new test at `test/stores/view/useTourProgress.test.ts`.
- `<TourOverlay>` surfaces both **Skip** and **Restart** buttons
(**P1-FR-5**) and re-evaluates predicates on `recentEvents.length`
changes in addition to `tickIndex`, so UI events advance the tour
without per-component imperative `tour.next()` calls.

### Chapter-4 placeholder

Pillar-4 owns the proper preview/commit dual-action flow against
`useConfigDraft` + the editor view. Until that ships, slice 1.3 provides
a single placeholder "🛠️ Preview JSON" button in `<HudPanel>` that emits
`ConfigPreviewOpened` so the walkthrough can advance. When Pillar-4
slice 4.3 lands, this chapter's step content stays valid: the real
editor will emit the same event, the placeholder button is removed, and
the predicate keeps working without modification.

### Verification

- `npm run verify` (format:check + lint + lint:demo + typecheck + 645
tests + lib build + typedoc) green.
- `cd examples/product-demo && npm run build` (Vite production) green.
- Compile-time enforcement spot check passed (rename → tsc errors at
every consumer; reverted).

### Out of scope

- Playwright `tour-happy-path.spec.ts` — slice 1.4.
- Real `cognitionSwitcher.ts` port with loss sparkline + prediction
strip — Pillar-2 slice 2.5; this slice ships a minimal cognition
`<select>` placeholder that calls
`useAgentSession.setCognitionMode(...)` (probes peer + swaps reasoner).
- Real JSON preview/commit editor — Pillar-4 slice 4.3.

Tracks: #132

## Test plan

- [x] `npm run verify` green (645 tests).
- [x] `cd examples/product-demo && npm run build` green.
- [x] Compile-time enforcement spot check (rename a `RegisteredHandle`
literal → `tsc` errors at every consumer; revert).
- [ ] Manual: load the demo, walk through chapters 1-5 end-to-end. Each
chapter advances when its predicate fires; URL tracks the cursor. Reload
mid-tour at `/tour/<step>` → cursor resumes. Reset preserves cursor;
Skip advances + records; Restart returns to chapter-1 step-1.
- [ ] Manual chapter-3 fallback: with `mistreevous` / `js-son` / tfjs
unavailable, the cognition `<select>` renders those modes disabled with
an install hint and the chapter still advances when an available
alternative is picked.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
_Generated by [Claude
Code](https://claude.ai/code/session_01TPggmKp12XqQdNjjMKVxd7)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Luis85 added a commit that referenced this pull request Apr 27, 2026
## Summary

Resolves all 11 findings from the 2026-04-27 docs-review run (`d9b4b85`)
tracked in #157: 5 MAJOR + 5 MINOR + 1 NIT.

| ID | File | Severity | Fix |
|----|------|----------|-----|
| `d9b4b85.1` | `CLAUDE.md:53` | MAJOR | Add `lint:demo` + `docs` to
`npm run verify` description |
| `d9b4b85.2` | `CONTRIBUTING.md:144` | MAJOR | Same `npm run verify`
alignment |
| `d9b4b85.3` | `docs/PRODUCT_VISION.md:419` | MAJOR | Remove leaked
`/root/.claude/plans/...` path |
| `d9b4b85.4` | `examples/product-demo/README.md:109` | MAJOR |
`src/main.ts` → `src/app/main.ts` (moved in #150) |
| `d9b4b85.5` | `PUBLISHING.md:36-38` | MAJOR | Replace stale 5-job CI
list with `CI gate (required check)` aggregator + current leaf-job
reference |
| `d9b4b85.6` | `docs/PRODUCT_VISION.md:3-4,~413,~415,~469` | MINOR |
Remove dead `docs/specs/overview.md` + `docs/specs/roadmap.md`
references (header, relationship section, review steps) |
| `d9b4b85.7` | `docs/PRODUCT_VISION.md:417` | MINOR | Remove dead
`docs/plans/review-remediation.md` link |
| `d9b4b85.8` | `CONTRIBUTING.md:143` | MINOR | `R-XX` → `#NNN` (no R-XX
scheme in this repo) |
| `d9b4b85.9` | `CLAUDE.md:44` | MINOR | Drop hardcoded
`D:\Projects\agent-library` path |
| `d9b4b85.10` |
`docs/plans/2026-04-26-pre-v1-demo-guided-walkthrough.md:20` | MINOR |
Mark rename preflight as resolved (archived via #134) |
| `d9b4b85.11` | `.claude/memory/project_pending_major_changesets.md:8`
| NIT | Replace stale 4-changeset count with pointer to
`.changeset/*.md` |

## Test plan

- [x] `npm run verify` (format:check + lint + lint:demo + typecheck +
test + build + docs) green
- [x] No code changes — docs-only PR; behavior unchanged
- [ ] Codex review on the PR is acknowledged or rebutted

## Notes

- No changeset (docs-only).
- Issue #157 uses the `docs-review` label and `<!-- d:... -->` markers,
which the `review-fix-shipped` Action does not handle (it only matches
`<!-- f:... -->` from the code-review bot). The owner ticks the boxes
manually per `docs/docs-review-bot/README.md`. PR body therefore lists
each finding ID for manual reconciliation rather than the `Refs #
finding:` magic line.
- Bundled all 11 findings into one PR per the "one PR per session" rule
and the doc-only nature of the changes (each fix is a one-liner with no
test surface).

Refs #157

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Luis Mendez <hallo@luis-mendez.de>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Luis85 Luis85 added the roadmap:v1-demo Pre-v1 product-demo evolution: walkthrough, cognition diff, fingerprint, editor, second scenario label May 5, 2026
@Luis85 Luis85 mentioned this pull request May 11, 2026
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

roadmap:v1-demo Pre-v1 product-demo evolution: walkthrough, cognition diff, fingerprint, editor, second scenario

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants