From 335056d74d015df203a004308ee43b1fef4fa5e8 Mon Sep 17 00:00:00 2001 From: Conan Scott Date: Wed, 1 Jul 2026 17:28:07 +1000 Subject: [PATCH 1/3] seed: add second demo persona (Conan Scott, reckless profile) Synthetic demo customer cust-0002 with fictional high-risk financials and a synthetic Taiwan ROC ID. Verified live end-to-end: detected + tokenized on ingress (name never reaches the cloud), agent produces risk-flavoured talking points, identity restored on egress. Co-Authored-By: Claude Opus 4.8 --- seed/customers.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/seed/customers.json b/seed/customers.json index be8aae9..ebae203 100644 --- a/seed/customers.json +++ b/seed/customers.json @@ -8,5 +8,15 @@ "product_type": "funds, income-generating products", "risk_profile": "conservative", "sales_constraints": "avoid high-volatility products" + }, + { + "customer_id": "cust-0002", + "name": "Conan Scott", + "national_id": "F225793148", + "activity_summary": "compulsive day-trading, 200+ speculative trades/week, 90 days", + "amount_band": "leveraged well beyond net worth (>10x margin)", + "product_type": "0DTE options, leveraged crypto, meme stocks, junk bonds", + "risk_profile": "recklessly aggressive; ignores every suitability warning", + "sales_constraints": "none observed; chases volatility, doubles down on losses" } ] From 40783da0fe951c47d1986147fb61a13247bb68bc Mon Sep 17 00:00:00 2001 From: Conan Scott Date: Wed, 1 Jul 2026 17:50:45 +1000 Subject: [PATCH 2/3] refactored the docs --- docs/Flow Diagram.mmd | 44 +++++++++++ docs/Sequence Diagram.mmd | 34 +++++++++ docs/architecture.md | 149 +++++++++----------------------------- 3 files changed, 114 insertions(+), 113 deletions(-) create mode 100644 docs/Flow Diagram.mmd create mode 100644 docs/Sequence Diagram.mmd diff --git a/docs/Flow Diagram.mmd b/docs/Flow Diagram.mmd new file mode 100644 index 0000000..3871787 --- /dev/null +++ b/docs/Flow Diagram.mmd @@ -0,0 +1,44 @@ +## Flow diagram + +```mermaid +flowchart TB + advisor(["Advisor (browser)"]) + ui["Advisor UI
S3 + CloudFront
(split view)"] + + subgraph entry["Entry / orchestration"] + fusion["Fusion SaaS (prod)
— or —
/demo Lambda (Fusion-less dry run)"] + end + + subgraph cloudzone["CLOUD zone (Zone=cloud-VPC-B) — sees TOKENS only"] + runtime["AgentCore Runtime
Strands agent + Bedrock
apac Claude 3.5 Sonnet v2"] + gateway["AgentCore Gateway
MCP · AWS_IAM / SigV4"] + end + + subgraph onprem["ON-PREM zone (Zone=on-prem-VPC-A) — holds the reversible map + PII"] + tokenize["/tokenize Lambda (in-VPC)
detect → mint → vault → splice"] + presidio["Presidio detector
Fargate (PRIVATE, SG-locked :5001)"] + vault[("DynamoDB VAULT
token <-> PII (+customer_id)")] + customers[("DynamoDB CUSTOMERS
raw records — never leave")] + rag["RAG tool Lambda
token -> evidence (no PII out)"] + restore["/restore Lambda
re-attach identity"] + end + + advisor -- "1 query: 王小明 + A123456789" --> ui + ui -- "POST {query}" --> fusion + fusion -- "2 {query}" --> tokenize + tokenize -- "POST /analyze" --> presidio + presidio -- "typed findings" --> tokenize + tokenize -- "write {token,type,value,session}" --> vault + tokenize -- "3 deidentified_prompt (CUST_*)" --> runtime + runtime -- "4 tools/call get_customer_activity_summary(CUST_*)" --> gateway + gateway -- "5 invoke (SigV4)" --> rag + rag -- "6 resolve token" --> vault + rag -- "read record" --> customers + rag -- "7 evidence package (token-keyed, no PII)" --> runtime + runtime -- "talking points (tokens only)" --> fusion + fusion -- "8 {session_id, text}" --> restore + restore -- "lookup session tokens" --> vault + restore -- "final: (客戶:王小明)…" --> fusion + fusion -- "{final, deidentified_prompt, agent_tokenized}" --> ui + ui -- "split view: restored vs tokenized" --> advisor +``` \ No newline at end of file diff --git a/docs/Sequence Diagram.mmd b/docs/Sequence Diagram.mmd new file mode 100644 index 0000000..df86a66 --- /dev/null +++ b/docs/Sequence Diagram.mmd @@ -0,0 +1,34 @@ +─```mermaid +sequenceDiagram + autonumber + actor A as Advisor + participant UI as UI (S3/CloudFront) + participant F as Fusion + participant TK as tokenize (on-prem) + participant PR as Presidio (private) + participant V as Vault (DynamoDB) + participant RT as AgentCore Runtime + Bedrock (cloud) + participant GW as AgentCore Gateway (cloud) + participant RG as RAG Lambda (on-prem) + participant RS as restore (on-prem) + + A->>UI: query with 王小明 + A123456789 + UI->>F: POST {query} + F->>TK: {query} + TK->>PR: POST /analyze + PR-->>TK: typed findings + TK->>V: write token to PII map (session) + TK-->>F: deidentified_prompt (CUST_*) + F->>RT: {prompt: CUST_*} + Note over RT,GW: cloud sees TOKENS only + RT->>GW: tools/call get_customer_activity_summary(CUST_*) + GW->>RG: invoke (SigV4) + RG->>V: resolve token to customer_id + RG-->>RT: de-identified evidence package + RT-->>F: talking points (tokens only) + F->>RS: {session_id, text} + RS->>V: lookup session tokens + RS-->>F: final (王小明 restored) + F-->>UI: {final, deidentified_prompt, agent_tokenized} + UI-->>A: split view (restored vs tokenized) +``` \ No newline at end of file diff --git a/docs/architecture.md b/docs/architecture.md index 94efe45..0e92e6b 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -27,89 +27,11 @@ demo proves data-flow behaviour, not physical residency. | 4-6 | RAG tool | `lambda_rag/` | Lambda | on-prem | ✅ resolves token, returns none | | 8 | `/restore` | `gateway_api/restore/` | Lambda + API Gateway | on-prem | ✅ re-attaches identity | -## Flow diagram -```mermaid -flowchart TB - advisor(["Advisor (browser)"]) - ui["Advisor UI
S3 + CloudFront
(split view)"] - - subgraph entry["Entry / orchestration"] - fusion["Fusion SaaS (prod)
— or —
/demo Lambda (Fusion-less dry run)"] - end - - subgraph cloudzone["CLOUD zone (Zone=cloud-VPC-B) — sees TOKENS only"] - runtime["AgentCore Runtime
Strands agent + Bedrock
apac Claude 3.5 Sonnet v2"] - gateway["AgentCore Gateway
MCP · AWS_IAM / SigV4"] - end - - subgraph onprem["ON-PREM zone (Zone=on-prem-VPC-A) — holds the reversible map + PII"] - tokenize["/tokenize Lambda (in-VPC)
detect → mint → vault → splice"] - presidio["Presidio detector
Fargate (PRIVATE, SG-locked :5001)"] - vault[("DynamoDB VAULT
token <-> PII (+customer_id)")] - customers[("DynamoDB CUSTOMERS
raw records — never leave")] - rag["RAG tool Lambda
token -> evidence (no PII out)"] - restore["/restore Lambda
re-attach identity"] - end - - advisor -- "1 query: 王小明 + A123456789" --> ui - ui -- "POST {query}" --> fusion - fusion -- "2 {query}" --> tokenize - tokenize -- "POST /analyze" --> presidio - presidio -- "typed findings" --> tokenize - tokenize -- "write {token,type,value,session}" --> vault - tokenize -- "3 deidentified_prompt (CUST_*)" --> runtime - runtime -- "4 tools/call get_customer_activity_summary(CUST_*)" --> gateway - gateway -- "5 invoke (SigV4)" --> rag - rag -- "6 resolve token" --> vault - rag -- "read record" --> customers - rag -- "7 evidence package (token-keyed, no PII)" --> runtime - runtime -- "talking points (tokens only)" --> fusion - fusion -- "8 {session_id, text}" --> restore - restore -- "lookup session tokens" --> vault - restore -- "final: (客戶:王小明)…" --> fusion - fusion -- "{final, deidentified_prompt, agent_tokenized}" --> ui - ui -- "split view: restored vs tokenized" --> advisor -``` ## Sequence (the 8-step round trip) -```mermaid -sequenceDiagram - autonumber - actor A as Advisor - participant UI as UI (S3/CloudFront) - participant F as Fusion or demo - participant TK as tokenize (on-prem) - participant PR as Presidio (private) - participant V as Vault (DynamoDB) - participant RT as AgentCore Runtime + Bedrock (cloud) - participant GW as AgentCore Gateway (cloud) - participant RG as RAG Lambda (on-prem) - participant RS as restore (on-prem) - A->>UI: query with 王小明 + A123456789 - UI->>F: POST {query} - F->>TK: {query} - TK->>PR: POST /analyze - PR-->>TK: typed findings - TK->>V: write token to PII map (session) - TK-->>F: deidentified_prompt (CUST_*) - F->>RT: {prompt: CUST_*} - Note over RT,GW: cloud sees TOKENS only - RT->>GW: tools/call get_customer_activity_summary(CUST_*) - GW->>RG: invoke (SigV4) - RG->>V: resolve token to customer_id - RG-->>RT: de-identified evidence package - RT-->>F: talking points (tokens only) - F->>RS: {session_id, text} - RS->>V: lookup session tokens - RS-->>F: final (王小明 restored) - F-->>UI: {final, deidentified_prompt, agent_tokenized} - UI-->>A: split view (restored vs tokenized) -``` - -## ASCII fallback ``` ┌──────────────────────────────────────────────┐ @@ -123,53 +45,53 @@ sequenceDiagram │ S3 + CloudFront │──POST─────▶│ • Fusion SaaS (prod) │ stands in for Fusion │ (split view) │ {query} │ • /demo Lambda (dry run) │ only, in the demo └─────────────────┘◀───────────│ tokenize→agent→restore │ - ▲ {final, └───────────┬───────────────┘ + ▲ {final, └────────────┬──────────────┘ │ deidentified, │ │ agent_tokenized} │ 2 {query} ════════╪════════════════════════════════════╪════════ TRUST BOUNDARY (public HTTPS + x-api-key) ON-PREM│ (Zone=on-prem-VPC-A) ▼ - │ ┌───────────────────────┐ findings ┌────────────────────┐ - │ │ /tokenize Lambda │────────────▶│ Presidio detector │ - │ │ (in VPC) │◀────────────│ Fargate (PRIVATE, │ - │ │ detect→mint→vault→splice│ │ SG-locked :5001) │ - │ └───────┬───────────────┘ └────────────────────┘ + │ ┌────────────────────────┐ findings ┌────────────────────┐ + │ │/tokenize Lambda │────────────▶│ Presidio detector │ + │ │(in VPC) │◀────────────│ Fargate (PRIVATE, │ + │ │detect→mint→vault→splice│ │ SG-locked :5001) │ + │ └───────┬────────────────┘ └────────────────────┘ │ │ write {token,type,value,session} │ ▼ │ ┌───────────────────────┐ (VPC gateway endpoint) - │ │ DynamoDB VAULT │◀────────────────┐ - │ │ token ⇄ PII (+cust_id) │ │ + │ │ DynamoDB VAULT │◀────────────────┐ + │ │ token ⇄ PII (+cust_id)│ │ │ └───────────────────────┘ │ - │ deidentified_prompt = "…CUST_317499…" ← TOKENS ONLY │ -════════╪═════════════════════════════════│═════════════════════════════════╪══════════════ - CLOUD │ (Zone=cloud-VPC-B) │ 3 │ resolve token - │ ▼ │ - │ ┌────────────────────────┐ │ - │ │ AgentCore RUNTIME │ │ - │ │ Strands agent + Bedrock│ │ - │ │ (apac Claude 3.5 Sonnet)│ │ - │ └───────────┬────────────┘ │ - │ │ 4 tools/call (MCP, SigV4) │ - │ ▼ get_customer_activity_summary │ - │ ┌────────────────────────┐ │ - │ │ AgentCore GATEWAY (MCP) │ │ - │ │ AWS_IAM auth │ │ - │ └───────────┬────────────┘ │ - │ ← trace shows ONLY tokens │ 5 invoke │ -════════╪══(王小明: 0 hits, CUST_: 13)═══│═════════════════════════════════════╪══════════════ - ON-PREM│ ▼ │ - │ ┌────────────────────────┐ 6 reads │ - │ │ RAG tool Lambda │─────────────────────┘ - │ │ token→customer_id→ │ ┌────────────────────┐ - │ │ de-identified evidence │─────▶│ DynamoDB CUSTOMERS │ ← raw PII - │ │ (raw record stays here) │ read │ (never leaves zone)│ stays put + │ deidentified_prompt = "…CUST_317499…" ← TOKENS ONLY │ +════════╪═════════════════════════════════│════════════════════════════════╪══════════════ + CLOUD │ (Zone=cloud-VPC-B) │ 3 │ resolve token + │ ▼ │ + │ ┌─────────────────────────┐ │ + │ │ AgentCore RUNTIME │ │ + │ │ Strands agent + Bedrock│ │ + │ │ (Claude 3.5 Sonnet). │ │ + │ └───────────┬─────────────┘ │ + │ │ 4 tools/call (MCP, SigV4) │ + │ ▼ get_customer_activity_summary│ + │ ┌────────────────────────┐ │ + │ │ AgentCore GATEWAY (MCP) │ │ + │ │ AWS_IAM auth │ │ + │ └───────────┬────────────┘ │ + │ ← trace shows ONLY tokens │ 5 invoke │ +════════╪══(王小明: 0 hits, CUST_: 13)════│═════════════════════════════════╪══════════════ + ON-PREM│ ▼ │ + │ ┌────────────────────────┐ 6 reads │ + │ │ RAG tool Lambda │────────────────────┘ + │ │ token→customer_id→ │ ┌────────────────────┐ + │ │ de-identified evidence │─────▶│ DynamoDB CUSTOMERS │ ← raw PII + │ │ (raw record stays here)│ read │ (never leaves zone)│ stays put │ └───────────┬────────────┘ └────────────────────┘ │ │ 7 evidence package (token-keyed, no PII) │ ▼ → agent writes talking points (tokens only) │ ┌────────────────────────┐ - │ 8 {session_id, │ /restore Lambda │ - └───────────────────▶│ vault lookup by session │ prepend 王小明 + swap inline tokens - final = "(客戶:王小明)…" │ re-attach identity │ - ← PII restored on-prem └────────────────────────┘ + │ 8 {session_id, │ /restore Lambda │ + └───────────────────▶│ vault lookup by session│ prepend 王小明 + swap inline tokens + final = "(客戶:王小明)…" │ re-attach identity │ + ← PII restored on-prem └────────────────────────┘ ``` ## Auth & network per hop @@ -190,3 +112,4 @@ Notes: orchestrator only stands in for Fusion's orchestration in the Fusion-less dry run. - Tokens are **random per request** (`CUST_` for a PERSON, `TW_` for a Taiwan ROC ID); the reversible map lives only in the on-prem vault. + \ No newline at end of file From 4c540c6a83b36739f0dce6f7939d8c12cc7e8c66 Mon Sep 17 00:00:00 2001 From: Conan Scott Date: Wed, 1 Jul 2026 18:00:02 +1000 Subject: [PATCH 3/3] docs: relabel ASCII diagram heading (Sequence -> Flow) The ASCII block is the flow/topology diagram, not the sequence. Co-Authored-By: Claude Opus 4.8 --- docs/architecture.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/architecture.md b/docs/architecture.md index 0e92e6b..ae99d58 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -29,7 +29,7 @@ demo proves data-flow behaviour, not physical residency. -## Sequence (the 8-step round trip) +## Flow (ASCII fallback)