diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..bba5ca4 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,15 @@ +# Default owners +* @crmuncher + +# Standards + fleet (slower review) +/AGENTS.md @crmuncher +/ARCHITECTURE.md @crmuncher +/README.md @crmuncher +/STATUS.md @crmuncher +/PLAN.md @crmuncher +/ROADMAP.md @crmuncher +/DECISIONS.md @crmuncher + +# Sensitive paths +/.secrets/ @crmuncher +/backend/chain_vault/ @crmuncher diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..1b6a476 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,68 @@ +# AGENTS.md β€” WalletPress + +> AI agent contract. Read this before touching anything in this repo. + +## Status +canonical Β· owner=crmuncher Β· last_updated=2026-07-02 + +## What This Repo Is +Wallet-as-a-service. Wallet engine, x402 service, chain vault, hosting. CLI for wallet management. Production-grade. + +## Type +`backend` Β· language=Python 3.12 + FastAPI + +## Where It Lives +- Source: `https://git.rugmunch.io/RugMunchMedia/walletpress` +- Deployed: Docker on Talos (/srv/walletpress/) +- Port: 8010 + +## Built With +- Standards: [git.rugmunch.io/RugMunchMedia/standards](https://git.rugmunch.io/RugMunchMedia/standards) +- Toolchain: [TOOLCHAIN.md](https://git.rugmunch.io/RugMunchMedia/standards/raw/branch/main/TOOLCHAIN.md) +- Conventions: [CONVENTIONS.md](https://git.rugmunch.io/RugMunchMedia/standards/raw/branch/main/CONVENTIONS.md) + +## Components +- `app/`: FastAPI source (adapters, agent, cli, core, plugins, routers) + +## Dependencies +- postgresql (data store) +- redis (cache + queue) + +## 🚨 CRITICAL RULES + +1. **No nested repos.** Don't commit other complete project trees inside this one. +2. **No secrets.** Never commit `.secrets/`, `.env`, `*.pem`, `*.key`, `*.crt`. Use gopass. +3. **No data blobs.** Don't commit `*.zip`, `*.parquet`, model weights, sqlite files. +4. **No broken files.** Shell heredoc accidents must be caught before commit. +5. **No duplicate scaffolds.** If a `backend/` or `frontend/` subdir exists at root, it's either THE app or bloat. +6. **Update STATUS.md before committing.** Builders must know where we are. +7. **Read DECISIONS.md before architectural changes.** Don't repeat rejected designs. + +## Commands +```bash +make install # install deps +make dev # dev server +make test # tests +make lint # ruff + format check +make typecheck # mypy strict +make security # bandit + gitleaks +make ci # full pipeline +make commit # conventional commit +make clean # remove build artifacts +``` + +## Architecture +See [ARCHITECTURE.md](ARCHITECTURE.md). Update it when components change. + +## Plan +[PLAN.md](PLAN.md) shows current sprint. Update weekly. + +## Status +[STATUS.md](STATUS.md) shows where we are RIGHT NOW. Update before each commit. + +## Owners +- Primary: crmuncher +- Backup: TBD + +## Related Repos +See [standards/PRODUCTS.md](https://git.rugmunch.io/RugMunchMedia/standards/raw/branch/main/PRODUCTS.md). diff --git a/DECISIONS.md b/DECISIONS.md new file mode 100644 index 0000000..e0fa692 --- /dev/null +++ b/DECISIONS.md @@ -0,0 +1,27 @@ +# DECISIONS.md β€” WalletPress + +> Architecture Decision Records (ADRs). Read before architectural changes. + +## What is an ADR? +A short document capturing an important architectural decision: +- Context (what's the problem?) +- Decision (what did we choose?) +- Consequences (what does this imply?) +- Alternatives (what else did we consider?) + +## How to Write a New ADR +1. Copy `docs/adr/0000-template.md` to `docs/adr/NNNN-short-title.md` +2. Fill in: Status, Context, Decision, Consequences, Alternatives +3. Add link below in "Index" +4. Commit as part of the change that triggered the ADR + +## Index + + +| Number | Title | Status | Date | +|--------|-------|--------|------| +| [0001](docs/adr/0001-initial-architecture.md) | Initial architecture | Accepted | 2026-07-02 | + +## Fleet-wide ADRs (in standards repo) +- [ADR-0001: Tailscale mesh as the only perimeter](https://git.rugmunch.io/RugMunchMedia/standards/raw/branch/main/MCP-ARCHITECTURE.md) +- [ADR-0012: 21-day sprint, not 10-week](https://git.rugmunch.io/RugMunchMedia/standards/raw/branch/main/FLEET-PLAN.md) diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md new file mode 100644 index 0000000..1b047ea --- /dev/null +++ b/DEPLOYMENT.md @@ -0,0 +1,75 @@ +# DEPLOYMENT.md β€” WalletPress + +> How to deploy. Build, push, restart, rollback. + +## Architecture +- Container: Docker +- Image registry: local (Talos) +- Orchestration: docker-compose on Talos +- Reverse proxy: nginx on Talos +- Auto-deploy: forgejo webhook β†’ Talos deploy script + +## Deploy + +### Automatic (CI/CD) +On merge to `main`: +1. forgejo webhook fires +2. Talos deploy script pulls latest commit +3. Rebuilds Docker image +4. Stops old container, starts new +5. Runs health check +6. Rolls back on failure + +### Manual +```bash +ssh netcup +cd /srv/walletpress +git pull origin main +docker build -t walletpress:latest . +docker stop walletpress +docker rm walletpress +docker run -d --name walletpress --restart unless-stopped --network host -p 8010:8010 walletpress:latest +``` + +## Health Check +```bash +curl -fsS http://localhost:8010/health +``` + +## Rollback +```bash +ssh netcup +cd /srv/walletpress +git log --oneline -5 # find last good commit +git checkout +docker build -t walletpress:latest . +docker restart walletpress +``` + +## Logs +```bash +docker logs walletpress --tail 100 -f +``` + +## Monitoring +- Prometheus: `/metrics` endpoint +- Grafana: dashboards in fleet-infra +- Loki: log aggregation + +## Secrets +All secrets in gopass: +- `rmi/walletpress/admin_key` +- `rmi/walletpress/db_password` +- _see AGENTS.md for full list_ + +Loaded via docker `--env-file` or systemd `EnvironmentFile`. + +## Firewall +- Public: 80, 443 (nginx) +- Internal: 8010 (localhost only, behind nginx) +- Tailscale: 8010 for admin access + +## Backup +- Code: forgejo (source of truth) + Hydra bare mirror (daily 04:00) +- Data: DB snapshot to R2 (daily) +- Config: gopass diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..de42586 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,83 @@ +# DEVELOPMENT.md β€” WalletPress + +> Dev workflow. Install, code, test, commit, PR. + +## Setup + +### Prerequisites +- Python 3.12+ / Node 20+ +- `gopass` for secrets +- `mise` for tool version mgmt (or manual) +- `pre-commit` for hooks + +### Install +```bash +git clone https://git.rugmunch.io/RugMunchMedia/walletpress.git +cd walletpress +make install +pre-commit install +``` + +### Environment +```bash +# Required env vars (loaded from gopass on deploy, .env locally) +# See .env.example +cp .env.example .env +$EDITOR .env # fill in test values +``` + +## Workflow + +### 1. Create a branch +```bash +git checkout -b feat/my-feature +# or fix/my-bug, docs/my-doc, chore/my-chore +``` + +### 2. Make changes +- Write code +- Add tests +- Update docs (AGENTS.md, ARCHITECTURE.md, STATUS.md) + +### 3. Run pre-commit locally +```bash +make lint +make test +make typecheck +make security +``` + +### 4. Commit (conventional) +```bash +make commit # interactive +# or: +git commit -m "feat(scope): add new feature" +``` + +Types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, ops, security + +### 5. Push + PR +```bash +git push -u origin feat/my-feature +# Open PR on forgejo: https://git.rugmunch.io/RugMunchMedia/walletpress/pulls/new +``` + +### 6. Wait for CI +- All checks must pass +- Review by CODEOWNERS +- Squash-merge to main +- Auto-deploys to Talos (via forgejo webhook) + +## Daily End-of-Day +```bash +make status # show what's changed +fleet-commit # commit helper with checklist +``` + +## Code Style +- Python: ruff (lint + format), mypy strict +- TypeScript: eslint + prettier +- Shell: shellcheck +- Markdown: vale + +See [standards/CONVENTIONS.md](https://git.rugmunch.io/RugMunchMedia/standards/raw/branch/main/CONVENTIONS.md). diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..93997a6 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,39 @@ +# PLAN.md β€” WalletPress + +> Current sprint. 21-day cycles per ADR-0012. + +## Status +current_sprint=2026-Q3-S1 Β· started=2026-07-01 Β· ends=2026-07-21 + +## Sprint Goals +1. _TODO: top 1-3 goals for this sprint_ + +## In Progress +- [ ] TODO: in-progress items + +## Backlog (this sprint) +- [ ] TODO: planned items + +## Risks +- TODO: anything blocking progress + +## Done (this sprint) +- _None yet β€” sprint just started._ + +## Carry-over from previous sprint +- _None._ + +--- + +## Definition of Done +- [ ] Code complete +- [ ] Tests written (>80% coverage on changed lines) +- [ ] Pre-commit hooks pass (ruff, mypy, gitleaks, bandit) +- [ ] CI passes on forgejo +- [ ] Conventional commit message +- [ ] PR reviewed + merged +- [ ] Deployed to staging +- [ ] Smoke-tested in production +- [ ] Observability in place (metrics, logs, alerts) +- [ ] Docs updated (AGENTS.md, ARCHITECTURE.md, README.md) +- [ ] STATUS.md updated diff --git a/README.md b/README.md new file mode 100644 index 0000000..1af51f2 --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# WalletPress + +> Part of **Rug Munch Media LLC** β€” Wyoming-based crypto intelligence platform. + +## What + +Wallet-as-a-service. Wallet engine, x402 service, chain vault, hosting. CLI for wallet management. Production-grade. + +## Type +`backend` Β· **Python 3.12 + FastAPI** + +## Quickstart +```bash +make install # install deps +make dev # start dev server +make test # run tests +make lint # lint + format +make ci # full CI pipeline +``` + +## Documentation +- [AGENTS.md](AGENTS.md) β€” AI agent contract +- [ARCHITECTURE.md](ARCHITECTURE.md) β€” technical architecture +- [PLAN.md](PLAN.md) β€” current sprint +- [ROADMAP.md](ROADMAP.md) β€” long-term direction +- [STATUS.md](STATUS.md) β€” where we are RIGHT NOW +- [DEVELOPMENT.md](DEVELOPMENT.md) β€” dev workflow +- [DEPLOYMENT.md](DEPLOYMENT.md) β€” how to deploy +- [TESTING.md](TESTING.md) β€” test strategy +- [SECURITY.md](SECURITY.md) β€” security model +- [DECISIONS.md](DECISIONS.md) β€” architecture decision records + +## Standards +This repo follows Rug Munch Media LLC fleet standards: +[git.rugmunch.io/RugMunchMedia/standards](https://git.rugmunch.io/RugMunchMedia/standards) + +## Repository +- Source of truth: `https://git.rugmunch.io/RugMunchMedia/walletpress` +- Mirrors: GitHub (LLC + personal), GitLab, HuggingFace +- Backup: Hydra daily at 04:00 via `git-backup.sh` diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 0000000..20c57d8 --- /dev/null +++ b/STATUS.md @@ -0,0 +1,36 @@ +# STATUS.md β€” WalletPress + +> Where we are RIGHT NOW. Update before every commit. + +## Last Updated +2026-07-02 (template, replace on first commit) + +## Deployment Status +- **Last deploy**: TBD +- **Current version**: TBD +- **Health**: TBD +- **Uptime (30d)**: TBD +- **Active branch**: `main` + +## Open Issues +- _None β€” track in forgejo issues_ + +## Recent Activity +- 2026-07-02: Repository created from `fleet-template` + +## Known Issues / Tech Debt +- _None yet_ + +## Quick Links +- [Live URL](https://walletpress.rugmunch.io) +- [API docs](https://walletpress.rugmunch.io/docs) +- [Health](https://walletpress.rugmunch.io/health) +- [Repo](https://git.rugmunch.io/RugMunchMedia/walletpress) + +## Status Indicators +Use these in commit messages + status updates: +- 🟒 healthy β€” deployed, monitored, no issues +- 🟑 degraded β€” running but with known issues +- πŸ”΄ down β€” service unavailable +- 🚧 in-development β€” pre-production, expect breakage +- ⏸️ paused β€” work intentionally stopped diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 0000000..ee7c83a --- /dev/null +++ b/TESTING.md @@ -0,0 +1,73 @@ +# TESTING.md β€” WalletPress + +> Test strategy. Unit, integration, e2e, fixtures. + +## Test Pyramid + +``` + /\ + / \ E2E (slow, few) + /----\ + / \ Integration (medium, more) + /--------\ + / \ Unit (fast, many) + /____________\ +``` + +- **Unit tests**: test individual functions/classes in isolation +- **Integration tests**: test components together (DB, API, auth) +- **E2E tests**: test full user flows (slow, run before deploy) + +## Structure +``` +tests/ +β”œβ”€β”€ unit/ # fast, no external deps +β”œβ”€β”€ integration/ # uses test DB, mocks external APIs +β”œβ”€β”€ e2e/ # full stack, runs against staging +β”œβ”€β”€ fixtures/ # test data (mainnet guard: no real addresses/keys) +└── conftest.py # pytest config +``` + +## Running + +```bash +make test # all tests +make test-unit # only unit +make test-integration # only integration +make test-cov # with coverage report +pytest tests/unit/test_X.py -v # single file +``` + +## Fixtures + +Use pytest fixtures. Examples: +- `clean_db` β€” fresh DB per test +- `mock_helius` β€” mock Helius API responses +- `auth_headers` β€” Bearer token for test user +- `sample_token` β€” fake token (test address, NOT mainnet) + +**NEVER use mainnet data in tests.** Pre-commit hook blocks this. + +## Coverage +- Target: >80% on changed lines +- Enforced in CI via `--cov-fail-under=80` + +## Mocking +- `httpx` for HTTP mocking (use `respx` or `pytest-httpx`) +- `unittest.mock` for general mocking +- VCR.py for recording/replaying API calls + +## Performance Tests +- `locust` for load testing (run against staging) +- Profile with `py-spy` or `cProfile` + +## CI +Every PR runs: +1. Lint (ruff) +2. Type check (mypy strict) +3. Unit tests + coverage +4. Integration tests (test DB) +5. Security scan (bandit, gitleaks) +6. Build Docker image (verify it compiles) + +Merge blocked if any fails. diff --git a/docs/adr/0000-template.md b/docs/adr/0000-template.md new file mode 100644 index 0000000..aa0bdcc --- /dev/null +++ b/docs/adr/0000-template.md @@ -0,0 +1,16 @@ +# ADR-NNNN: + +## Status +Proposed | Accepted | Deprecated | Superseded by ADR-XXXX + +## Context +What's the issue? What's the pressure for a decision? + +## Decision +What did we choose? + +## Consequences +What becomes easier? What becomes harder? + +## Alternatives +What else did we consider? Why didn't we pick them? diff --git a/docs/adr/0001-initial-architecture.md b/docs/adr/0001-initial-architecture.md new file mode 100644 index 0000000..dd9cd96 --- /dev/null +++ b/docs/adr/0001-initial-architecture.md @@ -0,0 +1,22 @@ +# ADR-0001: Initial Architecture + +## Status +Accepted Β· 2026-07-02 + +## Context +First commit of WalletPress. Need to document the foundational choices. + +## Decision +- **Language**: Python 3.12 + FastAPI +- **Port**: 8010 +- **Deployment**: Docker on Talos behind nginx +- **Source of truth**: forgejo +- **CI**: forgejo Actions +- **Secrets**: gopass + +## Consequences +- All future decisions build on this foundation +- Breaking changes to these need a new ADR + +## Alternatives +- _TBD_