Commit graph

340 commits

Author SHA1 Message Date
1114f44b36 perf(spreadsheet): swap sheet data without cloning 2026-07-27 15:12:35 +00:00
0ffd2dd487 refactor(spreadsheet): structure dependency cycle errors 2026-07-27 15:10:10 +00:00
01bc055d1e feat(pay): complete the partially-done review phases
Some checks failed
Payment domain and storage / isolated-payment-tests (push) Has been cancelled
No new phase was started. This finishes every item tranches 1-2 left
partial, so Phases 1, 3, 7 and 8 are complete for the two pure crates or
explicitly blocked on crates that cannot be built here.

Phase 1 (build governance):
- Check in Cargo.lock for both payment crates and build with --locked.
  .gitignore excluded them, which would have made item 1.1 a false claim.
- tools/test-rust-clean.sh now reads the channel from rust-toolchain.toml
  instead of a hardcoded default that had already drifted, and gates on
  fmt, clippy -D warnings, the sqlcipher feature and the benchmarks.
- CI enforces lockfile presence/freshness and a Makepad-boundary check that
  inspects manifests and use/extern lines rather than prose (1.4).

Building on the declared 1.97.1 toolchain surfaced five lints 1.85 missed;
all are fixed. The two Default impls are annotated rather than derived
because each encodes a security or state-machine decision.

Phase 3 (secure repository):
- 3.1 encryption at rest: new encryption.rs and an opt-in sqlcipher feature.
  PRAGMA key is applied first and verified by a forced read, so a wrong key
  fails as KeyRejected rather than as corruption. DatabaseKey redacts its
  Debug and zeroes on drop. No key is ever derived or persisted here, and
  there is no unencrypted fallback. A test asserts the recipient MSISDN is
  absent from the raw database bytes.
- 3.5: preferences.rs replaces the ANDROID_DATA marker file whose existence
  was the value; every field fails safe.
- 3.6: redact.rs. PaymentIntent's derived Debug leaked a customer MSISDN
  into any log line; it now masks phone, name and ids, with a regression
  test. StorageError no longer prints a full intent id.

Phase 7:
- 7.7 benchmarks over money, validation, fees, the intent lifecycle and
  evidence handling, using the stable harness so they run on the pinned
  toolchain. BASELINE.md records measured output.
- 7.1/7.2/7.3 verified already satisfied; the review text is stale.

Phase 8:
- 8.1 simulator.rs with a scripted gateway and biometric, no clock or I/O.
- 8.2 property tests over every permutation of a representative event set:
  no ordering dispatches twice, untrusted events never settle a payment,
  ambiguity never becomes failure, Confirmed is terminal, duplicate
  confirmations are idempotent, and replayed SMS cannot fake a conflict.

Validated on rustc 1.97.1 outside the incomplete workspace graph:
domain 66 tests, storage 20 tests, storage+sqlcipher 25 tests, fmt clean,
clippy -D warnings clean on both crates and both feature sets, benches run.
49 manifests parse; git diff --check clean.

Still unclaimed and blocked on uncompilable crates: UI wiring, Keystore key
provisioning, Phase 4 draw_walk I/O, Phase 5 adapters and legal review, the
Java PIN scrub, and B1/B4/B6 in nigig-core.
2026-07-27 15:07:28 +00:00
3845c9ce8e style(spreadsheet): format engine and test sources 2026-07-27 15:06:04 +00:00
b28fb02616 chore(spreadsheet): remove unused engine warnings 2026-07-27 15:04:30 +00:00
fe26cbe29a test(spreadsheet): harden cell reference coverage
Some checks failed
Payment domain and storage / isolated-payment-tests (push) Has been cancelled
2026-07-27 15:02:50 +00:00
2c71f5e166 test(spreadsheet): add isolated engine test target
Some checks failed
Payment domain and storage / isolated-payment-tests (push) Has been cancelled
2026-07-27 15:01:15 +00:00
922c33620a refactor(spreadsheet): remove legacy formula evaluator 2026-07-27 14:58:54 +00:00
ec1ab5deaa refactor(spreadsheet): route cell evaluation through AST engine 2026-07-27 14:57:42 +00:00
a7670cd228 fix(spreadsheet): complete cell reference parsing in AST engine 2026-07-27 14:50:33 +00:00
70eddf42c7 feat(pay): add evidence, event correlation and explicit reconciliation
Some checks failed
Payment domain and storage / isolated-payment-tests (push) Has been cancelled
Implements the review phases left open by the previous tranche in the two
pure crates, per REVIEWS/NIGIG_PAY_CONSOLIDATED_REVIEW.md.

nigig-pay-domain:
- evidence.rs: ObservedEvidence/EvidenceLog make SMS and USSD output an
  untrusted observation that can raise a reconciliation flag but can never
  settle a payment (0.4, B2). Replays are de-duplicated by a deterministic
  body digest; only the digest is retained, never the raw body (0.6).
