Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9b986d7
V48 Gate 3 (impl-only): Tool log titles use tool name
geraldarthurdavis Jul 20, 2026
7437a21
V48 Gate 3 (impl-only): Fix tool-name comment parse
geraldarthurdavis Jul 20, 2026
cb438b1
V48 Gate 4 (spec-impl): Admit packs + absolutes
geraldarthurdavis Jul 20, 2026
3d7362b
V48 Gate 4 (impl-only): Serve pitch deck as PDF
geraldarthurdavis Jul 20, 2026
0a84325
V48 Gate 4 (impl-only): Add pitch deck PDF asset
geraldarthurdavis Jul 20, 2026
5ad2310
V48 Gate 4 (impl-only): Stop synthesize remount
geraldarthurdavis Jul 20, 2026
cbb8f03
V48 Gate 4 (impl-only): Flatten packs absolutes
geraldarthurdavis Jul 20, 2026
e7575e3
V48 Gate 4 (impl-only): Gate PR title abbr law
geraldarthurdavis Jul 20, 2026
581b363
V48 Gate 4 (spec-only): Record e359 deposit success
geraldarthurdavis Jul 20, 2026
11cc008
V48 Gate 4 (impl-only): Refresh MCP OpenAPI docs
geraldarthurdavis Jul 20, 2026
752dee1
V48 Gate 4 (impl-only): Kind BTD reload patch
geraldarthurdavis Jul 20, 2026
769c7af
V48 Gate 4 (impl-only): Retry options hydrate
geraldarthurdavis Jul 20, 2026
0d7f7b7
V48 Gate 4 (impl-only): Fix deposit options race
geraldarthurdavis Jul 20, 2026
fa11cf0
V48 Gate 4 (spec-only): Doc deposit close signals
geraldarthurdavis Jul 20, 2026
9fa3a39
V48 Gate 4 (impl-only): AssetPack mark + Code/Coin
geraldarthurdavis Jul 20, 2026
18ce698
V48 Gate 4 (impl-only): Track ETH and SOL logo assets
geraldarthurdavis Jul 20, 2026
328e7fb
V48 Gate 4 (impl-only): Enlarge Code exchange marks
geraldarthurdavis Jul 20, 2026
3aa3c75
V48 Gate 4 (impl-only): Grow Code marks without shrinking coin
geraldarthurdavis Jul 20, 2026
34ee36a
V48 Gate 4 (spec-only): Clarify deposit vs shared
geraldarthurdavis Jul 20, 2026
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
Binary file added .bd/the-pitch.pdf
Binary file not shown.
11 changes: 11 additions & 0 deletions .docs/ASSET_PACKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,17 @@ Presentation envelope for UI selection:

Plus `finish:completion` (cleanup posture: Host dispose owned by **dispatch** after Finish).

**Critical distinction — Finish store ≠ product close (do not regress):**

| Layer | Scope | What happens | Stream / UI meaning |
| --- | --- | --- | --- |
| **SDIVF Finish** | Shared substrate (deposit *and* read synth) | Agents store selection envelope + `finish/completion` on the execution tree | Telemetry may show Finish / READY TO FINISH; **not** product-ready option cards |
| **Stream type inference** | **Shared** `ExecutionStreamAdapter` | Must not map store `key=completion` → terminal `completion` | Avoids early tail close for all synth pipelines |
| **Deposit dispatch close** | **Deposit only** (`dispatch-deposit-synthesis`) | Builds `depositOptionSynthesis`, **`finalizeExecutionRow`**, **then** SSE `completion` with `depositOptionsReady` + envelope | **Only then** may `/deposits` hydrate option cards |
| **Read dispatch close** | Read (mirror when implemented) | Same pattern with read envelope — do not assume deposit code covers it | `/reads` option hydrate |

Never map execution **store** keys named `completion` (e.g. `finish`/`completion`) to stream type `completion` — that closes the client tail and hydrates before the row write (deposit false “options not found”). Terminal product completion is **route-owned** `emitEvent(..., 'completion')` after finalize, or store namespace `final` only. Deposit hydrate order: row/event payload first; history GET retry is fallback. Full map: `apps/uapi/components/deposits/README.md` § Product terminal vs stream telemetry.

### 8.4 What is ultimately stored / shipped / journaled

| Layer | What |
Expand Down
25 changes: 25 additions & 0 deletions .docs/BITCODE_EXECUTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,28 @@ Operators should be able to:
- Replace pre-Finish labels with Finish and delivery-mechanism labels.
- Keep computer-use hidden unless the server admits it internally for Read measurement.
- Ensure all execution UI reads from the same Exchange activity model as `/packs`.

