Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,29 @@ flowchart LR
- The Blindfold Proxy on your machine **never has the key** — its only inputs are the agent's HTTP request and a sentinel string `__BLINDFOLD__`.
- The contract reads the key from KV **inside TDX memory**, substitutes it into the headers, makes the call, and returns the response. The plaintext key exists only on one stack frame, inside the enclave, for the duration of one call.

Architecture in detail: [`docs/03-architecture.md`](docs/03-architecture.md).
<details>
<summary><b>Step-by-step: one request through the proxy (sequence)</b></summary>

```mermaid
sequenceDiagram
autonumber
participant A as 🤖 Agent
participant P as Proxy
participant E as 🔒 Enclave
participant U as Upstream API
A->>P: request with Authorization Bearer __BLINDFOLD__
Note over P: overwrite Authorization with the sentinel,<br/>match URL prefix to provider host and secret
P->>E: ForwardRequest, sentinel only
Note over E: read secret from the map,<br/>replace __BLINDFOLD__ with the real key,<br/>apply the auth scheme
E->>U: real HTTPS request from inside TDX
U-->>E: response
E-->>P: response, sealed secret redacted
P-->>A: response — the key never crossed back out
```

</details>

**Full architecture** — 11 diagrams (context, components, all three secret paths, signup, attestation, trust boundaries, ledger, lifecycle): [`system_design.md`](system_design.md). Original writeup: [`docs/03-architecture.md`](docs/03-architecture.md).

---

Expand Down
65 changes: 63 additions & 2 deletions packages/chatbot/data/knowledge.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schemaVersion": "1.0.0",
"generatedAt": "2026-07-12",
"source": "Manually curated from docs/, README.md, FAQ.md, usage.md, EXAMPLES.md, packages/blindfold/src/*.ts and contract/src/*.rs + extraction pipeline (2026-07-04) + extraction pipeline (2026-07-04) + extraction pipeline (2026-07-04) + extraction pipeline (2026-07-11) + extraction pipeline (2026-07-12)",
"generatedAt": "2026-07-13",
"source": "Manually curated from docs/, README.md, FAQ.md, usage.md, EXAMPLES.md, packages/blindfold/src/*.ts and contract/src/*.rs + extraction pipeline (2026-07-04) + extraction pipeline (2026-07-04) + extraction pipeline (2026-07-04) + extraction pipeline (2026-07-11) + extraction pipeline (2026-07-12) + extraction pipeline (2026-07-12)",
"entries": [
{
"id": "kb-001",
Expand Down Expand Up @@ -20125,6 +20125,67 @@
],
"confidence": 0.7,
"lastVerified": "2026-07-12"
},
{
"id": "kb-system-architecture",
"intent": "system_architecture",
"audience": [
"user",
"founder",
"developer",
"enterprise",
"researcher",
"general"
],
"question": "How is Blindfold architected / how does the whole system work?",
"shortAnswer": "Client side: the CLI, a local sentinel proxy, and a Terminal 3 SDK wrapper. Server side: a Rust→WASM contract (`blindfold-proxy`) running inside an Intel TDX enclave, holding your secrets map and enforcing an egress allowlist. Your agent only ever sends the placeholder `__BLINDFOLD__`; the real key is substituted inside the enclave. Full diagrams are in system_design.md.",
"longAnswer": "## System architecture\n\n**Client side (`packages/blindfold`)** — all treated as *untrusted for secrets*:\n- `bin/blindfold.ts` — CLI dispatcher.\n- `src/proxy.ts` — the local sentinel proxy; overwrites any `Authorization` with `Bearer __BLINDFOLD__` and routes by URL prefix.\n- `src/providers.ts` — maps a URL prefix → upstream host + sealed-secret name + auth scheme (bearer/basic/sigv4/webhook).\n- `src/t3-client.ts` — wraps `@terminal3/t3n-sdk` (auth, seed, forward, release, delete, balance).\n- `src/sealed-ledger.ts` — a metadata-only, HMAC hash-chained record of what's sealed.\n\n**Server side (Terminal 3, Intel TDX)**:\n- `contract/` — a Rust→WASM contract published as `blindfold-proxy`. Its `forward` function substitutes the sealed secret *inside* the enclave and makes the outbound call; `release-to-tenant` returns plaintext to the authenticated tenant.\n- The tenant's `secrets` map holds the canonical key value — the only place it lives.\n- An egress allowlist (`agent-auth-update`) denies any host you haven't granted.\n\n**The flow:** agent → local proxy (sees only the sentinel) → enclave `forward` (swaps sentinel for the real key, calls the API) → response back. The plaintext key exists only inside the enclave, for one call. See **system_design.md** for the full set of diagrams (context, components, sequence flows, signup, attestation, trust boundaries, ledger, lifecycle).",
"links": [
{
"label": "system_design.md",
"url": "system_design.md",
"type": "code"
},
{
"label": "ARCHITECTURE.md",
"url": "ARCHITECTURE.md",
"type": "code"
}
],
"sources": [
"system_design.md",
"packages/blindfold/src/proxy.ts",
"contract/src/forward.rs"
],
"confidence": 0.97,
"lastVerified": "2026-07-13"
},
{
"id": "kb-three-secret-paths",
"intent": "three_secret_paths",
"audience": [
"developer",
"enterprise",
"researcher",
"general",
"user"
],
"question": "What are the three ways a sealed secret gets used (proxy vs release vs register)?",
"shortAnswer": "1) Proxy/forward — the key is substituted INSIDE the enclave, so your agent never holds it (strongest). 2) Release broker — the plaintext is returned to YOUR local process for one call (protects the agent's context, not your process). 3) Seed/register — the value enters the enclave once, at seal time. Pick per workload; see the Cost section.",
"longAnswer": "## The three secret paths\n\nBlindfold uses a sealed secret in three ways, with different security postures:\n\n| Path | Where plaintext appears | Guarantee | Use for |\n|---|---|---|---|\n| **Proxy / forward** | only inside the enclave | strongest — the agent never holds it | agent HTTP calls, autonomous agents |\n| **Release broker** | your local process, briefly | protects the agent's *context*, not your process | `blindfold use`, non-HTTP protocols, batch |\n| **Seed / register** | your process once, at seal time | unavoidable — the value must enter the enclave once | one-time setup |\n\n**Proxy** (`proxy.ts` → contract `forward`): the agent sends `Bearer __BLINDFOLD__`; the enclave swaps it for the real key and makes the call. **Release** (`release.ts` → contract `release-to-tenant`): hands the plaintext to your process for one command — cheaper for bursts (release once, reuse for N calls), but the value lives in your memory for that window. **Register** (`register.ts`): the single line that ever sees plaintext, sealing the value via `map-entry-set`. See system_design.md §4 for sequence diagrams of each.",
"links": [
{
"label": "system_design.md#4--the-three-secret-paths",
"url": "system_design.md",
"type": "code"
}
Comment on lines +20176 to +20181

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Informational

2. Kb deep-link url mismatch 🐞 Bug ≡ Correctness

The new kb-three-secret-paths entry’s link label includes the #4--the-three-secret-paths
fragment, but the URL omits it, so the rendered Sources link won’t navigate to the intended section.
Agent Prompt
### Issue description
A KB entry link label suggests a deep link (includes a `#...` fragment) but the actual `url` target is missing that fragment. The responder renders links using `link.url`, so users will not land on the intended section.

### Issue Context
In `kb-three-secret-paths`, the link object is:
- label: `system_design.md#4--the-three-secret-paths`
- url: `system_design.md`

### Fix Focus Areas
- packages/chatbot/data/knowledge.json[20176-20181]

### Suggested fix
Update the URL to include the anchor:
- `"url": "system_design.md#4--the-three-secret-paths"`
(Confirm the exact heading slug in `system_design.md` if GitHub’s generated anchor differs.)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

],
"sources": [
"system_design.md",
"packages/blindfold/src/release.ts"
],
"confidence": 0.96,
"lastVerified": "2026-07-13"
}
]
}
26 changes: 26 additions & 0 deletions packages/chatbot/src/intents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,32 @@ export const INTENT_PATTERNS: IntentPattern[] = [
],
examples: ["is Blindfold on npm?", "how do I install Blindfold?", "what's the npm package?"],
},
{
intent: "system_architecture",
patterns: [
{ type: "phrase", value: "system design", weight: 6 },
{ type: "phrase", value: "architect", weight: 5 },
{ type: "phrase", value: "design of", weight: 3 },
{ type: "phrase", value: "how is it built", weight: 4 },
{ type: "phrase", value: "how is blindfold built", weight: 5 },
{ type: "phrase", value: "how does the whole system", weight: 5 },
{ type: "phrase", value: "components", weight: 2 },
{ type: "phrase", value: "how it works end to end", weight: 4 },
],
examples: ["how is Blindfold architected?", "explain the system design", "what are the components?"],
},
{
intent: "three_secret_paths",
patterns: [
{ type: "phrase", value: "three ways", weight: 6 },
{ type: "phrase", value: "three paths", weight: 6 },
{ type: "phrase", value: "proxy vs release", weight: 7 },
{ type: "phrase", value: "release vs proxy", weight: 7 },
{ type: "phrase", value: "secret paths", weight: 6 },
{ type: "phrase", value: "release broker", weight: 4 },
],
examples: ["what are the three secret paths?", "proxy vs release?"],
},
Comment on lines +714 to +739

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

