Skip to content

Commit d026802

Browse files
Define wallet signer BTC operations
Close V29 Gate 3 with BTD-owned BTC fee quote lifecycle, signer-session recovery, blocked-readiness receipts, and operation posture. Expose operation posture through the BTC fee route and add a source-safe Terminal Wallet/BTC detail section with focused package, route, UI, spec, and gate-quality coverage.
1 parent 4fc0a83 commit d026802

21 files changed

Lines changed: 1664 additions & 12 deletions

.github/workflows/bitcode-gate-quality.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ jobs:
4747
node scripts/check-bitcode-canonical-inputs.mjs --current-target V28
4848
node scripts/check-v29-gate1-objectives-and-gating.mjs --skip-branch-check
4949
node scripts/check-v29-gate2-terminal-transaction-read-models.mjs --skip-branch-check
50+
node scripts/check-v29-gate3-wallet-signer-btc-operations.mjs --skip-branch-check
5051
5152
- name: Validate source casing and imports
5253
run: |
@@ -62,6 +63,7 @@ jobs:
6263
- name: Test gate packages
6364
run: |
6465
pnpm --filter @bitcode/btd test
66+
pnpm --filter @bitcode/btd test -- --runTestsByPath __tests__/btc-fee-operation.test.ts
6567
pnpm --filter @bitcode/pipeline-asset-pack exec jest --config jest.config.cjs --passWithNoTests --forceExit
6668
pnpm --filter @bitcode/pipeline-hosts exec jest --config jest.config.cjs --passWithNoTests --forceExit
6769
@@ -74,6 +76,7 @@ jobs:
7476
tests/terminalDepositReadWorkbench.test.ts \
7577
tests/terminalTransactionQuery.test.ts \
7678
tests/terminalTransactionReadModel.test.ts \
79+
tests/terminalWalletBtcOperation.test.ts \
7780
tests/pipelineExecutionLogHeader.test.tsx \
7881
--runInBand
7982

BITCODE_SPEC_V29.md

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ The V29 domain model extends V28 operationally:
157157
- `FindingFitsResult`: all threshold-passing fit deposits, search roots, ranking roots, blockers, no-worthy-fit posture, and selected synthesis context.
158158
- `AssetPackPreview`: source-safe measurements, quality score, disclosure policy, access policy, fee quote, range projection, and protected-source lock.
159159
- `SettlementUnlock`: BTC fee proof, BTD range/read-license/right transfer, paid disclosure decision, delivery admission, and reconciliation state.
160+
- `BtcFeeQuote`: deterministic BTC fee quote with quote root, measurement root, purpose, network, sats, pricing version, expiration, and lifecycle state.
161+
- `WalletSignerSessionRecovery`: signer-session posture proving whether the Reader wallet can sign a PSBT without server custody.
162+
- `BtcFeeOperationPosture`: operational state over quote, signer, PSBT, broadcast, finality, replacement, reorg, failure, and blocked readiness.
160163
- `TerminalTransaction`: URL-addressable activity combining execution, pipeline, agent, tool, prompt, ledger, database, delivery, and proof state.
161164
- `TerminalTransactionReadModel`: typed operator projection of a selected `TerminalTransaction`, including route state, active detail section, low-detail summary, section availability, expandable audit posture, and source-safe raw-payload boundary.
162165

@@ -191,14 +194,37 @@ The Terminal transaction read model must contain:
191194
- selected transaction identity, activity type, lens, status, participant, repository, branch, timing, and proof posture;
192195
- route state with canonical hrefs for each section and with the former `runId` carrier removed on write;
193196
- low-detail default summary, metrics, and posture chips sufficient for ordinary operation without opening raw JSON;
194-
- section read models for Shippables, identity, closure, proofs, history, journal, activity stream, and console;
197+
- section read models for Shippables, identity, Wallet/BTC, closure, proofs, history, journal, activity stream, and console;
195198
- explicit section availability: available, empty, or blocked with an operator-readable reason;
196199
- expandable detail metadata preserving row counts, metric counts, payload availability, and target DOM section ids;
197200
- a source-safe disclosure boundary: protected AssetPack source is never displayed before settlement, and raw payloads remain audit detail rather than the default operator contract.
198201

199202
The model is deterministic from execution history, detail readback, route query state, and data mode.
200203
It must tolerate partial live readback by preserving a fallback selected-run projection while naming empty or blocked sections.
201204

