nigig-org/crates/pageflipnav/Cargo.toml
andodeki 23fce675de
Some checks failed
repo hygiene / hygiene (push) Has been cancelled
Payment domain, storage, platform and UI / isolated-payment-tests (push) Has been cancelled
Payment domain, storage, platform and UI / payment-ui-tests (push) Has been cancelled
feat(pay): USSD automation on by default; containment moves to packaging
Option A, as requested. Plus an audit of the whole review against the code.

## The default flips

  nigig-pay-ui   default = []            (leaf stays off; see below)
  nigig-pay      default = ["demo"]
  nigig-mpesa    default = ["demo"]
  pageflipnav    default = ["native", "demo"]

`cargo run -p pageflipnav` now drives *334#, shows the PIN field and
dispatches. That is the app's primary function and it works out of the box.

A release build opts out:

  cargo build -p pageflipnav --no-default-features --features native

This was not one line. A first attempt flipped the four `default =` lines
and the opt-out still leaked: the app crates depended on nigig-pay-ui with
its own defaults, so `--no-default-features` on pageflipnav was silently
re-enabled one level down. Verified with a compile probe rather than
cargo tree, which truncates. The inner deps now carry
`default-features = false`, and the probe confirms both directions:
default -> demo ON, --no-default-features -> demo OFF.

ADR 0007's Play-policy note is untouched. The containment requirement of
review item 0.1 is not dropped — the flag exists, CI exercises both
directions, and a shipped build still cannot dispatch. What changed is
which way it points by default, so development and device testing are not
fighting it.

CI guards inverted to match: they now assert automation is on by default
*and* that the packaging opt-out still works. check-no-pin-capture.sh now
probes the packaging build, since the default legitimately captures a PIN.

## REVIEWS/IMPLEMENTATION_AUDIT.md

Every phase checked against the code, not against the tranche notes. Where
they disagreed the code won. Summary: phases 0-5 and 7 done bar 5.2 and
Keystore provisioning; phase 6 substantially done with the thread_local
session ownership outstanding; phase 8 partly.

## B7 found live while auditing

Month navigation had never been examined. Both copies of the transactions
widget still stepped months with Duration::days(31) and years with
Duration::days(366). Reproduced before touching it:

  2025-12-28 -1 month => 2025-11-27   (drifts a day)
  2026-03-30 -1 month => 2026-02-27   (drifts; repeated steps skip a month)
  2027-06-15 +1 year  => 2028-06-15   (366d wrong on a non-leap year)

Now uses checked_add_months/checked_sub_months, which clamp to the end of
the target month, and checked_add_signed on the day path. An
unrepresentable date leaves the view where it was.

Neither claimed done nor flagged open — simply never looked at. That is the
argument for auditing code rather than notes.

## Validation

  domain 137 / storage 41 / platform 64 / mpesa 29 / pay-ui 61   pass
  cargo check: pay-ui, pay, mpesa, core (default and opt-out)    pass
  demo-on-by-default probe, both directions                      pass
  no-PIN-capture guard against the packaging build               pass

Unrelated and still blocking a full APK: nigig-map fails to compile on
clean HEAD (12 errors, no field center_lat on ViewportState).
2026-08-02 08:06:43 +00:00

104 lines
4.5 KiB
TOML

