walletpress/BUILDER.md
cryptorugmunch e13bd4d774
Some checks are pending
CI / lint (push) Waiting to run
CI / test (push) Waiting to run
CI / security (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / license (push) Waiting to run
CI / ai-review (push) Waiting to run
docs: apply fleet-template (16-artifact scaffold)
Adds missing standard artifacts:
- README.md (if missing)
- AGENTS.md (AI agent contract)
- PLAN.md (current sprint)
- STATUS.md (where we are)
- DEVELOPMENT.md (dev workflow)
- DEPLOYMENT.md (deploy procedure)
- TESTING.md (test strategy)
- DECISIONS.md (ADR index + templates)
- .github/CODEOWNERS
- .github/workflows/ci.yml

Preserves all existing artifacts.

Refs: RugMunchMedia/fleet-template
2026-07-02 02:07:06 +07:00

431 lines
No EOL
16 KiB
Markdown

# 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