# WalletPress — Daily Builder Workflow

> **Status:** Canonical. Owner: WalletPress Engineering.
> **Last updated:** 2026-06-30.
> **Audience:** Every AI agent and engineer working on WalletPress. Read on session start.
> **Purpose:** The single workflow every contributor follows so nothing gets duplicated, every change has context, and the repo stays coherent day over day.

---

## TL;DR — Read this first

Every session, every agent, every engineer:

1. **Read the four canonical docs in order:** WALLETPRESS.md → ARCHITECTURE.md → SECURITY.md → AUDIT.md.
2. **Pick from the open work list** below. Don't pick from scratch — the list is the canonical "what's next."
3. **Touch only what's assigned.** If you find a related bug, log it in AUDIT.md "Known issues" and move on. Don't fix it in this PR.
4. **One logical change per PR.** Conventional commits. Tests in the same PR.
5. **Push to Talos daily** (`git push talos main`). Hydra mirrors at 4 AM.
6. **Update the docs in the same PR** if you change behavior. Docs drift is the #1 cause of agent misalignment.

---

## Source-of-truth hierarchy

If two files disagree, trust in this order:

1. **The code itself** — `git log` to see intent.
2. **AUDIT.md** — bugs and known issues.
3. **ARCHITECTURE.md** — design + roadmap.
4. **SECURITY.md** — security rules.
5. **ADDRESS_GENERATION.md** — chain truth table.
6. **BUILDER.md** (this file) — workflow.
7. **WALLETPRESS.md** — product summary.
8. **STRATEGY.md** — business plan (lowest priority — most stale).
9. **PROGRESS.md / ROADMAP.md / ROADMAP_V2.md** — historical. Aspirational. Don't trust claims; check the code.

If you find a conflict between source-of-truth files, raise it in the daily standup. Don't silently pick one.

---

## Session-start checklist (every agent, every time)

Before writing any code:

```bash
# 1. Update the working tree
cd ~/sites/walletpress
git fetch --all
git status
git log --oneline -10

# 2. Run the audit
cd backend
make check    # lint + type + test
make security # bandit + safety

# 3. Verify environment
echo "WP_ADMIN_KEY set: $([ -n "$WP_ADMIN_KEY" ] && echo yes || echo NO)"
echo "WP_VAULT_PASSWORD set: $([ -n "$WP_VAULT_PASSWORD" ] && echo yes || echo NO)"
which uvicorn
python3 -c "import bip_utils, cryptography, ecdsa, pynacl, coincurve; print('crypto deps OK')"

# 4. Read today's standup notes (if maintained)
cat docs/standup/$(date +%Y-%m-%d).md 2>/dev/null || echo "No standup yet today"
```

If any of these fail, do not start a new feature — fix the break first.

---

## The "what's next" list

This is the canonical work queue. Items have stable IDs (`WP-NNN`) so they can be referenced across docs and PRs.

### WP-001 → WP-020 — P0 from AUDIT.md (do FIRST)

| ID | Item | Owner | Status |
|----|------|-------|--------|
| WP-001 | Disable 17 BROKEN chains in chains.py | — | **DONE** (2026-06-30) — all 17 chains fixed via chain_addresses module instead of disabled |
| WP-002 | Fix x402 credits verification (no payment = no credit) | — | **DONE** (2026-06-30) — verify_payment() called before crediting |
| WP-003 | Migrate hosted passwords to Argon2id | — | **DONE** (2026-06-30) — argon2-cffi PasswordHasher, legacy SHA-256 migrates on login |
| WP-004 | Persist team keys + role enforcement | — | **DONE** (2026-06-30) — KeyStore has role field, middleware enforces operator min on writes |
| WP-005 | KEK file backend (replace env-only vault password) | — | **DONE** (2026-06-30) — file > env, auto-generates on first run, mode 0600 |
| WP-006 | Implement or rename `wallet_sweep` and DCA scheduler | — | **DONE** (2026-06-30) — EVM chains broadcast via Web3 + eth_account; non-EVM still intent |

### WP-021 → WP-040 — P1 from AUDIT.md