1. Overconfident generic intents 🐞 Bug ≡ Correctness

The new intent patterns include very generic phrases (e.g., "components", "three ways") that are
matched via substring and can yield confidence=1.0 with only a single hit, causing incorrect intent
routing and overly confident answers for minimally-related queries.
Agent Prompt
### Issue description
New intent patterns for `system_architecture` and `three_secret_paths` include extremely generic phrases (e.g., `components`, `three ways`). Because phrase matching is substring-based and the engine’s confidence formula scales directly with raw pattern weight, these generic matches can produce **confidence=1.0** and route to the wrong intent.

### Issue Context
- `phrase` patterns match via `text.includes(...)`.
- Classification `score` is the sum of matched pattern weights.
- Engine confidence is `min(1, patternScore*0.5 + kbConfidence*0.4 + audienceBonus)`; with KB confidence ~0.96–0.97, even a single low-signal match can clamp to 1.

### Fix Focus Areas
- packages/chatbot/src/intents.ts[714-739]

### Suggested fix
- Remove or replace overly generic patterns:
  - Drop `{ type: "phrase", value: "components", ... }`.
  - Drop `{ type: "phrase", value: "three ways", ... }`.
- Prefer more specific phrases/regex that encode Blindfold context, e.g.:
  - `regex: "\\b(blindfold|tdx|enclave)\\b.*\\b(architecture|system design|components)\\b"`
  - `regex: "\\bthree\\b.*\\b(secret paths|sealed secret|proxy vs release|forward vs release)\\b"`
- If you want to keep a “components” trigger, make it contextual (e.g., `"blindfold components"`) and/or reduce weight so it can’t overwhelm unrelated intents.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

{
intent: "signup_vs_login",
patterns: [
Expand Down
2 changes: 2 additions & 0 deletions packages/chatbot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export type Intent =
| "signup_self_serve"
| "install_from_npm"
| "signup_vs_login"
| "system_architecture"
| "three_secret_paths"
| "one_line_change"
| "is_production_ready"
// Concepts
Expand Down
Loading