veza/docs/audit-2026-04
senke 68a0d390e2 docs(audit): P1.7 → P0.12 post-probe; add v1.0.7 item G + Idempotency-Key TTL note
2026-04-17 Q2 probe confirmed the subscription money-movement finding
wasn't a "needs confirmation from ops" P1 — it was a live P0 bypass.
An authenticated user could POST /api/v1/subscriptions/subscribe,
receive 201 active without payment, and satisfy the distribution
eligibility gate. v1.0.6.2 (commit 9a8d2a4e7) closed the bypass at
the consumption site via GetUserSubscription filter + migration 980
cleanup.

axis-1-correctness.md:
  * P1.7 renamed to P0.12 with the bypass chain, probe evidence, and
    v1.0.6.2 closure cross-reference.
  * Residual subscription-refund / webhook completeness work split out
    as P1.7' (original scope, still v1.0.8).

v107-plan.md:
  * Item G added (M effort) — replaces the v1.0.6.2 filter with a
    mandatory pending_payment state + webhook-driven activation,
    closing the creation path rather than compensating at the gate.
  * Dependency graph gains a third track (independent of A/B/C/D/E/F).
  * Effort total revised from 9-10d to 12-13d single-dev, 5d to 7d
    two-dev parallel.
  * Item D acceptance gains a TTL caveat section — Hyperswitch
    Idempotency-Key has a 24h-7d server-side TTL; app-level
    idempotency (order.id / partial UNIQUE) remains the load-bearing
    guard beyond that window.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 12:31:07 +02:00
..
axis-1-correctness.md docs(audit): P1.7 → P0.12 post-probe; add v1.0.7 item G + Idempotency-Key TTL note 2026-04-17 12:31:07 +02:00
README.md docs(audit): 2026-04 correctness/accounting findings (axis 1) 2026-04-17 03:21:33 +02:00
v107-plan.md docs(audit): P1.7 → P0.12 post-probe; add v1.0.7 item G + Idempotency-Key TTL note 2026-04-17 12:31:07 +02:00

VEZA Audit — 2026-04

Scope — VEZA backend (Go) + web (TypeScript). TALAS software (firmware, PCB reverse-engineering pipeline) is out of scope and will be audited separately when its phase stabilises.

Source state — commits up to a57bb6f78 (v1.0.6.1, 2026-04-17).

Auditor — Claude Opus 4.7 (1M context).

Axes

# File Status
1 axis-1-correctness.md — correctness / accounting delivered
2 axis-2-state-machines.md — transition matrix + illegal-transition tests 🔲 pending v1.0.7
3 axis-3-security.md — attack surface (signatures, rate limits, authz, secrets) 🔲 pending
4 axis-4-tests.md — coverage vs reality, failure-injection gap 🔲 pending
5 axis-5-debt.md — documented debt vs hidden debt (TODO/FIXME inventory) 🔲 pending

Axis 2 is gated on v1.0.7 landing first — otherwise the transition matrix captures a v1.0.6.1 snapshot that's immediately stale. See v107-plan.md for the sequencing.

Reading conventions

Every finding cites file:line evidence. Structure:

### P{0|1|2}.N — short title
**Evidence** — concrete cites
**Consequence** — what breaks today / tomorrow
**Action** — what to do, with enough detail that an implementer can start
**Criticity** — P0 / P1 / P2 / wontfix (with justification)

P0 = fix within v1.0.7 or earlier (ledger diverges today, or a v1.0.7 commitment is structurally blocked). P1 = v1.0.7 target. Operational visibility / correctness hardening. P2 = v1.0.8+. Nice-to-have. wontfix = justified non-action.

Info needed from ops (not determinable from code)

Tracked in axis-1-correctness.md. Absence of answers becomes a finding in its own right.

Derived deliverables

  • v107-plan.md — sequencing, dependencies and relative effort for the axis-1 P0 findings + the CHANGELOG-parked v1.0.7 items. Read this before picking up v1.0.7 work.