| ID | Item | Owner | Status |
|----|------|-------|--------|
| WP-021 | `verify()` writes on every read (perf + race) | — | open |
| WP-022 | Add real Alembic migrations (currently dead code) | — | open |
| WP-023 | Remove ALTER-on-every-put in vault.py | — | open |
| WP-024 | Audit log integrity chain (SHA-256 like agent_safety) | — | open |
| WP-025 | Redact mnemonic from audit log | — | open |
| WP-026 | Fix x402 verify_order DB path | — | open |
| WP-027 | x402 keys-in-body opt-in flag | — | open |
| WP-028 | x402 xpub derivation correct address format per chain | — | open |
| WP-029 | LLM call timeout + per-key rate limit | — | open |
| WP-030 | Orchestrator HITL bypass fix | — | open |
| WP-031 | Plan JSON schema validation (anti-prompt-injection) | — | open |
| WP-032 | audit_log hash chain mutex | — | open |
| WP-033 | DCA scheduler actually executes | — | open |
| WP-034 | Receipt signing key envelope encryption | — | open |

### WP-040 → WP-060 — Phase 1 broken chains (per-chain work)

| ID | Chain | Effort | Status |
|----|-------|--------|--------|
| WP-040 | Stellar (xlm) | S | **DONE** (2026-06-30) — stellar-sdk verified |
| WP-041 | Tezos (xtz) | S | **DONE** (2026-06-30) — manual tz1 watermark impl |
| WP-042 | Injective (inj) | S | **DONE** (2026-06-30) — bech32 with HRP |
| WP-043 | Cosmos Hub (atom) | S | **DONE** (2026-06-30) — bech32 with HRP |
| WP-044 | Osmosis (osmo) | S | **DONE** (2026-06-30) — bech32 with HRP |
| WP-045 | Sei (sei) | S | **DONE** (2026-06-30) — bech32 with HRP |
| WP-046 | Juno (juno) | S | **DONE** (2026-06-30) — bech32 with HRP |
| WP-047 | Evmos (evmos) | S | **DONE** (2026-06-30) — bech32 with HRP |
| WP-048 | Algorand (algo) | S | **DONE** (2026-06-30) — SHA-512/256 checksum |
| WP-049 | TON | M | **DONE** (2026-06-30) — manual workchain+CRC16 impl |
| WP-050 | Filecoin (fil) | S | **DONE** (2026-06-30) — f1 + blake2b impl |
| WP-051 | Nano (xno) | S | **DONE** (2026-06-30) — manual blake2b impl |
| WP-052 | Polkadot (dot) — sr25519 | L | **DONE** (2026-06-30) — substrate-interface |
| WP-053 | Kusama (ksm) — sr25519 | L | **DONE** (2026-06-30) — substrate-interface |
| WP-054 | Monero (xmr) | L | **DONE** (2026-06-30) — monero library |
| WP-055 | Cardano (ada) — Bech32 stake | L | **DONE** (2026-06-30) — pycardano Kholaw + verified against cardano-address CLI |
| WP-056 | Bitcoin Cash (bch) — cashaddr | S | **DONE** (2026-06-30) — bitcash |
| WP-057 | XRP — custom alphabet | M | **DONE** (2026-06-30) — manual XRP alphabet impl |
| WP-058 | Zcash (zec) — prefix fix | S | **DONE** (2026-06-30) — 0x1C → 0x1CB8 |
| WP-059 | BTC segwit variants | M | open |

### WP-060 → WP-080 — Phase 2 architectural cleanup

| ID | Item | Status |
|----|------|--------|
| WP-060 | Split `chain_vault.py` (2249 lines) into 4 modules | open |
| WP-061 | Migrate raw SQL → Alembic | open |
| WP-062 | Consolidate DB paths | open |
| WP-063 | Pluggable KeyBackend | open |
| WP-064 | Per-wallet HKDF keys | open |
| WP-065 | Pydantic MCP tool args | open |
| WP-066 | Repository pattern | open |
| WP-067 | Replace JSON KeyStore with SQLite | open |

### WP-080 → WP-100 — Phase 3 product features

| ID | Item | Status |
|----|------|--------|
| WP-080 | SSE progress for batch generation | open |
| WP-081 | Email verification (hosted) | open |
| WP-082 | Login rate limit (hosted) | open |
| WP-083 | Encrypted backup archive | open |
| WP-084 | Chain auto-detect on mnemonic import | open |
| WP-085 | Off-site backup replication | open |
| WP-086 | Monitoring + alerting | open |
| WP-087 | Load testing (Locust) | open |
| WP-088 | External pen test | open |
| WP-089 | SBOM + Sigstore for Docker images | open |
| WP-090 | GDPR data export + delete (hosted) | open |

### WP-100 → WP-120 — Phase 4 desktop + mobile

| ID | Item | Status |
|----|------|--------|
| WP-100 | Tauri desktop app | open |
| WP-101 | PWA mobile | open |
| WP-102 | React Native app | open |

---

## PR / commit workflow

### Branching