[package]
name = "pageflipnav"
version = "1.0.0"
edition = "2021"
[features]
## USSD automation is ON by default.
##
## Review item 0.1 asked for dispatch behind a compile-time flag. That was
## implemented as default-off, which made the *334# automation — the app's
## primary function — unreachable in an ordinary build, and unreachable at
## all from the APK crate until 9f0e133.
##
## The containment requirement has not been dropped; it has moved to release
## packaging, which is where a shipping decision belongs. A Play-listed build
## must be produced with `--no-default-features` (plus the features it does
## want), and the unresolved Google Play policy risk is recorded in
## REVIEWS/adr/0007-payment-platform-boundary.md.
##
## Turning it off for a build:
## cargo build -p pageflipnav --no-default-features --features native
default = ["native", "demo"]
native = ["dep:tokio", "dep:reqwest", "nigig-core/native"]
## Enable automated *334# USSD payment in the shipped app.
##
## This is the crate that produces the APK, so without this the `demo` flag
## on nigig-pay/nigig-mpesa is unreachable: building pageflipnav could never
## turn the automation on, and the Pay sheet always reported that dispatch
## was unavailable with no way to change it.
##
## Off by default (review items 0.1/0.3): a default APK is a tracker that
## never dials USSD and never captures an M-Pesa PIN.
##
## Enabling it turns on AccessibilityService-driven USSD automation, which
## remains an unresolved Google Play policy risk (review item 5.2,
## REVIEWS/adr/0007). Use it for your own device testing; do not publish an
## APK built with it until that decision is made.
##
## cargo run -p pageflipnav --features demo
demo = ["nigig-pay/demo", "nigig-mpesa/demo"]
[profile.small]
inherits = "release"
opt-level = 'z'
lto = true
codegen-units = 1
panic = 'abort'
strip = true
[dependencies]
makepad-widgets = { git = "https://gitdab.com/andodeki/makepad", rev = "a79f0dce4d477e2232344facca0798d3f25043ec", default-features = false, features = ["test", "serde", "maps"] }
robius-use-makepad = "0.1.1"
robius-open = { git = "https://github.com/project-robius/robius", rev = "b766e62b0600f5d2ee21cc6995648346fc277bd8" }
robius-directories = { git = "https://github.com/project-robius/robius", rev = "b766e62b0600f5d2ee21cc6995648346fc277bd8" }
robius-contacts = { version = "0.1.0", path = "../robius-contacts" }
postcard = { version = "1.1.3", features = ["use-std"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
error_set = "0.9.1"
unicode-segmentation = "1.11.0"
imghdr = "0.7.0"
rand = "0.8.5"
url = "2.5.0"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
clap = { version = "4.0.16", features = ["derive"] }
hashbrown = { version = "0.16", features = ["raw-entry"] }
futures-util = "0.3"
nigig-core = { path = "../nigig-core" }
nigig-uikit = { path = "../nigig-uikit" }
robius-ussd = { path = "../robius-ussd", features = ["serde"] }
robius-trigger = { path = "../robius-trigger" }
robius-fingerprinting = { path = "../robius-fingerprinting" }
nigig-chat = { path = "../apps/nigig-chat" }
nigig-feed = { path = "../apps/nigig-feed" }
nigig-email = { path = "../apps/nigig-email" }
nigig-sms = { path = "../apps/nigig-sms" }
nigig-ai = { path = "../apps/nigig-ai" }
nigig-walkie = { path = "../apps/nigig-walkie" }
nigig-alerts = { path = "../apps/nigig-alerts" }
nigig-rider = { path = "../apps/nigig-rider" }
nigig-delivery = { path = "../apps/nigig-delivery" }
nigig-garage = { path = "../apps/nigig-garage" }
nigig-tow = { path = "../apps/nigig-tow" }
nigig-mobility = { path = "../apps/nigig-mobility" }
nigig-pay = { path = "../apps/nigig-pay", default-features = false }
nigig-insure = { path = "../apps/nigig-insure" }
nigig-build = { path = "../apps/nigig-build" }
nigig-health = { path = "../apps/nigig-health" }
nigig-book = { path = "../apps/nigig-book" }
nigig-property = { path = "../apps/nigig-property" }
nigig-vehicle = { path = "../apps/nigig-vehicle" }
nigig-marikiti = { path = "../apps/nigig-marikiti" }
nigig-shop = { path = "../apps/nigig-shop" }
nigig-mpesa = { path = "../apps/nigig-mpesa", default-features = false }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { version = "1", features = ["rt", "rt-multi-thread", "sync", "time", "macros"], optional = true }
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"], optional = true }
[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
[dev-dependencies]