## Stream telemetry vs product terminal (synthesis runs)

Pipeline SSE is **progress telemetry**, not the product close signal by itself.

| Concern | Shared vs product-specific |
| --- | --- |
| SDIVF Finish stores (`finish/completion`) | Shared substrate (deposit + read) |
| `ExecutionStreamAdapter` not mapping `key=completion` → terminal | Shared stream law |
| Persist envelope + emit product `completion` | **Per product route** (deposit: `depositOptionSynthesis`; read: mirror when wired) |
| Option-card hydrate | **Per experience** (`/deposits` today; `/reads` when parity lands) |

1. **In-band Finish** — SDIVF may store `finish/completion` while the host run is
still owned by the route dispatcher. Those stores must stream as ordinary
status/progress events, **not** as terminal `completion`.
2. **Product terminal (deposit today)** — After
`dispatch-deposit-synthesis` persists `depositOptionSynthesis`, it emits
`completion` with `depositOptionsReady: true` + envelope. That is when
`/deposits` may treat the run as closed for option cards.
3. **Hydrate order (deposit)** — Prefer `executions.output` or the product
completion payload; history GET retry is fallback only. See deposits README
and `ASSET_PACKS.md` §8.3.

**Deposit regress symptom:** Finish / READY TO FINISH in the log, then false
“Synthesized options were not found” while the row already has options.
6 changes: 4 additions & 2 deletions .github/workflows/bitcode-gate-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ jobs:
if [[ "$PR_BASE_REF" == version/* && "$PR_HEAD_REF" =~ ^v([0-9]+)/gate-([0-9]+)- ]]; then
expected_version="V${BASH_REMATCH[1]}"
expected_gate="${BASH_REMATCH[2]}"
title_re="^${expected_version}[[:space:]]+Gate[[:space:]]+${expected_gate}([[:space:]]\((specification-only|implementation-only|specification-implementation)\))?:[[:space:]].+"
# AGENTS / SPECIFYING §2.8: abbreviated (spec-only|impl-only|spec-impl)
# only. Expanded forms are illegal in subjects — do not re-accept them.
title_re="^${expected_version}[[:space:]]+Gate[[:space:]]+${expected_gate}([[:space:]]\((spec-only|impl-only|spec-impl)\))?:[[:space:]].+"
if [[ ! "$PR_TITLE" =~ $title_re ]]; then
echo "Gate pull request titles must begin with: ${expected_version} Gate ${expected_gate}: or ${expected_version} Gate ${expected_gate} (specification-only|implementation-only|specification-implementation):"
echo "Gate pull request titles must begin with: ${expected_version} Gate ${expected_gate}: or ${expected_version} Gate ${expected_gate} (spec-only|impl-only|spec-impl):"
echo "Observed: ${PR_TITLE}"
exit 1
fi
Expand Down
34 changes: 34 additions & 0 deletions .qa/BITCODE_V48_QA.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,40 @@ with rebuild-alone canon in `BITCODE_SPEC_V48.md` §G3-1…G3-15. Optional live
smoke remains in the Gate 3 runbook §6; it does not block version-branch merge
when CI is green.

**Gate 4 open** on `v48/gate-4-depositor-packs-finalization`: depositor website
completion (batch admit → `/packs`, deposit detail reload, absolute
measurements on packs, patchfile download on deposit review only). Live defect
class (2026-07-20): selecting 2 options produced 1 packs row; packs detail
showed session `Candidate count` / `Admitted count` / admission-report root as
fake measurements; reloading synthesis run
`e2f1f110-b6b6-43ce-a7b9-a3b80bcf891a` dropped options/logs.

**Live monitor (Gate 4 close):** deposit synthesis run
`e359b78a-7c73-49bb-a54b-35e32dd1ef94` on staging-testnet
(`tkpyosihuouusyaxtbau`).

- **Terminal:** `completed` (~490s sandbox host, repo
`advancedengineeredsoftware/Bitcode` @ `version/v48`).
- **Options:** 3 presentable packs, each with **8 absolute measurements** +
contents (path-op): Documentation Capability, Proof Artifacts Operations,
Application Manifest Patterns.
- **Next operator step:** select all 3 → confirm deposit → expect **3**
`/packs` depository rows with absolute chips only (no session candidate
counts). Reload
`/deposits?transactionId=e359b78a-7c73-49bb-a54b-35e32dd1ef94` → options +
telemetry rehydrate.

### Gate 4 follow-up fixes (post-e359 screenshots)

- DIV header badge: phase-gated **DIV pass N** (not bare ITER on Setup/Finish).
- Packs **Kind** column = capability/pattern/operations; **BTD** column =
unsettled absolute-derived estimate (not function-count).
- Measurement detail rows carry buyer descriptors.
- Patch download = `bitcode.artifact.patch` path-op-json (`.path-op.json`).
- Pipeline master excludes admission receipts; openRunDetail redirects admit
rows to `synthesisRunId` so logs/options remain on the synthesis run.
- Policy UI: admitted packs show admitted + soft-warning copy, not active block.


- Version: `V48`
- Active canon during QA: `V47`
Expand Down
71 changes: 71 additions & 0 deletions .specifications/BITCODE_SPEC_V48_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -1206,6 +1206,77 @@ option projection); real in-sandbox execution is verified against deployed sandb

These ops items do **not** block Gate 3 PR merge into `version/v48` once CI is green.

## V48 Gate 4 open: Depositor website completion + Packs absolute measurements

**Branch:** `v48/gate-4-depositor-packs-finalization`
**Canon surface:** Gate 4 completion artifact law in DELTA + depositor website
completion proofs; this NOTES entry records live finishing work after Gate 3
deposit SDIVF closed.

### Gate 4 product objectives (binding for finish)

1. **Batch admit reliability** — every selected presentable option that the
depositor confirms becomes one `admitted-to-depository` ledger row and one
`/packs` network `depository-assetpack` row. Soft compensation/ROI
incompleteness must not silently drop confirmed deposits; critical source
policy remains hard-block.
2. **Per-pack admission payload** — never embed the full session admission
report (`candidateCount`, `admittedCount`, report roots) as pack
measurements. Each admitted pack carries **that option's absolute
measurements** + identity roots only.
3. **Deposit detail reload** — revisiting a synthesis run
(`transactionId=<runId>`) rehydrates options, telemetry history, and
admission state from the execution row + ledger (not only live SSE).
4. **Depositor review completeness** — option cards expose full absolutes,
roots, contents summary, and **Download patchfile** (path-op JSON
descriptor). "Admitted" UI requires receipt state
`admitted-to-depository`, not merely a review decision label.
5. **Packs source-safety** — patch/fileChanges never projected on `/packs`
network detail. Patch is visible only to the depositor on `/deposits`
(owner) or, later, entitled buyers after settle (Gate 5). Absolute
measurement chips + detail are the commercial measurement surface on
`/packs`.
6. **Then Gate 5** — Read experience parity with deposit, neediness as the
critical measurement difference.

### Closure checklist

- [ ] Admit N selected → N packs rows with absolute chips
- [ ] Reload deposit synthesis detail → options + logs + admitted cards
- [ ] Packs detail never shows candidate/admitted session counts as measurements
- [ ] Unit tests: admission soft-block override, pack measurement projection,
admission activity draft
- [ ] Gate 4 checker / depositor-website-completion artifact green

## V48 Gate 5 plan: Reader website completion (neediness delta)

**After Gate 4 packs/deposit solid.** Branch target:
`v48/gate-5-reader-website-completion`.

### Deposit ↔ Read parity map

| Concern | Deposit | Read (delta) |
| --- | --- | --- |
| SDIVF product package | `syntheses/deposit` | `syntheses/read` |
| Steering | Obfuscations + path pickers | Need text + Relevant/Irrelevant paths |
| Measurements | **absolutes only** | **absolutes + needinesses (*-fit)** |
| Option review | Select → batch admit | Select → settle quote |
| Finish envelope | presentable deposit options | presentable read options |
| Next pipeline | (none — Depository) | `ExecutionPipelineSimpleSettleAssetPack` |
| Packs projection | depository-assetpack + absolutes | settled-assetpack + absolutes + needinesses |

### Gate 5 objectives

1. Cold reload of read synthesis run rehydrates Need, options, telemetry (mirror
deposit hydrate).
2. Option cards show neediness catalog + download path-op patchfile for the
reader reviewing unpaid options (source-safe descriptor only until buy).
3. Settle path journals one packs row per settled pack with neediness + absolute
chips; no session aggregate counts as measurements.
4. Source-safety: patch never on `/packs` until rights transfer / delivery
entitlement.
5. Five-step session law from DELTA Gate 5 remains binding.

## Non-goals during V48 opening

- Do not implement V48 product behavior from this notes-only opening.
Expand Down
8 changes: 4 additions & 4 deletions apps/mcp/docs/openapi/bitcode-mcp-openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"info": {
"title": "Bitcode MCP Server API",
"version": "1.0.0",
"description": "\n# Bitcode MCP Server API\n\nThe Model Context Protocol (MCP) server exposing Bitcode’s technical knowledge exchange via standardized tools, resources, and prompts.\n\n## Features\n\n- Tools interface for AssetPack execution and optional Shippable delivery\n- Real‑time streaming (WebSocket)\n- Multi‑modal attachments (Figma, documents, images, audio, video)\n- BTC fee posture plus measured non-fungible $BTD AssetPack amount\n\n## Getting Started\n\n1. **Get API Key** in your Bitcode account\n2. **Connect an MCP Client** (e.g., Claude Desktop)\n3. **Call a Tool**: \n - \n name: `bitcode://pipelines/asset-pack/execute`\n \n## Support\n\n- **Documentation**: https://docs.bitcode.dev/mcp\n- **Community**: https://discord.gg/bitcode-mcp\n- **Support**: mcp-support@bitcode.dev\n ",
"description": "\n# Bitcode MCP Server API\n\nThe Model Context Protocol (MCP) server exposing Bitcode’s technical knowledge exchange via standardized tools, resources, and prompts.\n\n## Features\n\n- Tools interface for AssetPack execution and optional settle delivery\n- Real‑time streaming (WebSocket)\n- Multi‑modal attachments (Figma, documents, images, audio, video)\n- BTC fee posture plus measured non-fungible $BTD AssetPack amount\n\n## Getting Started\n\n1. **Get API Key** in your Bitcode account\n2. **Connect an MCP Client** (e.g., Claude Desktop)\n3. **Call a Tool**: \n - \n name: `bitcode://pipelines/asset-pack/execute`\n \n## Support\n\n- **Documentation**: https://docs.bitcode.dev/mcp\n- **Community**: https://discord.gg/bitcode-mcp\n- **Support**: mcp-support@bitcode.dev\n ",
"contact": {
"name": "Bitcode API Support",
"url": "https://bitcode.dev/support",
Expand Down Expand Up @@ -195,7 +195,7 @@
"url": {
"type": "string",
"format": "uri",
"description": "External URL for the PR-backed Shippable",
"description": "External URL for the settle PR delivery",
"example": "https://github.com/bitcode-labs/webapp/pull/123"
},
"content": {
Expand Down Expand Up @@ -231,7 +231,7 @@
"enum": [
"pull_request"
],
"description": "V26 Shippable type to create"
"description": "Delivery template type to create"
},
"attachments": {
"type": "array",
Expand Down Expand Up @@ -293,7 +293,7 @@
"items": {
"$ref": "#/components/schemas/AssetPack"
},
"description": "Generated AssetPack results and PR Shippables"
"description": "Generated AssetPack results and settle PR deliveries"
},
"metrics": {
"$ref": "#/components/schemas/ExecutionMetrics"
Expand Down
12 changes: 6 additions & 6 deletions apps/uapi/app/api/deck/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* Serve the pitch deck from the monorepo SoT (`.bd/the-pitch.key`).
* Serve the pitch deck PDF from the monorepo SoT (`.bd/the-pitch.pdf`).
* Does not copy into `public/` — one source of truth on disk.
* (Keynote source remains at `.bd/the-pitch.key` for authoring only.)
*/

import { createReadStream, existsSync } from 'node:fs';
Expand All @@ -10,10 +11,10 @@ import { Readable } from 'node:stream';
export const runtime = 'nodejs';
export const dynamic = 'force-dynamic';

const DECK_RELATIVE = path.join('.bd', 'the-pitch.key');
const DECK_FILENAME = 'the-pitch.key';
const DECK_RELATIVE = path.join('.bd', 'the-pitch.pdf');
const DECK_FILENAME = 'the-pitch.pdf';

/** Resolve monorepo-root `.bd/the-pitch.key` from app or repo cwd. */
/** Resolve monorepo-root `.bd/the-pitch.pdf` from app or repo cwd. */
function resolveDeckPath(): string | null {
const cwd = process.cwd();
const candidates = [
Expand Down Expand Up @@ -42,8 +43,7 @@ export async function GET() {
return new Response(webStream, {
status: 200,
headers: {
// Keynote packages are zip-based; keep generic so clients download cleanly.
'Content-Type': 'application/octet-stream',
'Content-Type': 'application/pdf',
'Content-Disposition': `inline; filename="${DECK_FILENAME}"`,
'Cache-Control': 'public, max-age=300',
'X-Bitcode-Deck-Source': DECK_RELATIVE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -622,11 +622,20 @@ export async function runDepositOptionSynthesis(
duration_ms: durationMs,
});

// Terminal product signal AFTER row output is written. Carry the selection
// envelope on the event so the UI can render options from the same signal
// that closes the stream — no second GET race with finish/completion stores.
await ExecutionStreamAdapter.emitEvent(execution.id, 'completion' as never, {
message: isBudgetPartial
? `AssetPacksSynthesis partial: recovered ${synthesis.optionCount} measured options after host budget (Validation incomplete).`
: `AssetPacksSynthesis completed with ${synthesis.optionCount} measured options.`,
runId,
productTerminal: true,
depositOptionsReady: true,
optionCount: synthesis.optionCount,
depositOptionSynthesis: synthesis,
reviewProjections,
partial: isBudgetPartial,
});

bitcodeServerTelemetry('info', 'deposit-synthesize-options', 'synthesized', {
Expand Down
91 changes: 83 additions & 8 deletions apps/uapi/app/api/packs/activity/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,90 @@ async function readGlobalDepositoryRecords(limit: number): Promise<BitcodeActivi
.eq('context->>admissionState', 'admitted-to-depository')
.order('created_at', { ascending: false })
.limit(Math.min(limit, 50));
return (data || []).map((row: Record<string, unknown>) =>
buildBitcodeActivityRecordFromExecutionHistory({
return (data || []).map((row: Record<string, unknown>) => {
const output = (row.output as Record<string, unknown> | null) || {};
const context = (row.context as Record<string, unknown> | null) || {};
const assetPackTitle =
(typeof output.assetPackTitle === 'string' && output.assetPackTitle) ||
(typeof context.assetPackTitle === 'string' && context.assetPackTitle) ||
null;
const assetPackKind =
(typeof output.assetPackKind === 'string' && output.assetPackKind) ||
(typeof output.optionKind === 'string' && output.optionKind) ||
(typeof output.kind === 'string' && output.kind) ||
(typeof context.assetPackKind === 'string' && context.assetPackKind) ||
(typeof context.optionKind === 'string' && context.optionKind) ||
null;
const estimatedBtd =
typeof output.estimatedBtd === 'number'
? output.estimatedBtd
: typeof context.estimatedBtd === 'number'
? context.estimatedBtd
: null;
const estimatedBtdCells =
typeof output.estimatedBtdCells === 'number'
? output.estimatedBtdCells
: typeof context.estimatedBtdCells === 'number'
? context.estimatedBtdCells
: null;
// Flatten per-pack absolute measurements onto context+output so pack
// activity projection prefers catalog chips over any residual session
// aggregates still present on older admission rows.
const measurements =
(Array.isArray(output.measurements) && output.measurements) ||
(Array.isArray(output.absolutes) && output.absolutes) ||
(Array.isArray(context.measurements) && context.measurements) ||
[];
const summary =
typeof output.summary === 'string'
? String(output.summary)
: assetPackTitle
? `Admitted ${assetPackTitle} to the Depository.`
: null;
return buildBitcodeActivityRecordFromExecutionHistory({
...row,
summary:
typeof (row.output as Record<string, unknown> | null)?.summary === 'string'
? String((row.output as Record<string, unknown>).summary)
: null,
} as never),
);
summary,
context: {
...context,
source: 'deposit-option-review-admission',
admissionState: 'admitted-to-depository',
packActivityType: 'depository-assetpack',
activityType: 'depository-assetpack',
assetPackTitle,
assetPackKind,
optionKind: assetPackKind,
kind: assetPackKind,
optionId: context.optionId || output.optionId || null,
depositoryAssetPackId:
context.depositoryAssetPackId || output.depositoryAssetPackId || null,
compensationState:
context.compensationState || output.compensationState || null,
measurementRoot: context.measurementRoot || output.measurementRoot || null,
estimatedBtd,
estimatedBtdCells,
btdHonesty: 'estimate',
// Source-safe absolute catalog only — never patch / fileChanges.
measurements,
},
output: {
...output,
packActivityType: 'depository-assetpack',
assetPackTitle,
assetPackKind,
optionKind: assetPackKind,
kind: assetPackKind,
estimatedBtd,
estimatedBtdCells,
btdHonesty: 'estimate',
measurements,
// Strip session-aggregate noise if present on legacy rows.
candidateCount: undefined,
admittedCount: undefined,
optionCount: undefined,
depositAdmission: undefined,
},
} as never);
});
} catch {
return [];
}
Expand Down
Loading
Loading