243 Commits

Author SHA1 Message Date
David McKay de2bc6efc0 feat(banking): rank largest charges instead of repeating the team split
The report's third column was budget-usage bars: the same three team totals the
donut beside it already showed, redrawn with limits added. Two charts, one fact.

It now ranks the largest individual charges, which changes the unit of analysis
from team to transaction. A team aggregate cannot distinguish one $15,000
charge from thirty $500 ones, so this is information the donut genuinely cannot
carry. Bars stay coloured by owning team, so a row still ties back to its slice
without the two charts duplicating each other.

Budget-vs-limit is not lost: it remains the "Over policy limit" KPI above and
the "Needs a decision" rows below.

Invoice-derived line items now carry the policy id of the team they belong to,
so they colour like any other charge. Without it they fell back to a generic
swatch and a Marketing charge did not match Marketing's slice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 13:11:26 -07:00
David McKay 269d49a2c0 feat(banking): generative-UI polish for PIN, charges, report and notes
Five presentation fixes to the Northwind Finance demo, all from running the
beats live.

PIN change now resolves into a card rather than the sentence "New PIN saved."
It shows the card face, brand and last4, a masked new-PIN row and an active
badge. Digits are never rendered: they are never sent to the agent, so the mask
is the honest representation.

Reopening a thread replays setCardPin with status "inProgress" and no result,
so the answered card sat on "Loading..." forever. Other human-in-the-loop tools
here (showCharges) do replay their result, so this is specific to that call.
The outcome is now remembered per tool call id for the session and consulted
ahead of the replayed status. Both this card and the charges card key their
resolved state on the RESULT rather than the status, so an answered call can
never replay with live buttons.

setCardPin also registers once via a ref instead of depending on `cards`:
useFrontendTool re-registers whenever JSON.stringify(deps) changes and
re-registration removes the tool, so the PIN write tore down the very tool that
was servicing it.

showCharges becomes human-in-the-loop. Opening a filtered list is safe, but it
replaces the whole screen, and an agent that does that unasked reads as the
agent being in charge. The confirm card names the sort and filters before the
page changes, and on arrival the Sort and Show controls carry the brand tint
whenever they are non-default, so what the agent set is what lights up.

The Q2 report shows three different chart forms (share-of-total pie, time
series, budget bars) instead of three bar charts, and the seed is rebalanced so
team shares read 42/28/30 instead of 98/2/2 while all three pending charges
still exceed their limits. This drops the income-vs-expenses chart that was
showing $0.00.

Notes about reported charges carry a leading alert emoji so they cannot be
skimmed past. The seeded procedure asks for it and the handler applies it
regardless, because a model is not a reliable emoji emitter.

Finally, prose answers get a house style. The agent was formatting the first
few bullets of a list and then lapsing into plain text, which reads as a
rendering bug rather than a style choice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 11:12:00 -07:00
Maxim 1e575233e6 test(banking): make the memory-recall e2e approval loop actually completable
The approval loop could never pass, independent of the demo's behavior:

  for (let step = 0; step < 4; step++) {
    const approve = page.getByRole("button", { name: /^approve$/i });
    await approve.first().click({ timeout: 30_000 }).catch(...)
  }