- reconciliation.rs: explicit queue with typed reasons and attributed
  resolutions (2.8, 6.3). SafeToRecreate never mutates or re-dispatches the
  original intent. The user-facing message says "do not retry" and never
  "failed" (U4).
- coordinator.rs: operation_id -> intent index so an unmatched callback
  changes nothing (2.7); hard duplicate-dispatch guard where only a
  never-started dispatch refunds the budget (2.9, B3);
  expire_local_confirmation_window replaces Submitted -> Failed on timeout
  and cannot disturb a settled payment.

nigig-pay-storage:
- schema migration 2 adds payment_intent_evidence with a unique digest
  constraint and a durable payment_reconciliation_queue (3.2, 3.3).
- legacy import now durably queues unprovable records.
- fault-injection tests for unwritable path, corrupt file, unusable worker
  path and audit-insert rollback (3.4); restart-equivalence tests (8.2).

Both crates deny unwrap/expect/panic/indexing outside tests (7.8). That
ratchet caught PaymentStorageWorker::spawn aborting on thread-spawn
failure; it is now fallible and returns StorageError.

Validated in an isolated toolchain over copies of the two pure crates:
cargo fmt --all --check clean, cargo clippy --workspace --all-targets
-D warnings clean, 43 domain tests and 17 storage tests passing, and all
49 workspace manifests parse. The full workspace is not asserted buildable
here: external Makepad/Robius sibling path dependencies are absent, so the
Makepad UI wiring, SQLCipher/Keystore encryption and the Java PIN scrub
remain explicitly unclaimed.
2026-07-27 14:39:15 +00:00
99f73f587d added updates 2026-07-27 07:28:06 +03:00
62dada264e build: consume Makepad sibling APIs through widgets 2026-07-27 04:22:42 +00:00
0c4e5e0a95 build: reexport direct Makepad map and CAD crates 2026-07-27 03:48:20 +00:00
e73def6d1b build: align Makepad dependencies with Robrix fork 2026-07-27 03:32:08 +00:00
5af8a20d04 build: use Robrix upstream Robius dependencies 2026-07-27 03:26:49 +00:00
11063d9602 fix(pay): wipe demo PIN after USSD request handoff 2026-07-27 03:24:54 +00:00
7c4d6441dd fix(pay): zeroize legacy demo PIN state 2026-07-27 03:07:24 +00:00
52adb32270 refactor(pay): remove unused PIN-bearing bulk request helper 2026-07-26 19:27:05 +00:00
1346c1006f test(pay): remove duplicated and skipped integration tests 2026-07-26 19:25:36 +00:00
ffa60532ed refactor(pay): name local SMS results as observed evidence 2026-07-26 19:23:53 +00:00
c61242c356 fix(pay): make payment total arithmetic checked 2026-07-26 19:20:06 +00:00
e435154f3c fix(pay): reject implicit floating point money conversion 2026-07-26 19:19:05 +00:00
56c8f4b9da feat(pay): expose sqlite reconciliation queue 2026-07-26 19:15:26 +00:00
62dd7bc96a refactor(pay): keep legacy pending store demo-only 2026-07-26 19:13:14 +00:00
ae93e37b7f feat(pay): migrate legacy pending records at flow startup 2026-07-26 19:12:10 +00:00
b36faef990 feat(pay): import legacy pending records into sqlite 2026-07-26 19:08:52 +00:00
4ffb627dc9 fix(pay): surface legacy pending store persistence errors 2026-07-26 19:06:37 +00:00
9bcc5aecbf fix(pay): block legacy flow entry outside demo mode 2026-07-26 19:04:42 +00:00
37054d52b6 fix(pay): gate legacy USSD request construction behind demo 2026-07-26 19:03:44 +00:00
83c50e5558 fix(pay): hide and discard PIN input outside demo mode 2026-07-26 19:01:55 +00:00
50cbcf76ab fix(pay): prevent PIN use when production dispatch is disabled 2026-07-26 19:00:43 +00:00
062f42ba27 fix(pay): surface ambiguous ussd outcomes for reconciliation 2026-07-26 18:59:20 +00:00
0b21781234 fix(pay): reconcile stale dispatches instead of failing them 2026-07-26 18:56:54 +00:00
ff33a9c413 fix(pay): disable automatic ussd dispatch retries 2026-07-26 18:54:24 +00:00
50d356db17 feat(pay): connect coordinator to durable storage worker 2026-07-26 18:51:22 +00:00
f6750c8259 feat(pay): add domain coordinator and sqlite storage foundation 2026-07-26 18:42:02 +00:00
e9616c3288 added missing crates 2026-07-26 21:22:21 +03:00
a2ea0ffc7c updated map 2026-07-26 18:00:48 +03:00
cc05abdc71 Initial commit 2026-07-26 19:38:26 +03:00