205+
## V29 Wallet/BTC operation canon
206+
207+
Wallet and BTC fee state is an ordinary Terminal transaction surface, not an opaque settlement footnote.
208+
The canonical wallet/BTC operation model is owned by `packages/btd` and projected by Terminal.
209+
210+
The operation model must contain:
211+
212+
- quote lifecycle: quoted, accepted, expired, superseded, and failed;
213+
- deterministic quote root over quote id, purpose, network, sats, measurement root, issue time, and expiration;
214+
- signer recovery: missing, prepared authorization required, stored authorization requiring live reconnect, expired, revoked, failed, network mismatch, capability missing, server-custody rejected, or live authorized;
215+
- PSBT handoff: accepted quote prepares a PSBT; the wallet signs; the signed PSBT broadcasts;
216+
- finality states: prepared, signed, broadcast, confirmed, replaced, reorged, and failed;
217+
- blocked-readiness receipts naming the blocker id, summary, required action, quote id, wallet session id, receipt id, and no-server-custody posture;
218+
- Terminal read rows and metrics for state, network, sats, confirmations, quote root, wallet session, payer wallet, PSBT handoff, txid, server custody, and next action.
219+
220+
No server component may custody the Reader private key.
221+
Server-side routes may prepare receipts, validate proofs, serialize quote/posture evidence, and persist registry rows only when explicitly requested.
222+
They must not claim signature, broadcast, finality, settlement unlock, or rights transfer without matching receipt and readback evidence.
223+
224+
The Terminal Wallet/BTC section is source-safe before settlement.
225+
It may reveal quote roots, state labels, txids, and readiness blockers.
226+
It may not expose protected AssetPack source, wallet secrets, provider tokens, or private signing material.
227+
202228
## V29 canonical subsystem surfaces
203229

204230
### Depositing and asset supply
@@ -265,10 +291,10 @@ It must tolerate partial live readback by preserving a fallback selected-run pro
265291

266292
- Current canonical objects and emitted artifacts: BTC fee quote, PSBT, payment observation, settlement unlock, BTD range, source-to-shares, journal entry, ledger anchor, reconciliation report.
267293
- Current algorithms and derivation rules: Share-to-Fee pricing is deterministic from measurement weights and measurement volume; BTC fee payment gates protected-source unlock and read-license/right transfer.
268-
- Current invariants and fail-closed conditions: settlement conservation drift, missing payment proof, stale fee quote, reorg, replacement, broadcast failure, or custody ambiguity blocks finality.
269-
- Current proof obligations: quote root, PSBT state, txid or blocked-readiness receipt, ledger anchor, source-to-shares report, and reconciliation result.
270-
- Current source-bearing implementation basis: `packages/btd` fee/range/journal/reconciliation primitives, UAPI settlement routes, Terminal payment UI, and Supabase projections.
271-
- Current validating commands and parity basis: BTD tests, settlement route tests, staging ledger/database readback, and V29 gate checks.
294+
- Current invariants and fail-closed conditions: settlement conservation drift, missing payment proof, stale fee quote, unaccepted quote, missing signer capability, reorg, replacement, broadcast failure, or custody ambiguity blocks finality.
295+
- Current proof obligations: quote root, signer recovery state, PSBT state, txid or blocked-readiness receipt, ledger anchor, source-to-shares report, and reconciliation result.
296+
- Current source-bearing implementation basis: `packages/btd` fee/range/journal/reconciliation primitives, UAPI settlement routes, Terminal Wallet/BTC section, and Supabase projections.
297+
- Current validating commands and parity basis: BTD tests, settlement route tests, Terminal wallet/BTC tests, staging ledger/database readback, and V29 gate checks.
272298
- Current accepted boundaries: value-bearing mainnet stays outside V29 unless separately approved.
273299

274300
### Proof contract, witnesses, and replay

BITCODE_SPEC_V29_DELTA.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ Closure acceptance:
9999

100100
Gate 3 owns wallet connection depth, signer-session recovery, BTC fee quote lifecycle, PSBT handoff, broadcast/finality/replacement/reorg/failure states, blocked-readiness receipts, and no server-custody posture.
101101

