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
431 lines
No EOL
16 KiB
Markdown
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 |