araharah-executor
7994c84a40
docs(04): research phase domain — destination search + KL gazetteer
...
Phase 4 research: in-Worker SearchSource over a curated KL gazetteer.
Two critical platform findings:
- Telegram start_param is NEVER delivered to inline web_app buttons
(direct links + attachment menu only). The destination id must ride
as a URL query param on the button's URL; D-11's substance preserved.
- beforeinstallprompt never fires in a WebView. ONBD-03 must use
Telegram's native WebApp.addToHomeScreen(); iOS status is always
"unknown" by platform design.
Benchmarked the CPU budget: naive full-corpus Damerau is 52ms at
D-07's max scale vs the 10ms Workers Free limit. Exact-hash-first +
token-prefiltered residual is 0.0003ms.
Also: Phase 2 CS3/CS4/CS5 gates need declared amendments; ODbL
attribution obligation for the OSM-derived gazetteer.
2026-10-23 22:50:13 +08:00
araharah-executor
275879a18b
ambek .planning
2026-10-23 22:37:55 +08:00
araharah-executor
e512104d5e
assets: add arah² brand assets — logo + PSD source; display logo in README header
2026-10-23 21:10:00 +08:00
araharah-executor
91ad0c9d93
docs: generate + verify project documentation — canonical docs, per-package READMEs, verified fix pass
...
- New: docs/ARCHITECTURE.md, docs/GETTING-STARTED.md, docs/DEVELOPMENT.md,
docs/TESTING.md, docs/CONFIGURATION.md (colored mermaid diagrams, quoted labels)
- Regenerated README.md (arah² / arah2bot naming, canonical clone URL)
- New per-package READMEs: theme/, bot/, web/
- Verified 13 docs against the live codebase (2 fix iterations + 2 residual
corrections); corrected 56 stale claims across AGENTS/DESIGN/IDEAS/GSD_FIX
2026-10-23 20:56:40 +08:00
araharah-executor
af3edefbc6
add sume
2026-10-23 19:18:43 +08:00
araharah-executor
1890b5b1ca
docs(03): verification exit addendum — probe removal + GEO-03 platform allowlist
2026-10-23 18:53:28 +08:00
araharah-executor
8a5c8b415f
fix(03-04): GEO-03 probe platform allowlist — official telegram-web-app.js writes one sessionStorage bookkeeping key; app surfaces stay empty
2026-10-23 18:52:59 +08:00
araharah-executor
2589e2126f
docs(03-04): checkpoint resolution — device matrix passed
2026-10-23 18:45:15 +08:00
araharah-executor
9d6fdc64be
docs(03): device matrix PASSED + phase verification
2026-10-23 18:45:15 +08:00
araharah-executor
fc99745672
chore(03-04): remove the device-matrix diagnostic probe — exit obligation, matrix passed
2026-10-23 18:41:41 +08:00
araharah-executor
28045d9b9e
docs(03-04): log round 7 — probe readings; version-gate the settings CTA
2026-10-23 01:44:14 +08:00
araharah-executor
19a51e5882
fix(03-04): LOCATION SETTINGS CTA version-gated 8.0+ — hides the no-op off-Telegram (Chrome SDK stub reports 6.0)
2026-10-23 01:43:34 +08:00
araharah-executor
e64cf7003b
docs(03-04): log debug round 6 — signature-field HMAC erratum (the live blocker)
2026-10-23 01:34:53 +08:00
araharah-executor
22fda6d12a
fix(03-04): HMAC data-check-string excludes only hash — signature field participates (real clients rejected as tampered; erratum M6)
2026-10-23 01:34:19 +08:00
araharah-executor
c062ebaee1
docs(03-04): log debug round 5 — diagnostic probe armed
2026-10-23 01:25:35 +08:00
araharah-executor
f4453996ac
fix(03-04): on-screen diagnostic probe — WA version/platform, initData char-count, session + location categories
2026-10-23 01:24:52 +08:00
araharah-executor
de07c99e8a
docs(03-04): log debug round 4 — settings CTA on the wrong instance
2026-10-23 01:19:41 +08:00
araharah-executor
38ce59b1ca
fix(03-04): LOCATION SETTINGS CTA on the denied card (was only on awaiting-pin instance — patch-order bug)
2026-10-23 01:19:10 +08:00
araharah-executor
caeb9f9729
docs(03-04): log debug round 3 — telegram-web-app.js integration erratum
2026-10-23 01:15:10 +08:00
araharah-executor
3793741d2f
fix(03-04): load telegram-web-app.js in head — production WebApp was never defined (no initData, no LocationManager, no BackButton)
2026-10-23 01:14:27 +08:00
araharah-executor
ad4d18b180
docs(03-04): UI-SPEC amend — third denied CTA (LOCATION SETTINGS) as debug-round-2 amendment
2026-10-23 01:07:50 +08:00
araharah-executor
89268074a6
docs(03-04): log debug round 2 — LocationManager openSettings deep-link round
2026-10-23 01:07:27 +08:00
araharah-executor
9fa4acb319
fix(03-04): Telegram LocationManager deep-link — LOCATION SETTINGS CTA on denied cards + locationManagerUpdated chain re-run
2026-10-23 01:06:52 +08:00
araharah-executor
fff865f6cd
docs(03-04): log mid-gate debug round 1 (menu button + dead CTAs)
2026-10-23 01:01:20 +08:00
araharah-executor
b1d8768866
fix(03-04): web_app menu button on deployed origin + wire CTA actions on both denied-shaped cards
2026-10-23 01:00:27 +08:00
araharah-executor
fc183216c3
docs(03-04): complete one-deployable architecture plan — SUMMARY (checkpoint armed)
2026-10-23 00:46:44 +08:00
araharah-executor
5c155e393d
feat(03-04): Mock-Telegram runner page + Playwright capture harness — 7/7 captures + GEO-03 probe
...
- runner page: ?mock/?scheme/?pin/?locale profile block wholly inside if (__ARAHARAH_HARNESS__) — installer + /api/session + /api/location + /api/location-fallback fetch stubs dead-code-eliminated from production; main.ts import stays outside the guard
- harness-only ?sessiondelay/?fixdelay boot-stage photograph knobs (localhost resolves the chain in ms — staged BOOT-01/BOOT-02 cards need a hold)
- capture.mjs extends theme/scripts/screenshot.mjs: MIN_BYTES, WR-05 docroot guard, READY-signal race, dist-harness docroot, DENIED_LEG_TIMEOUT_MS=90000 for LINK 3's 60s pre-denial poll, timeout = hard failure with a signal diagnostic
- 7 captures: boot-1/boot-2 stages, live light+dark (theme-slot attribute asserted), Desktop denied card w/ ASK VIA CHAT, chat-pin relay LIVE, DSGN-02 side-by-side vs navigate_map_overview
- GEO-03 runtime probe: localStorage/sessionStorage/cookies/IndexedDB asserted empty after boot-to-live
- mock fixes (Rule 1): LocationManager delivery now uses the Telegram wire shape {latitude,longitude,horizontal_accuracy,course} (authoring shape mapped to undefined → NaN LngLat pageerror); languageCode→initData so localeFromInitData parses the real wire format
CAPTURE OK — 7/7 non-blank captures; GEO-03 probe PASSED
2026-10-23 00:37:58 +08:00
araharah-executor
8b39ea70c3
feat(03-04): Worker [assets] binding + one-command deploy + D-14 build-artifact gate
...
- wrangler.jsonc assets block serves ../web/dist; run_worker_first keeps /api/* + /telegram/* on the Worker (D-13)
- root npm run deploy = build theme → web → bot wrangler deploy + set-webhook (D-15); dev = build + wrangler dev --port 8787 --local (D-12)
- vite.config.ts dual-build: __ARAHARAH_HARNESS__ define keyed on --mode harness, separate dist/dist-harness outDirs
- main.ts guard unchanged; ambient constant declared once in web/src/vite-env.d.ts
- build-artifact.test.mjs BA1..BA6: zero CDN refs, self-hosted fonts, MapLibre worker, inlined style, no mock installer in ANY emitted file (HTML included)
2026-10-23 00:15:26 +08:00
araharah-executor
d573acc583
feat(03-03): status strip, state cards, recenter control, boot choreography — map-first, D-09 staged states
...
- strip.ts: six-state lamp+word left cluster, ±M / FIX Ns AGO telemetry (U+00B1 glyph), elapsed-seconds for acquiring
- cards.ts: boot/denied/lost builders from theme classes, machine-blink gantry (500ms JS duty cycle), GEO/SYS registers from strings.ts, D-06 CTA inversion (chat-fallback=btn-primary, retry=btn-secondary)
- recenter.ts: 40x40 plate w/ >=44 hit slop, orthogonal inline-SVG crosshair, three data-attribute notch states, no inline handlers
- main.ts: boot order map->session->chain (bootMap before acquireFix), null-map guards on every map consumer, ARAHARAH-LIVE emitted outside the guard, data-map=absent fallback, localeFromInitData, ASK VIA CHAT w/ D-03 revalidation, 1s tick re-running the chain at 45s staleness
- map.ts: attribution control moved bottom-left (UI-SPEC flush chip, compact)
- shell.css: attrib chip #map-scoped override (wins cascade over maplibre css), strip left cluster, recenter z-index
- vite.config.ts: define __ARAHARAH_HARNESS__ keyed on --mode harness (bare ambient global would ReferenceError in plain dev; Rule 3)
- session.test.mjs: SESS1-4 memory-token gates
2026-10-23 00:08:34 +08:00
araharah-executor
c437d312f6
feat(03-03): Rams shell stylesheet + MapLibre v6 bootstrap, position marker, follow controller
...
- shell.css: token-only chrome (zero hex, zero transition/animation), dark-slot activation, machined geometry (8px lamp/notch, 40x40 plate, data-map=absent field)
- map.ts: setWorkerUrl + ?worker&url, build-time-inlined liberty-rams.json, GPUInitializationError -> null gate, RAMS-BASEMAP-READY signal
- marker.ts: dot + accuracy circle (100m display cap) + heading cone hidden on null, DOM Marker SVG namespace discipline
- follow.ts: 96px camera padding, 400ms flyTo, user-gesture-only free mode
- UI-SPEC: planner amendments verified (Pitfall 4 present; Open Question 1 appended)
2026-10-22 23:53:18 +08:00
araharah-executor
83985c4a09
feat(03-03): copy module — UI-SPEC table verbatim (en+ms) + COPY1..6 copy gate
...
- web/src/i18n/strings.ts: 25-key ShellStrings, pickLocale verbatim from bot, localeFromInitData over the raw initData string (RESEARCH §Security V2)
- web/test/copy-gate.test.mjs: parity, content, fallback, no-inline-copy source-introspection (comments stripped), initData locale derivation
2026-10-22 23:51:05 +08:00
araharah-executor
4e4b75da00
docs(03-02): complete location chain core + Mock-Telegram harness plan — SUMMARY
...
4 tasks, 17 test cases green (GEO-01/02/03, PX-02), typecheck clean; 3 auto-fix
deviations documented; no STATE/ROADMAP writes (orchestrator-owned)
2026-10-22 23:47:47 +08:00
araharah-executor
2659b7f352
feat(03-02): D-11 Mock-Telegram harness + the four requirement gates (17 cases green)
...
- telegram-mock.ts: fake window.Telegram.WebApp injected into the SAME window
(never an iframe — Bot API 10.2 origin restriction, Pitfall 6); Web-Crypto
dev signer mirroring bot/src/security/initdata.ts's two-step HMAC (async
makeDevInitData — node:crypto stays out of the browser bundle path);
controllable LocationManager stream, themeChanged emitter, BackButton clicks
- location-chain.test.mjs (10 cases): GEO-01 version gate / null-WebApp guard
/ null-denial / hard timeout / stale-detector + one-read nudge; GEO-02 pin
pickup / bounded 60s poll / Desktop no-geolocation leg ' same denial keys
- no-storage.test.mjs (3 cases): GEO-03 comment-stripped grep gate over
web/src/**/*.{ts,html}, no-SW invariant, store.ts storage-assignment probe
- theme.test.mjs (4 cases): PX-02 colorScheme + luminance fallback + setStyle
source-introspection (Pitfall 7) + themeChanged re-apply; document stub
installed and restored per case
- Rule 1 fix in telegram.ts: looksStale/nudgeAndRetryTelegram accept an
omitted lastAccepted (undefined normalized to null) ' acquireFix(deps)
first-call contract
2026-10-22 23:46:17 +08:00
araharah-executor
0a35bce256
feat(03-02): Telegram platform wrappers — theme slot switch, BackButton total wire, safe-area union
...
- theme.ts: colorScheme → data-tg-theme on <html>; header_bg_color 0-1 luminance fallback
(T-03-11 — Telegram hex is a signal, never a consumed CSS value); applyTheme's ONLY
statement is the attribute set (Pitfall 7 / D-10, greppable invariant)
- backbutton.ts: hide() at init (one shell state), onClick is total — close() at the root,
no dead-ends (UI-SPEC §BackButton)
- safe-area.ts: env(safe-area-inset-*) probe ∪ WebApp.safeAreaInset, per-edge max,
version-gated at 8.0, applied as --safe-* custom properties on :root
- webapp.ts + backbutton/safe-area never read node_modules types;
@types/telegram-web-app stays dropped (web/package.json untouched)
2026-10-22 23:40:03 +08:00
araharah-executor
faab77a84f
feat(03-02): D-04 chain state machine + memory-only session store + /api/session client
...
- chain.ts: acquireFix tries telegram → webview → chat-pin in locked order; staleness
routes to the nudge inside link 1, never to success (Pitfall 2); pluggable cadence —
NO setInterval/watchPosition anywhere (Phase 6 picks, Open Question 2)
- isFixStale (45s = UI-SPEC signal-lost trigger) + fixAgeSeconds for FIX Ns AGO telemetry
- store.ts: module-scope token holder, zero persistence calls (the D-07 invariant);
SESSION_TTL_SECONDS = 900 mirrors bot/src/kv/sessions.ts by name (D-03)
- client.ts: posts VERBATIM initData as the body, validates token shape, maps 401
categories exactly (malformed/tampered/stale/network)
2026-10-22 23:39:16 +08:00
araharah-executor
9552e7e4ab
feat(03-02): Fix type + three source adapters (telegram/webview/chat-pin) — GEO-01 wrappers
...
- types.ts: the shared Fix shape + LocationState machine (type-only, D-04/D-05/D-07)
- telegram.ts: version-gated LocationManager init/getLocation, hard 8s timeout (Pitfall 3),
null-safe telegramLocationSupported (plain browser/Desktop = false, not TypeError),
looksStale + haversine + the Android nudge (issue #56 navbar read DISCARDED, then retry)
- webview.ts: one-shot geolocation read, maximumAge: 0 (freshness axis), 8s timeout
- chat-pin.ts: bounded 60s poll of GET /api/location (Bearer token) + POST /api/location-fallback
throw-on-fail so the ASK VIA CHAT handler can revalidate (D-03)
- telegram/webapp.ts created early (Rule 3: task 1 imports TelegramWebAppLike from task 3's
file; declared the narrow hand-rolled interface now, verbatim per plan)
2026-10-22 23:37:58 +08:00
araharah-executor
3fd0694ee6
chore(03-01): lockfile resolution for the web workspace (maplibre-gl, vite, playwright-into-web)
2026-10-22 23:34:40 +08:00
araharah-executor
1fefd90b6e
docs(03-01): complete web/_workspace + GEO-02 relay plan — SUMMARY
2026-10-22 23:34:33 +08:00
araharah-executor
ecaf242d0e
feat(03-01): GEO-02 server half both directions — chat-keyboard fallback + GET /api/location + POST /api/location-fallback (claim-scoped)
...
- handlers/location-fallback.ts: requestLocationFallback (ReplyKeyboardMarkup request_location:true copy from strings.ts), recordSharedPin, registerLocationFallback (filters message.location, T-03-03)
- strings.ts: awaitingPin/shareLocationButton/pinReceived in en+ms (CS1 parity) — all bot copy stays in strings.ts
- bot.ts: createBot threads env.chat_sessions into the fallback handler; optional client fetch seam for tests; one-caller rule documented
- webhook.ts: GET /api/location relay + POST /api/location-fallback trigger, both resolve chat_id & locale from getClaimByToken CLAIM, never client input (T-03-01/26/27); telegram-send failure is category-only 502 (T-03-28)
- location-pin.test.mjs: LP1–LP14 (TTL contract, range guard, cross-user isolation both routes, locale split); LP12/LP13 patch node-fetch's cached default (grammy's node shim transport), then restore
- CS4 scope untouched (handlers/ not scanned); CS1 parity automatic
2026-10-22 23:33:01 +08:00
araharah-executor
4fbbb0b516
feat(03-01): TTL-only KV location-pin layer under the existing privacy gates (GEO-03, PRIV-02)
...
- kv/location-pin.ts mirrors sessions.ts shape: writePin/getPin/clearPin, key loc:<chat_id> (chat-scoped, claim-derived — never user-id scoped across keys)
- PIN_TTL_SECONDS=300; writePin is the only write path, expirationTtl on the same line referencing the named constant
- getPin is a defensive read: parse guard + shape guard + |lat|<=90 / |lon|<=180 range guard (V5 Input Validation) — corrupt records return null
- privacy.test.mjs: storageModules now scans kv/location-pin.ts, so PG1 (same-line TTL) and PG2 (no persistence-shaped exports) apply automatically
2026-10-22 23:25:59 +08:00
araharah-executor
9376cabca2
feat(03-01): stand up web/ npm workspace with Wave-0 hand-rolled test runner (D-01, D-02, D-11, D-14)
...
- web/ workspace: TS + Vite shell (maplibre-gl 6.15.0, vite 8.3.5, TS 5.9.3; no UI framework, no Telegram SDK script tag)
- tsconfig mirrors bot/ strictness byte-for-byte except the three authorized keys (DOM lib, vite/client types, resolveJsonModule)
- test/runner.mjs + harness.mjs copied verbatim from bot/test/ (body-identical past header)
- root package.json: web workspace + web:* delegate scripts
- web/src/main.ts entry module created (tsc include:['src'] needs ≥1 input; 03-02/03-03 mount here)
2026-10-22 23:24:41 +08:00
araharah-executor
af691ae40e
fix(02-bot-skeleton-initdata-security): WR-03 honest rotate-on-new invariant + best-effort post-mint reconciliation (fold in IN-01b dead branch, IN-01c Phase-4 notes)
2026-10-22 20:21:11 +08:00
araharah-executor
3ea1fdd932
fix(02-bot-skeleton-initdata-security): WR-02 fail-closed /telegram/webhook — unarmed WEBHOOK_SECRET rejects (constant 500, category-only log) before grammY's accept-everything compare
2026-10-22 20:18:34 +08:00
araharah-executor
8995498bff
fix(02-bot-skeleton-initdata-security): WR-01 cap /api/session body at 4 KB before JSON split (413, category-only logs)
2026-10-22 20:17:34 +08:00
araharah-executor
aedff86542
docs(02-03): record D-16 deploy-gate APPROVAL + finalize SUMMARY
...
- User verdict verbatim in 02-03-APPROVAL.md: "it works! Menu or / has /help and /privacy! approved!"
- Walkthrough checks a-e all green; reply-language D-05 behavior confirmed (no force-ms)
- Four live-debug remediations documented: webhook path, revoked runtime BOT_TOKEN, empty webhook re-arm, menu cache (setChatMenuButton + all_private_chats scope)
- SUMMARY finalized: 3/3 tasks, APPROVED walkthrough, self-check PASSED
2026-10-22 19:57:28 +08:00
araharah-executor
d600d6e71a
fix(02-03): set-webhook auto-appends /telegram/webhook to a pathless URL
...
- Deploy walkthrough revealed a bare workers.dev origin setWebhook answers ok but drops updates at / (404)
- Normalize WEBHOOK_URL: no path -> append /telegram/webhook; invalid URL -> fail fast, never echo values (T-02-04)
- .dev.vars.example documents the path expectation
2026-10-22 19:56:24 +08:00
araharah-executor
2ea7f6edc7
docs(02-03): finalize SUMMARY — deploy record, live security smokes, walkthrough gate pending
...
- Deployment record: workers.dev URL, KV namespace id, secrets set-once, setWebhook + setMyCommands (en/ms) ok
- Live smokes: webhook 401 (no/wrong secret), /api/session 401 malformed + 405, 404 fallback, KV baseline []
- Deviation: production secrets uploaded via wrangler secret put (deploy chain is set-once for secrets)
2026-10-22 18:53:55 +08:00
araharah-executor
492a97bd89
fix(02-03): wire chat_sessions KV namespace id (created via wrangler kv namespace create)
...
- Replace KV_ID_PLACEHOLDER with real namespace id (non-secret, account-scoped)
- Closes the deliberate deploy-checkpoint input from task 2
2026-10-22 18:45:44 +08:00
araharah-executor
c8f064f65a
docs(02-03): complete command surface + Worker wiring plan (deploy checkpoint pending)
...
- SUMMARY for tasks 1-2 (b4393fb , df3b7d6 ): strings module + text-only
command surface, Worker entry with webhook auth + /api/session gate,
registration/deploy scripts, all suites green (27/27, dry-run exit 0)
- task 3 deploy gate returned to orchestrator: BOT_TOKEN + Cloudflare
auth + KV namespace id required before the real-client walkthrough
- STATE.md / ROADMAP.md untouched (orchestrator-owned)
2026-10-22 11:50:53 +08:00
araharah-executor
df3b7d65c1
feat(02-03): Worker entry — webhook route + /api/session security gate + deploy plumbing (D-11, D-14, D-16, D-17)
...
- src/webhook.ts: routes exactly /telegram/webhook (grammY cloudflare-mod
adapter, constant-time secret-token auth against env.WEBHOOK_SECRET) and
POST /api/session (validateInitData → 401 category-only rejections →
mintSession one-time token; single mint path, no extra branch — T-02-01/02/06)
- D-14: the only log statement is '[initdata] rejected: <category>' — no
payload, ids, or timestamps
- scripts/set-webhook.mjs: setWebhook with secret_token + allowed_updates
[message], secrets read from gitignored .dev.vars, token never echoed
- bot deploy script chains wrangler deploy + set-webhook; wrangler.jsonc
gains workers_dev (webhook URL target); KV id stays placeholder for the
deploy checkpoint
- verified: 27/27 tests, typecheck clean, wrangler deploy --dry-run exit 0
2026-10-22 11:49:43 +08:00