- `main` — always green. Never commit broken code.
- `feat/WP-NNN-short-name` — feature branch.
- `fix/WP-NNN-short-name` — bug fix branch.
- `chore/*` — maintenance.

### Commit messages

Conventional commits. Mandatory.

```
feat(wallet_engine): add bech32 Cosmos address generation

Closes WP-043.

- Use bech32 library with HRP per chain
- Verified against cosmjs reference for 4 test mnemonics
- tests/test_address_vectors.py updated

Refs: ADDRESS_GENERATION.md
```

Types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`, `security`.

### PR template

`.github/pull_request_template.md` should include:

```markdown
## Summary
[1-2 sentences]

## WP ID
[WP-NNN from BUILDER.md]

## Source-of-truth docs updated
- [ ] AUDIT.md (if bug fix)
- [ ] ADDRESS_GENERATION.md (if chain change)
- [ ] ARCHITECTURE.md (if architectural change)
- [ ] SECURITY.md (if security change)

## Checklist
- [ ] `make check` passes locally
- [ ] `make security` passes
- [ ] Test added for new behavior
- [ ] No P0/P1 bugs introduced
- [ ] No secrets in diff
- [ ] Conventional commit message

## How to verify
[Specific commands an agent can run to confirm]
```

### What NOT to do in a PR

1. **Don't bundle unrelated changes.** One logical change per PR.
2. **Don't refactor while fixing.** That's two PRs.
3. **Don't update PROGRESS.md / ROADMAP.md** unless you're explicitly rewriting those docs.
4. **Don't add dependencies** without a justification paragraph in the PR body.
5. **Don't change the public API** without updating the WP plugin or SDK in the same PR.
6. **Don't add new chains** without ADDRESS_GENERATION.md update + tests.

---

## Daily standup format

`docs/standup/YYYY-MM-DD.md`:

```markdown
# Standup — YYYY-MM-DD

## Yesterday
- @engineer-1: WP-003 migrated 12 of 47 hosted users to Argon2id
- @engineer-2: WP-040 Stellar address gen + test passing
- @engineer-3: WP-006 decided on "implement" — opened sub-tasks

