Task 4, re-scoped per the plan's honest-FAIL branch: the c3 class is NOT retired — every record now states the measured post-ALT truth. - KNOWN-LIMITATIONS: the cross-metro section is the /cari-shaped record — WHAT CHANGED (ALT built, D-03 optimality green quoted) / what REMAINS (the CPU verdict FAIL lines quoted with date; the one-directional- Lipschitz wall named; the escalation open); the roadmap-pointer ALT row flips to Built (Phase 8) with the measured verdict — never 'not built' again - ROAD-GRAPH: the ladder table gains the (c2) rung (EXECUTED, measured FAIL, the L=32 probe quoted); the decision paragraph states c2 executed-verdict-fail and names the real remaining options; new 'The ARG2 binary layout' section (72-byte header, landmarkCount/ landmarkQuantumS, u16 suffix + sentinels, the quantum knob's ≈6,553 s ceiling, the storage-name-vs-format-truth law); key facts carry the optimality gate and the ARG2 wording; the fork contract's build step teaches the landmark stage (no new commands) - docs/CONFIGURATION.md: verify-only — all path/script claims still true, no edit needed - staged as selective hunks; the tree's pre-existing doc-sync edits (battery paragraph, 'six maintainer scripts' intro) remain uncommitted greps: 'Next-milestone item, not built' = 0; the measured p95 strings quoted; (c2)/landmarkQuantumS/ARG2 all present; ARG1 appears only in layout/router-pending contexts.
125 lines
7.5 KiB
Markdown
125 lines
7.5 KiB
Markdown
<!-- generated-by: gsd-executor (07-05, D-08) -->
|
||
|
||
# Known limitations
|
||
|
||
arah² is a turn-by-turn navigator for the Kuala Lumpur metro, delivered inside
|
||
Telegram: you search a destination with the bot (`/cari KLCC`), open the Mini App,
|
||
and follow live route guidance built on OpenStreetMap data. It works today for real
|
||
drivers, and it has real limits. This page lists what arah² does **not** do well —
|
||
stated plainly, for two readers: a driver deciding whether arah² fits today's trip,
|
||
and a fork deciding what they are inheriting. Nothing here is a hidden defect; every
|
||
claim names its evidence, and none of it is fixed by asking harder.
|
||
|
||
## Data coverage
|
||
|
||
arah² routes over a snapshot of OpenStreetMap, and inherits OSM's gaps honestly:
|
||
|
||
- **No traffic awareness.** There is no live traffic feed; the ETA is a
|
||
distance-and-speed estimate from the route model, not a prediction.
|
||
- **No lane guidance.** There is no lane-level arrow guidance; the maneuver glyph
|
||
names the turn, not the lane.
|
||
- **Speed limits appear only where OSM maps them.** Many KL roads carry no
|
||
`maxspeed` tag in OSM, so no limit is shown on those roads.
|
||
- **Turn restrictions and one-ways** are only as good as the OSM snapshot the road
|
||
graph was built from; a restriction edited in OSM last week may not be reflected
|
||
until the next graph build.
|
||
- **The road graph is a build-time artifact** (`routing/data/kl-roadgraph.v1.bin`),
|
||
rebuilt by a maintainer — forks rebuild their own (`docs/ROAD-GRAPH.md`).
|
||
|
||
## Cross-metro routes may not resolve
|
||
|
||
Route computation runs inside Cloudflare Workers' free plan, whose per-request CPU
|
||
allowance is small. On the real KL road graph, short product routes (2–8 km — the
|
||
common search-and-reroute trip) resolve inside the plan; cross-metro routes
|
||
(20–30 km) do not. Those trips therefore degrade honestly: the app shows the
|
||
router-pending card — "the router is not ready for this trip" — instead of freezing
|
||
or drawing a wrong line. Workers Paid was rejected: it breaks the project's $0
|
||
mandate.
|
||
|
||
WHAT CHANGED (Phase 8, shipped 2026-10-25): the promised ALT landmark
|
||
preprocessing was built — the ARG2 graph layout carries build-time landmark
|
||
tables (L=24, quantum 0.1 s, coverage 0.980), the search steers with them, and
|
||
optimality is verified: the D-03 gate reproduces the frozen pre-ALT record
|
||
exactly (53/53 routed pairs within ±0.1%, max |Δ| 0.005%, verdict classes
|
||
preserved — `node routing/scripts/measure-optimality-gate.mjs`).
|
||
|
||
What REMAINS — the CPU verdict measured over budget, so the degradation stands:
|
||
the 25-route gate printed `GATE FAIL: p95 152.788 ms exceeds the 8 ms budget`
|
||
and the 100-pair cross-metro verdict `GATE FAIL: p95 185.692 ms exceeds the
|
||
8 ms budget` (2026-10-25; the `--landmarks 32` probe measured worse:
|
||
182.725 / 204.499 ms). The faster steering that would help is provably
|
||
unsound here: the fromTable triangle bounds are one-directional Lipschitz
|
||
(their u-side term needs the reverse edge, which a oneway does not provide),
|
||
and the bidirectional search's shared potential is consistent only with
|
||
two-sided families — the D-03 gate caught the four-family variant returning
|
||
suboptimal routes (x038: 1234.6 s vs the 1214.8 s optimum) before it shipped.
|
||
The honest escalation — direction-split potentials with a re-proven meet rule,
|
||
Contraction Hierarchies, or Workers Paid — is open, documented in
|
||
`docs/BUDGETS.md`'s c3 section. Full-speed routing is NOT claimed; only that
|
||
the measurement is printed and the gate decides.
|
||
|
||
## The /cari command may be missing from the Telegram menu
|
||
|
||
Some drivers saw a command menu listing `/help` and `/privacy` but **not** `/cari`.
|
||
ROOT CAUSE (found and FIXED 2026-10-25, 07-06 launch-gate canary): it was a bot-side
|
||
script bug, not a Telegram defect — `bot/scripts/register-commands.mjs` sent the scope
|
||
under the wrong parameter name (`bot_command_scope`; the Bot API field is `scope`),
|
||
which Telegram silently ignores, so every registration call actually hit the default
|
||
scope and the group-scope "clear" calls wiped the default set entirely. The correct
|
||
parameter was verified against https://core.telegram.org/bots/api/methods/setmycommands,
|
||
the script was fixed, and all private-chat scopes now read back `help, privacy, cari`
|
||
via `getMyCommands` (verified 2026-10-25). What REMAINS: the Telegram client caches the
|
||
menu — a device that opened the bot before the fix may keep showing the stale menu
|
||
until the app restarts. **The workaround: type `/cari` in the chat** — the command
|
||
itself has always worked; only its discoverability was affected.
|
||
|
||
## Beta quality
|
||
|
||
This is a private beta with a handful of drivers in Kuala Lumpur, not a finished
|
||
product. The device matrix was walked on real Android and iOS phones, Telegram
|
||
Desktop, and a plain browser; battery drain is a measured number, not an estimate —
|
||
one Android guidance run of at least 30 screen-on minutes with battery percentage
|
||
read at start and end, the method and caveats recorded in the launch-gate file
|
||
(`07-LAUNCH-GATE.md`) before the first driver is onboarded. Fullscreen and
|
||
orientation behaviour varies by Telegram client version; where the platform refuses
|
||
a fullscreen request the app degrades to a usable portrait/landscape layout rather
|
||
than failing. Known limits that are milestones, not defects: no voice guidance, no
|
||
live trip sharing, no toll toggle, no traffic-aware ETA — all are post-validation
|
||
items on the roadmap.
|
||
|
||
## What is being worked on next
|
||
|
||
Three tracks target the limits above. One of them — the ALT landmark layout —
|
||
shipped in Phase 8; its measured outcome (optimality verified, CPU verdict
|
||
still over budget) is recorded in the section above. The other two are not in
|
||
this release.
|
||
|
||
| Track | What it fixes | Honest status |
|
||
| --- | --- | --- |
|
||
| WASM-router | A client-side router compiled to WebAssembly — the static-hosted endgame where routing cost leaves the Worker entirely | Committed direction, not built |
|
||
| ALT landmark preprocessing | The cross-metro CPU degradation (the section above) — build-time landmark layout cuts A* steering cost at $0 runtime | Built (Phase 8, 2026-10-25): optimality verified; the CPU verdict measured over budget (p95 152.8/185.7 ms vs 8 ms) — the degradation stands |
|
||
| Engine B | A fully client-side webview router — routing runs in the browser, the Worker serves only data | Future track, not built |
|
||
|
||
## Privacy in one paragraph
|
||
|
||
Your coordinates live only in memory and in TTL-expiring KV records: sessions expire
|
||
in about 15 minutes, location pins in 5 minutes, guidance envelopes in about 2 hours;
|
||
there is no location history, no profile, and nothing retained past those TTLs. There
|
||
is NO telemetry of any kind in this release — no analytics, no crash reporting, no
|
||
usage tracking. The shipped bundle contacts only the map tile host, the Telegram API,
|
||
and the app's own Worker. `docs/PRIVACY-AUDIT.md` holds the full record, including
|
||
how each claim was verified.
|
||
|
||
## How to run the audit yourself
|
||
|
||
Forks inherit the audit tools — run both before your first driver:
|
||
|
||
- `npm run privacy-audit` — greps every source tree for storage-API writes outside
|
||
the platform allowlist, coordinate/payload logging, and telemetry in the shipped
|
||
bundle, and probes the live KV namespaces. **Exit 0 = every gate passed; exit 2 =
|
||
environment drift — investigate, never a pass.**
|
||
- `npm run budget-audit` — re-measures Worker CPU, bundle sizes, KV write classes,
|
||
and cache headers against the documented free-tier ceilings, and re-runs the golden
|
||
route and search corpora. **Exit 0 = every budget held; exit 2 = environment drift
|
||
— investigate, never a pass.**
|