102+
Closure acceptance:
103+
104+
- `packages/btd` defines `BtcFeeQuote`, `WalletSignerSessionRecovery`, `BtcFeeBlockedReadinessReceipt`, and `BtcFeeOperationPosture`.
105+
- BTC fee quotes have deterministic quote roots, accepted/expired/superseded/failed lifecycle transitions, BTC-only fee asset, and measurement-root pricing posture.
106+
- Signer recovery distinguishes missing, prepared, stored reconnect, expired, revoked, failed, network mismatch, capability missing, server-custody rejected, and live authorized states.
107+
- BTC fee operation posture maps accepted quote, PSBT-ready, signed, broadcast, confirmed, replaced, reorged, failed, and blocked states into next actions and settlement booleans.
108+
- The BTC fee API serializes operation posture and accepts JSON-safe quote carriers without mutating registry rows unless explicitly requested.
109+
- Terminal adds a Wallet/BTC transaction detail section with source-safe metrics, rows, blockers, quote root, signer session, PSBT handoff, txid, finality, and server-custody posture.
110+
- Gate-quality CI runs the Gate 3 checker plus BTD operation and Terminal Wallet/BTC tests.
111+
102112
### Gate 4: Reading Transaction Recovery And Pipeline Observability
103113

104114
Gate 4 owns deep Terminal visibility over `ReadNeedComprehensionSynthesis` and `ReadFitsFindingSynthesis`, including execution, phase, PTRR agent, PTRR step, ThricifiedGeneration, prompt, tool, output, and typed parse telemetry.

BITCODE_SPEC_V29_NOTES.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ For a simplified reading of V29:
5656

5757
3. **Gate 3: Wallet Signer Session And BTC Fee Operations**
5858
- Deepen signer-session recovery, BTC fee quote, PSBT handoff, broadcast, replacement, reorg, failure, and blocked-readiness states.
59+
- Acceptance detail: BTC quote lifecycle and signer recovery are package-owned primitives; API responses expose JSON-safe operation posture; Terminal exposes Wallet/BTC as a route-owned transaction detail section with blockers before raw payloads.
5960

6061
4. **Gate 4: Reading Transaction Recovery And Pipeline Observability**
6162
- Make `ReadNeedComprehensionSynthesis` and `ReadFitsFindingSynthesis` execution telemetry fully readable in Terminal at execution, phase, PTRR agent, PTRR step, ThricifiedGeneration, prompt, tool, raw output, and parsed output levels.
@@ -106,6 +107,19 @@ The low-detail default should answer:
106107

107108
The detailed view may still carry raw payload accordions for audit, but the ordinary collapsed view must be typed and readable.
108109

110+
## Gate 3 working notes
111+
112+
Gate 3 makes wallet and BTC fee operation readable and typed before the later settlement-repair gate.
113+
114+
Accepted Gate 3 posture:
115+
116+
- BTC fee quote lifecycle and quote-root derivation live in `packages/btd`.
117+
- Signer-session recovery is explicit and never implies server custody.
118+
- PSBT, signed, broadcast, confirmed, replaced, reorged, failed, and blocked readiness are represented as operation posture, not prose-only route errors.
119+
- The BTC fee API can serialize the operation posture and normalize JSON-safe quote carriers.
120+
- Terminal has a Wallet/BTC detail section so fee readiness is visible before raw ledger payload inspection.
121+
- Gate 3 does not implement settlement reconciliation repair; Gate 6 owns drift repair and ledger/database reconciliation action depth.
122+
109123
## Later-version boundaries
110124

111125
- V30 remains reserved for Protocol/BTD hardening that is not necessary to close Terminal transaction depth.