Two compounding problems. The recall path emits at most three HITL cards
(openPolicyException -> finalizePolicyException -> approveTransaction) but the
loop demanded four, so the last iteration always waited on a card that never
arrives. And the per-click timeout (30s) equalled the whole test budget
(playwright.config.ts sets no `timeout`, so Playwright's 30s default applied),
so the first miss consumed the entire test and the `.catch()` fallback to the
other APPROVE_LABELS was unreachable dead code.

Now: poll every label for the next visible approve control, treat "no card
left" as flow completion rather than a timeout, keep a runaway guard that is
explicitly not the expected card count, and give the test a budget that can
actually hold one agent turn plus the closing server poll.

Confirmed against a local run (aimock + the docker Intelligence stack): the
agent recalls the procedure, files the EXC-BOARD-APPROVED exception, and
approves the charge, and the "Record a workflow?" card never appears. The
header's "verify on first green run" notes are updated to record what that
run settled and what it did not.

The spec still fails at its closing assertion: PUT /api/v1/transactions/t-3
{status:"approved"} keeps returning 422, i.e. store.hasApprovedException() is
false, so the over-limit gate is never lifted even though the (fixture-scripted)
agent text claims it was. That is pre-existing and out of scope here — this PR
touches no part of the approval path (lib/store, the exceptions/transactions
routes, copilot-context, components/wow are all untouched). Left failing rather
than skipped so it stays visible.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-29 15:27:08 +02:00
Maxim 0850c5e522 Merge remote-tracking branch 'origin/main' into blitz/glass-inspector/integration
Realigns the inspector/memory work onto the banking demo as it shipped in
#6136 (ChatGPT-style shell, gen-UI beats, durable-memory self-learning) and
#6202 (README refresh).

All six conflicts were the same collision: this branch removes the bespoke
Glass Engine inspector, while #6136 kept and rebuilt around it.

- run-handler.ts: kept both sides (our CopilotKitCoreCatalogComponent and
  main's MAX_FOLLOW_UP_DEPTH landed at the same spot).
- wrapper.tsx / layout.tsx: took main's rewritten provider tree and
  right-hand icon rail, minus the Glass Engine providers, pane, and
  telescope toggle. Also dropped main's `padClass` (it reserved space for
  the Glass pane and referenced a now-removed `glassActive`) and
  `<ProactiveNotice />` (main removed it; the import is already gone).
- memory-tab.tsx, lib/intelligence/memory.ts: confirmed the deletions.
  Their only remaining importers were the bespoke inspector and the
  banking-local /api/memories routes, all removed here. seed-memories.ts
  is unaffected: it POSTs to INTELLIGENCE_API_URL, not the local route.
- README.md: kept our product-inspector section over main's Glass Engine
  availability/activation prose, and documented the Capabilities tab.

Drive-by fixes to comment rot the migration created: user-id.ts and the
copilotkit route doc comments referenced the deleted Memory-panel proxies,
and the README pointed the presenter-reset control at the removed
telescope toggle.

Also replaces a literal NUL byte in capabilityKey() with a unicode escape.
The raw control character made tsc/grep/diff treat run-handler.ts as a
binary file, which hid this very merge's conflict markers from grep.
Behavior is unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 21:10:21 +02:00
David McKay b2f4b47a2d docs(banking): refresh the demo README to match what shipped
#6136 changed the demo substantially and left the README describing an older
build. Corrections:

- It documented CopilotPopup; the chat is a left-docked CopilotSidebar rendering
  two columns (thread rail + conversation) with the app's nav rail on the right.
- It called the learned over-limit memory `procedural`; the code writes
  `operational`.
- It said the Glass Engine Memory tab was "top-k semantic recall, not a full
  enumeration". It is now a complete enumeration ("Stored memories (N)"),
  aggregated across the demo's identities, with semantic search as a separate
  box.
- It listed per-run reset as a future follow-up. It ships, gated behind
  PRESENTER_RESET_ENABLED, and also re-seeds memory and returns to the bare root.
- It described showTransactions as a useFrontendTool; it is a useComponent so it
  persists in the transcript.
- The "change my Visa PIN from the team page" example described a navigation
  fallback; PIN entry is now a component in the chat and the agent never sees the
  digits.

Adds what was missing: the eight-pill demo script, the /charges page, the PDF/Q2
multimodal beat, seeded memory (and why the over-limit procedure is deliberately
NOT seeded), the components-not-markdown-tables rule, per-team chart colour, and
the two incompatible helper families in actions.ts that make destructuring `ok`
report a success as a failure.

All three screenshots are replaced — they showed the old right-docked chat, so
they contradicted the first paragraph.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-28 09:22:11 -07:00
David McKay 66a6af5d3e feat(banking): ChatGPT-style shell, gen-UI beats, and durable-memory self-learning
Turns the Northwind Finance banking demo into a presentable end-to-end demo.
Every beat was driven live and verified against real app state, not just the
agent's own claims.

The demo is eight suggestion pills, in order: show a chart; change a card PIN in
an interactive in-chat component; ask what is on screen; open the 10 most
expensive charges; prep the Q2 report from an attached PDF invoice; summarize
spend using a remembered preference; handle an unrecognized charge using a
remembered procedure; and finally learn a brand-new procedure by watching the
officer clear an over-limit charge. The last three are sequenced deliberately:
already-knows-a-preference, already-knows-a-procedure, learns-a-new-one — and on
a fresh thread the newly learned procedure is recalled and applied to a
different charge unaided.

Shell and UI:
- Chat docks LEFT as two columns (thread rail + conversation) with the app's
  icon rail moved right via flex `order`, so nav still precedes <main> in the
  DOM. The chat surface runs ChatGPT's neutral palette while the app keeps its
  violet identity.
- Tool activity renders as ChatGPT-style expandable lines; internal AG-UI
  plumbing is filtered out of the transcript.
- Tabular data always renders as components, never markdown tables; a one-row
  table is blocked structurally because a single-record table is narration.
- Filed reports are a dashboard (KPI tiles, three charts, decision rows) rather
  than a memo, with one colour per team across every chart and ranked bars in
  place of a donut that collapsed when an invoice pushed one team to 96%.
- PIN entry happens in the chat component; the agent never asks for or receives
  the digits.

Fixes worth review attention:
- Anything a RECALLED procedure can call must be registered globally. Four
  action tools were registered on the cards route, so a saved procedure only
  worked from one page.
- An unanswered human-in-the-loop card poisons the thread: skipping it left an
  unresolved tool call and the next message failed with "Tool result is missing
  for tool call ...". The procedure's closing step no longer gates; approvals
  that move money still do.
- actions.ts has two helper families that are not interchangeable —
  openPolicyException / finalizePolicyException / changeTransactionStatus return
  {ok, data/error}, while changePin / addNoteToTransaction resolve with the
  updated record. Destructuring `ok` off the second family reports success as
  failure.
- A stale canvas surface hid the page: it is derived from the last a2ui-surface
  message and replaces the page body until dismissed, but the dismiss effect
  keyed on pathname only, so a ?tab= switch left it covering the page.
- Suggestion pills ignore clicks while a run is in flight, since a double-click
  orphaned the previous run's tool call.

Deliberately NOT included: the @copilotkit/license-verifier pnpm patch (local
workaround for the "Invalid license token" banner) stays uncommitted, because it
patches a dependency for every install and is not demo scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 16:22:36 -07:00
Maxim f6d6d70fb7 chore(banking): finalize product inspector migration
Drop the stale doc-comment reference to the deleted src/lib/glass-engine.ts in
presenter.ts (final verification sweep).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:12:28 -07:00
Maxim 49c4ded95e docs(banking): replace Glass Engine docs with product inspector
Remove the GLASS_ENGINE_AVAILABLE env block from .env.example and replace the
README's 'Advanced mode — Glass Engine' section with a note on the product
web-inspector (enabled via showDevConsole; Memory tab powered by
exposeMemoryRoutes in Intelligence mode).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:11:31 -07:00
Maxim be07ba7782 test(banking): retarget memory-learning e2e off the bespoke inspector
Delete the final e2e test that drove the bespoke Glass Engine pane and remove
the GLASS_ENGINE_AVAILABLE env from both playwright configs. Self-learning
recall stays covered by the headless recall test; the product web-inspector is
covered by packages/web-inspector's own tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:10:38 -07:00
Maxim 3e0d8aa00e refactor(banking): delete bespoke inspector, glass gate, and dead memory routes
Delete the 13 Glass Engine inspector files (pane, tabs, event store, event-card
mapping, deployment gate, env gate) and their tests, the dead Next /api/memories
proxy routes, and the now-unused src/lib/intelligence/memory.ts helper module
(+ test). Memory now flows through the product path (core memory store →
runtime /api/copilotkit/memories) rather than the banking-local Next proxies.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:09:19 -07:00
Maxim 9f40ebe2a2 refactor(banking): remove Glass Engine deployment gate from layout
Drop useGlassEngine(), the Telescope toggle button, and the glassActive-driven
body padding from the app layout. The product inspector launcher replaces the
telescope toggle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:07:46 -07:00
Maxim 2614060266 refactor(banking): drop bespoke inspector providers from wrapper
Remove the GlassEngineProvider / InspectorStoreProvider wrappers and the
<InspectorPane/> mount from the client tree, and drop the glassAvailable prop
(and its server-side threading in layout.tsx). The product web-inspector
enabled in the prior commit replaces the bespoke pane.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:07:46 -07:00
Maxim fc085e2a3a feat(banking): enable product web-inspector via showDevConsole
Set showDevConsole={true} on the CopilotKitProvider to surface the product
web-inspector on every host, and set exposeMemoryRoutes: true on the
Intelligence-mode CopilotRuntime so the inspector's Memory tab can list and
recall memories in the demo.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-14 15:04:49 -07:00
David McKay a9c0910dea Merge branch 'main' into feat/banking-open-generative-ui 2026-07-09 12:07:23 -07:00
Maxim c1819f4932 test(banking): correct OGUI double-pill rationale comment
The .first() guard on the 'rendered on the canvas' handoff-pill assertion
was justified by an inaccurate comment (accumulation across exchanges). The
real cause is intra-turn: generateSandboxedUi has followUp:true, so aimock
re-serves the same fixture on the unchanged-userMessage follow-up turn in
replay -> a second identical pill. A terminating sequenceIndex follow-up
fixture was attempted but destabilized the suite (title-generation requests
substring-match the pill text and consume the sequence counter before the
real leg-1 turn), so the .first() guard remains. Test/fixtures only; no
source changes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 20:34:29 +02:00
github-actions[bot] 87b6fa330d style: auto-fix formatting 2026-07-09 17:34:36 +00:00
Maxim cd7e49e467 test(banking): OGUI routing asserts the canvas surface 2026-07-09 19:27:57 +02:00
Maxim c541f1b32d feat(banking): render OGUI surfaces on the canvas with a chat handoff pill 2026-07-09 19:14:50 +02:00
Maxim 001b915af2 feat(banking): useOguiSurface reads the latest OGUI activity from the stream 2026-07-09 18:49:37 +02:00
Maxim c54148412a test(banking): deterministic OGUI routing guard over the adjacency set
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 16:43:47 +02:00
Maxim 2dfedb0769 test(banking): fix stale smoke-test pill assertions 2026-07-09 02:54:43 +02:00
Maxim b041d998bf feat(banking): register OGUI on the provider, mount data-sync, add OGUI pills 2026-07-09 02:42:10 +02:00
Maxim c2f0b0f14b feat(banking): enable OGUI on both runtimes and fence it in the prompt 2026-07-09 02:11:12 +02:00
Maxim 795b185d4f feat(banking): SandboxDataSync mirrors live view into OGUI snapshot 2026-07-09 01:39:38 +02:00
Maxim d8b2da43ae feat(banking): read-only OGUI sandbox functions with projection DTOs 2026-07-09 01:20:14 +02:00
Maxim d1c573c6a2 refactor(banking): extract shared over-limit derivation into src/lib/over-limit 2026-07-09 01:08:38 +02:00
Martha Kelly Schumann 9a47bc72a7 Merge PR #5851 via QA Agent Pipeline
Auto-merged from Linear Needs Merge after approval and green CI.
2026-07-08 15:14:57 -07:00
Maxim 95430de51a chore(banking): add stop-demo.sh teardown companion to run-demo.sh
run-demo.sh detaches everything except the Next.js dev server (docker
compose up -d, native Metal TEI via nohup/disown, then exec pnpm dev), so
Ctrl-C on the dev server leaves the docker stack and the host embedder
running. stop-demo.sh brings those leftovers down in one command.

Tears down, idempotently:
  - the Next.js dev server on :3000 (defensive; usually gone via Ctrl-C)
  - the docker compose stack (project banking-memory), containers only by
    default so a re-run reuses the built image + seeded data
  - the native Metal TEI on :7067 (Apple Silicon; the host process docker
    doesn't manage), SIGTERM then SIGKILL

Flags: --purge also drops volumes for a clean slate; --keep-tei leaves the
slow-to-warm embedder running when only bouncing the stack.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-08 18:49:34 +02:00
QA Agent e743c28df7 docs(deepagents): add complete TypeScript state streaming examples
- Add full StateGraph + Annotation setup with CopilotKitStateAnnotation.spec
- Show complete tool implementation with proper ToolMessage handling
- Include graph compilation with nodes, edges, and routing logic
- Pattern examples after working shared-state-streaming.ts reference
- Fix both Deep Agents and LangGraph docs versions
- Include formatter fixes for JSON files

Fixes FAC-101
2026-07-07 13:41:03 -07:00
Maxim 258820e4ce fix(banking-demo): cap native TEI warmup batch to survive Metal fault
The self-hosted `run-demo.sh` path launches a native Metal
`text-embeddings-router` on :7067 for the durable-memory demo. TEI's
default `--max-batch-tokens` (16384) can fault the Metal backend during
its warmup forward pass on some Apple Silicon machines. The process then
either deadlocks (every thread parked in a pthread cond wait at 0% CPU)
or dies silently with no panic — a GPU-level abort — so it never binds
:7067 and the 300s health wait times out. The demo appears to "crash"
with no actionable error.

Pass `--max-batch-tokens 512` so warmup uses a small forward pass, which
clears reliably. This only bounds per-request tokens (memory texts are
short), not the embedding vectors, so recall stays byte-identical to the
docker/CI embedder.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 16:18:35 +02:00
github-actions[bot] 57ec68ecf9 style: auto-fix formatting 2026-07-06 14:22:05 +00:00
Maxim 6d5d407624 fix(banking): make fresh setup work on Apple Silicon (native TEI + run-demo.sh)
The bundled tei embedder image is amd64-only; under arm64 emulation the Candle
backend is unavailable and TEI falls back to the ONNX/ORT backend, which needs
onnx/model.onnx files Qwen3-Embedding-0.6B doesn't publish (404) -> crash-loop.
A fresh clone on Apple Silicon therefore couldn't stand up the embedder, so
memory save/recall were dead. Ports the proven pattern from the Intelligence
repo's docker-compose.deps.yml + demos/splat-demo/run-demo.sh into this demo:

- docker-compose.yml: gate the bundled `tei` behind the `cpu-fallback` profile,
  so a bare `docker compose up` skips the crash-looping emulated image. amd64/CI
  opt back in with `--profile cpu-fallback`. (intelligence's tei dep is
  required:false, so it starts fine without it, using MEMORY_EMBEDDINGS_URL.)
- run-demo.sh: one-command cold start. On Apple Silicon it runs a native Metal
  TEI on :7067 (same 1.9.3 + Qwen3-Embedding-0.6B => byte-identical embeddings,
  ~20x faster) and points app-api at it; on amd64/CI it uses the docker tei via
  the profile. Mints a dev license if .env lacks one, then starts `pnpm dev`.
- README: correct the failure description (emulation->ONNX crash-loop, not OOM),
  document run-demo.sh as the recommended start, and the profile-gated manual path.

All CopilotKit-repo-only (banking's compose is standalone); no Intelligence
changes. Validated: shellcheck clean, compose valid, bare `up` skips tei and
keeps intelligence healthy, memory save/recall verified through the native TEI.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 16:20:03 +02:00
Maxim 771f78c095 docs(banking): document PRESENTER_RESET_ENABLED 2026-07-06 16:20:03 +02:00
Maxim bfb91085e4 feat(banking): add env-gated presenter reset button to sidebar 2026-07-06 16:20:03 +02:00
Maxim 86ef09cdb3 feat(banking): thread resetEnabled flag to the layout 2026-07-06 16:20:02 +02:00
Maxim 271928249d fix(banking): report partial progress on reset memory failure 2026-07-06 16:20:02 +02:00
Maxim 7cbbaef5a9 feat(banking): gate reset endpoint on flag, forget all personas 2026-07-06 16:20:02 +02:00
Maxim 8be514df0b feat(banking): export SEEDED_USER_IDS for full-slate reset 2026-07-06 16:20:01 +02:00
Maxim 9744c104e2 feat(banking): add presenterResetEnabled env flag 2026-07-06 16:20:01 +02:00
Maxim 157d9fc723 feat(banking): reproducible dev-license mint helper (self-hosted memory)
Phase 3 of the banking->Intelligence-main migration. Self-hosted Intelligence
gates the paid `memory` feature behind a signed offline license; a locally-built
(unbaked) app-api trusts a runtime BAKED_LICENSE_KEYS_JSON, so a throwaway
keypair can sign an enterprise license with features.memory=true.

- scripts/mint-dev-license.mjs: prints (or --write upserts into .env)
  COPILOTKIT_LICENSE_TOKEN + BAKED_LICENSE_KEYS_JSON + INTELLIGENCE_DEPLOYMENT_MODE.
  Drives the signer from the PRIVATE Intelligence source via INTELLIGENCE_REPO
  (same coupling the docker-compose image build already has) rather than
  vendoring any signing code into this public repo. No secret is embedded; the
  script is dev-only and never imported by the app runtime.
- .env.example: documents BOTH the managed path (CopilotKit-issued token, no
  baked key — the eventual hosting target) and the self-hosted dev path, so the
  demo is not locked to the local stack.
- package.json: add `mint-dev-license` script.

Replaces the ephemeral Intelligence/tmp/mint-banking-license.ts. .env stays
gitignored; nothing sensitive is committed. Local-only until verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 16:20:01 +02:00
Maxim 3b1e04275e chore(banking): rename memory kinds to Intelligence main enum
Phase 2 of the banking->Intelligence-main migration. Main's memory lib
(libs/memory/src/types.ts) closes MemoryKind to topical|episodic|operational;
the demo was authored against the legacy semantic|procedural names, which the
backend now rejects/misfiles. Rename across the whole surface:
- agent prompt (route.ts CLASSIFY + SAVE-THE-PROCEDURE): semantic->topical,
  procedural->operational
- recorder instruction (copilot-context.tsx), learning-tab dual-read dropped,
  memory-tab KIND_COLORS, memory unit-test fixture
- smokes (facts + drift) and the e2e spec seed + fixtures comment

Only true kind: values renamed; "semantic recall"/"top-k semantic search"
mechanism descriptions left intact (recall is vector search regardless of enum).
aimock fixture re-record was a no-op: the one fixture pins the recall-and-apply
arc (no kind: values); the seed is REST-side in the spec.

Verified: pnpm test:unit 47/47, tsc --noEmit clean, eslint clean on touched files.
Local-only until the full migration is verified against the main stack.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 16:20:00 +02:00
Maxim ccd1c974f5 wip(banking): migrate compose auth to Intelligence main (Phase 1 spike)
Phase 1 of the banking->Intelligence-main migration (branch:
feat/banking-intelligence-main-migration). PROVEN GREEN against main:
- INTELLIGENCE_DEPLOYMENT_MODE=self_hosted (renamed from legacy DEPLOYMENT_MODE)
- dropped legacy DEFAULT_ORGANIZATION_ID (main's loadAuthEnv rejects it)
- BAKED_LICENSE_KEYS_JSON wired: main gates memory behind a signed license
  carrying the "memory" feature (MEMORY_NOT_ENTITLED otherwise). A locally
  minted dev enterprise license + baked public key unlocks it (recipe mirrors
  Intelligence apps/app-api-e2e global-setup). Verified: /mcp attaches
  recall/save/forget_memory and save_memory(kind=topical) round-trips via the
  cpk key.

REMAINING (next session): (1) reproducible dev-license mint helper + .env wiring
(mint script currently at Intelligence/tmp/mint-banking-license.ts, ephemeral);
(2) kind rename semantic->topical, procedural->operational across prompt, memory
lib, smokes, e2e spec; (3) aimock fixture re-record for new kinds; (4) re-verify
e2e/smokes/manual arc. Working demo (PR #5763, demo branch) is untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 16:18:52 +02:00
github-actions[bot] 40fe2c64a6 style: auto-fix formatting 2026-07-03 18:15:03 +00:00
Maxim f568c7e3d6 fix(banking): tell the agent to omit save_memory supersedes unless it has a real memory UUID 2026-07-03 19:30:56 +02:00
Maxim ca5f6f7da9 test(banking): use UUID thread/run ids in smokes (backend validates thread id as UUID) 2026-07-03 17:26:39 +02:00
Maxim 277b037193 test(banking): smokes preflight the demo dev server for a clear 'run pnpm dev' error 2026-07-03 17:23:45 +02:00
Maxim 84095d63ec test(banking): add /mcp readiness gate to memory smokes; document backend boot-window flake 2026-07-03 17:17:50 +02:00
Maxim fba5b085c3 test(banking): drain full turn in drift smoke so rule-9 negative save assertion is reliable 2026-07-03 16:28:24 +02:00
Maxim c3728848c2 fix(banking): add memberId to learning-tab fetch useCallback deps 2026-07-03 16:22:38 +02:00
Maxim 40babda9d0 docs(banking): document general memory and the 2-persona cross-user demo 2026-07-03 16:14:26 +02:00