## Today
- @engineer-1: WP-003 migration script ready for review (PR #123)
- @engineer-2: WP-041 Tezos start
- @engineer-3: WP-006 sweep implementation draft

## Blockers
- WP-001 needs product decision: do we ship with 17 chains disabled, or block release on fixing them all?

## Decisions made
- Keep WordPress plugin MIT (was: GPL by WordPress convention)
- Adopt `langchain` only if WP-XXX Y happens
```

If a decision is made in standup, update the relevant source-of-truth doc immediately.

---

## Testing discipline

### What to test

- Every new function gets a test.
- Every bug fix gets a regression test.
- Every new chain gets a `tests/test_address_vectors.py` entry.
- Every new MCP tool gets an integration test that hits it through the MCP protocol (not direct call).

### Test layout

```
backend/tests/
├── test_chain_vault.py     # CRUD + persistence
├── test_chains.py          # Chain metadata validation
├── test_vault.py           # Encryption + storage
├── conftest.py             # Fixtures
├── test_address_vectors.py # Per-chain golden vectors (Phase 1)
├── test_auth.py            # API key + roles (after WP-004)
├── test_audit_chain.py     # SHA-256 chain integrity (after WP-024)
├── test_agent_safety.py    # HITL + kill switch
├── test_x402.py            # Marketplace (after WP-002, WP-006)
└── test_proof.py           # Merkle + receipts
```

### Coverage gates

- New code: ≥80% line coverage.
- Modified code: coverage can't decrease.
- Security-critical paths (vault, auth, proof, agent_safety): 100% line coverage.

---

## Deployment workflow

WalletPress doesn't ship from Cinnabox — it ships from Talos.

```bash
# 1. Push to Talos
cd ~/sites/walletpress
git push talos main

# 2. SSH into Talos
ssh netcup

# 3. Update + restart on Talos
cd /root/sites/walletpress  # or wherever it's deployed
git pull
cd backend
make test                    # run tests on Talos too
docker compose -f docker-compose.yml build
docker compose -f docker-compose.yml up -d

# 4. Verify
curl -s http://localhost:8010/health
```

Tagging:

```bash
git tag -a v1.0.0-audit -m "v1.0.0-audit: P0+P1 fixes"
git push talos v1.0.0-audit
git push origin v1.0.0-audit  # external mirror
```

---

## Agent-specific rules

When you're an AI agent (opencode, aider, Hermes, Claude Code, Continue, Kilo, kimi-code):

1. **Read `WALLETPRESS.md`, `ARCHITECTURE.md`, `SECURITY.md`, `AUDIT.md`, `BUILDER.md`, `ADDRESS_GENERATION.md`** at the start of every session. Use the file tool to confirm they exist before relying on them.
2. **Don't fix bugs you find incidentally.** Log them in AUDIT.md "Known issues" and move on.
3. **Don't propose architectures.** Use ARCHITECTURE.md as the answer to "what should this look like?"
4. **Don't trust PROGRESS.md or ROADMAP.md.** They claim features that don't exist. Run the code.
5. **Don't write to `data/` directory in tests.** Use a tempdir fixture.
6. **Don't commit `.env` files.** Always `gopass` for secrets.
7. **Don't add new dependencies** without updating `requirements.txt` AND `requirements.lock` AND `pyproject.toml`.
8. **Run `make check` before committing.** If it fails, fix the lint/type/test, don't bypass.
9. **Conventional commits only.** Don't merge-squash messages.
10. **Don't create PRs without a WP-NNN ID** in the body.

---

## What gets built where

Decision tree when you need to add a feature:

```
Is this a bug fix?
├── yes → AUDIT.md → find the ID (or add one) → fix in `fix/WP-NNN` branch
└── no, it's a feature
    ├── Does it touch the wallet engine?
    │   ├── yes → chains.py + generator.py + ADDRESS_GENERATION.md + test_address_vectors.py
    │   └── no
    │       ├── Does it expose a new endpoint?
    │       │   ├── yes → routers/* + main.py + OpenAPI regen + WP plugin update
    │       │   └── no
    │       │       ├── Does it expose a new MCP tool?
    │       │       │   ├── yes → agent/mcp_server.py + agent_safety check + HITL flow
    │       │       │   └── no
    │       │       │       ├── Does it change security boundaries?
    │       │       │       │   ├── yes → SECURITY.md update + ARCHITECTURE.md update + threat model
    │       │       │       │   └── no
    │       │       │       │       └── It's core only. Add to the relevant core/ module.
```

This is the **canonical routing rule**. If you're not sure, ask in the standup.

---

## Anti-patterns

We've seen these fail. Don't repeat them:

1. **"I'll just quickly add this feature while I'm in here."** No. PR scope is sacred.
2. **"The test is too hard to write, I'll skip it."** No. Refactor the code so the test is easy.
3. **"I'll just use a global dict for now and persist later."** No. Use the repository pattern from day one.
4. **"The chain is similar enough to BTC, I'll reuse the logic."** No. Each chain has its own format. Test vectors per chain.
5. **"I'll just put a `try/except` around it."** No. Catch the specific exception. Log it. Re-raise with context.
6. **"I'll log the full params dict to debug."** No. Redact secrets before logging.
7. **"I'll hardcode the RPC for now."** No. Use `WP_RPC_{CHAIN}` env var from day one.
8. **"Tests are slow because of LLM calls, I'll mock everything."** No. Mock only at the network boundary. Keep the logic under test.
9. **"I'll commit straight to main."** No. Branch, PR, review, merge.
10. **"I'll update the docs later."** No. Docs in the same PR. Always.

---

## Cadence summary

| Cadence | Activity | Tool |
|---------|----------|------|
| **Every session** | Read source-of-truth docs | editor |
| **Every PR** | `make check` + `make security` | local |
| **Daily** | Standup + push to Talos | git + ssh |
| **Weekly** | Run `make vuln-scan`, update dependencies | tools |
| **Per release** | Cut tag, run pre-release checklist | SECURITY.md |
| **Per chain addition** | Update ADDRESS_GENERATION.md + tests | editor |
| **Per security finding** | Update AUDIT.md + (if design change) ARCHITECTURE.md | editor |

---

## Onboarding a new agent

If you're a new agent arriving cold:

1. Read `WALLETPRESS.md` (5 min)
2. Read `ARCHITECTURE.md` (15 min)
3. Read `SECURITY.md` (10 min)
4. Read `AUDIT.md` (15 min)
5. Skim `ADDRESS_GENERATION.md` (5 min)
6. Read this file (5 min)
7. Run `make check` (5 min)
8. Pick a small WP-NNN item (start with WP-001 or WP-040)
9. Open a PR

Total onboarding: ~1 hour to first useful PR.

---

## See also

- `WALLETPRESS.md` — product summary
- `ARCHITECTURE.md` — system design + roadmap
- `SECURITY.md` — threat model
- `AUDIT.md` — bugs and fixes
- `ADDRESS_GENERATION.md` — chain truth table