BITCODE_SPEC_V29_PARITY_MATRIX.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ No `_legacy/` source is active source truth.
5050
| Draft family and branch posture | Gate 1 | `BITCODE_SPEC_V29.md`, DELTA, NOTES, PARITY, `BITCODE_SPEC.txt`, branch `v29/gate-1-objectives-and-gating` | drafted | V29 family validates in draft mode over active V28 and `check:v29-gate1` passes. |
5151
| Workflow retargeting | Gate 1 | `.github/workflows/bitcode-gate-quality.yml`, `.github/workflows/bitcode-canon-quality.yml` | drafted | CI checks V28 active / V29 draft posture instead of stale V27/V28 posture. |
5252
| Terminal transaction read models | Gate 2 | `uapi/app/terminal/terminal-transaction-read-model.ts`, `uapi/app/terminal/terminal-transaction-query.ts`, `TerminalTransactionWorkspace.tsx`, `TerminalTransactionDetailSurface.tsx`, UAPI tests, Gate 2 checker | drafted | Terminal transaction state is URL-addressable, recoverable, typed, low-detail by default, and expandable without raw JSON as the ordinary operator contract. |
53-
| Wallet signer/BTC operations | Gate 3 | `packages/btd`, wallet API, BTC fee route, Terminal wallet UI | pending | Signer session, PSBT, broadcast/finality/reorg/replacement/failure states are ordinary Terminal states. |
53+
| Wallet signer/BTC operations | Gate 3 | `packages/btd/src/btc-fee-operation.ts`, BTC fee route, Terminal Wallet/BTC detail section, BTD and UAPI tests, Gate 3 checker | drafted | Signer session, PSBT, broadcast/finality/reorg/replacement/failure states are ordinary Terminal states. |
5454
| Reading pipeline observability | Gate 4 | `packages/pipelines/asset-pack`, `packages/pipeline-hosts`, Terminal stream components | pending | Pipeline/phase/PTRR/ThricifiedGeneration/tool/prompt telemetry is complete and readable. |
5555
| AssetPack disclosure rights | Gate 5 | BTD access primitives, AssetPack preview UI, disclosure policy tests | pending | Source-safe preview and paid unlock are proven without source leakage. |
5656
| Settlement reconciliation repair | Gate 6 | BTD journal/reconciliation, Supabase readback, Terminal repair UI | pending | Ledger, database, and metaphysical state drift is visible and repairable. |
@@ -68,6 +68,7 @@ No `_legacy/` source is active source truth.
6868
| Spec-family shape | V29 SPEC, DELTA, NOTES, and PARITY satisfy the full spec-family checker | drafted |
6969
| Gate 1 script | `pnpm run check:v29-gate1` fails closed on stale posture or missing gates | drafted |
7070
| Gate 2 read model | `pnpm run check:v29-gate2` proves typed route-owned Terminal transaction reading | drafted |
71+
| Gate 3 wallet/BTC operation | `pnpm run check:v29-gate3` proves quote lifecycle, signer recovery, blocked readiness, API posture, and Terminal Wallet/BTC detail | drafted |
7172
| Product implementation gates | Gates 3-9 close remaining Terminal transaction depth with tests and docs | pending |
7273
| Promotion gate | Gate 10 closes generated proof and promotion automation | pending |
7374

@@ -115,3 +116,26 @@ Gate 1 is complete when the V29 draft family validates, `check:v29-gate1` passes
115116
## Gate 2 completion condition
116117

117118
Gate 2 is complete when Terminal selected transaction state rewrites recoverable URLs, a typed read model drives detail navigation and low-detail summaries, focused tests pass, `check:v29-gate2` passes, CI invokes the checker, docs name the implemented source surfaces, and the gate branch is committed and pushed for review into `version/v29`.
119+
120+
## Gate 3 Parity
121+
122+
| Requirement | Source evidence | Current V29 judgment |
123+
| --- | --- | --- |
124+
| BTC fee quote lifecycle is package-owned | `packages/btd/src/btc-fee-operation.ts`, `packages/btd/__tests__/btc-fee-operation.test.ts` | drafted |
125+
| Signer-session recovery is explicit and no-custody | `buildWalletSignerSessionRecovery`, BTD operation tests | drafted |
126+
| Blocked-readiness receipts name blocker and repair path | `buildBtcFeeBlockedReadinessReceipt`, BTD operation tests | drafted |
127+
| Operation posture covers PSBT, broadcast, finality, replacement, reorg, failure | `buildBtcFeeOperationPosture`, BTD operation tests | drafted |
128+
| BTC fee route serializes JSON-safe operation posture | `packages/api/src/routes/btd-crypto.ts`, route typecheck, route tests | drafted |
129+
| Terminal exposes Wallet/BTC detail section | `terminal-transaction-query.ts`, `terminal-transaction-read-model.ts`, `TerminalTransactionWalletBtcCard.tsx`, `terminal-wallet-btc-operation.ts`, UAPI tests | drafted |
130+
| Gate 3 checker is wired to package scripts and CI | `scripts/check-v29-gate3-wallet-signer-btc-operations.mjs`, `package.json`, gate workflow | drafted |
131+
132+
## Gate 3 accepted boundaries
133+
134+
- Gate 3 does not implement full settlement reconciliation repair; Gate 6 owns drift repair and readback repair actions.
135+
- Gate 3 does not expose protected AssetPack source before settlement.
136+
- Gate 3 does not broadcast value-bearing mainnet transactions.
137+
- Gate 3 does not add versioned API routes or source identifiers.
138+
139+
## Gate 3 completion condition
140+
141+
Gate 3 is complete when package primitives model BTC quotes, signer recovery, operation posture, and blocked readiness; API responses serialize operation posture; Terminal has a Wallet/BTC route-owned detail section; focused package and UAPI tests pass; `check:v29-gate3` passes; CI invokes the checker and tests; docs name the implemented source surfaces; and the gate branch is committed and pushed for review into `version/v29`.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"check:v28-gate13": "node scripts/check-v28-gate13-product-closure-promotion-readiness.mjs",
4747
"check:v29-gate1": "node scripts/check-v29-gate1-objectives-and-gating.mjs",
4848
"check:v29-gate2": "node scripts/check-v29-gate2-terminal-transaction-read-models.mjs",
49+
"check:v29-gate3": "node scripts/check-v29-gate3-wallet-signer-btc-operations.mjs",
4950
"check:spec-quality": "node scripts/run-bitcode-spec-quality.mjs --mode basic",
5051
"check:spec-quality:title": "node scripts/run-bitcode-spec-quality.mjs --mode strict-from-title",
5152
"check:spec-quality:v24": "node scripts/run-bitcode-spec-quality.mjs --mode strict-version --version V24",

packages/api/src/routes/__tests__/btd-crypto.test.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,11 @@ import {
3636
buildPostBtdReadAccessRoute,
3737
buildPostBtdTerminalJournalRoute,
3838
} from '../btd-crypto';
39-
import { createBtdMeasureMintState } from '@bitcode/btd';
39+
import {
40+
advanceBtcFeeQuote,
41+
buildBtcFeeQuote,
42+
createBtdMeasureMintState,
43+
} from '@bitcode/btd';
4044

4145
const issuedAt = '2026-05-06T00:00:00.000Z';
4246

@@ -59,6 +63,23 @@ function walletSessionInput() {
5963
};
6064
}
6165

66+
function acceptedFeeQuote() {
67+
return advanceBtcFeeQuote(
68+
buildBtcFeeQuote({
69+
quoteId: 'quote-api-1',
70+
feePurpose: 'asset_pack_anchor',
71+
network: 'signet',
72+
sats: 1200n,
73+
satsPerVbyte: 4,
74+
measurementRoot: 'measurement-root-api-1',
75+
relatedAssetPackId: 'asset-pack-api-1',
76+
issuedAt,
77+
expiresAt: '2026-05-06T01:00:00.000Z',
78+
}),
79+
{ state: 'accepted' },
80+
);
81+
}
82+
6283
function mintDraftInput() {
6384
return {
6485
assetPackId: 'asset-pack-api-1',
@@ -511,6 +532,7 @@ describe('BTD crypto API builders', () => {
511532
receiptId: 'btc-fee-api-1',
512533
feePurpose: 'asset_pack_anchor',
513534
payerSession: walletSessionInput(),
535+
feeQuote: acceptedFeeQuote(),
514536
psbt: 'cHNidP8BAHECAAAAA',
515537
satsPaid: 1200n,
516538
satsPerVbyte: 4,
@@ -546,6 +568,12 @@ describe('BTD crypto API builders', () => {
546568
expect(prepared.receipt.feeAsset).toBe('BTC');
547569
expect(prepared.receipt.walletAuthorizationProof.proofKind).toBe('message_signature');
548570
expect(prepared.receipt.exchangeSequence).toBe(11n);
571+
expect(prepared.operationPosture).toMatchObject({
572+
phase: 'psbt_ready',
573+
canSignPsbt: true,
574+
noServerCustody: true,
575+
quote: { quoteId: 'quote-api-1' },
576+
});
549577
expect(prepared.terminalJournalEntry.transactionKind).toBe('btc_fee_payment');
550578
expect(confirmed.receipt.txid).toBe('btc-txid-api-1');
551579
expect(confirmed.receipt.confirmations).toBe(2);
@@ -915,6 +943,10 @@ describe('BTD crypto API builders', () => {
915943
receiptId: 'btc-fee-api-1',
916944
feePurpose: 'asset_pack_anchor',
917945
payerSession: walletSessionInput(),
946+
feeQuote: {
947+
...acceptedFeeQuote(),
948+
sats: '1200',
949+
},
918950
psbt: 'cHNidP8BAHECAAAAA',
919951
satsPaid: '1200',
920952
satsPerVbyte: 4,
@@ -933,6 +965,14 @@ describe('BTD crypto API builders', () => {
933965
expect(body.receipt.feeAsset).toBe('BTC');
934966
expect(body.receipt.serverCustody).toBe(false);
935967
expect(body.receipt.exchangeSequence).toBe('11');
968+
expect(body.operationPosture).toMatchObject({
969+
phase: 'psbt_ready',
970+
canSignPsbt: true,
971+
quote: {
972+
quoteId: 'quote-api-1',
973+
sats: '1200',
974+
},
975+
});
936976
expect(body.committed).toBe(true);
937977
expect(insertBtcFeeTransaction).toHaveBeenCalledWith(
938978
expect.objectContaining({

0 commit comments

Comments
 (0)