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
araharah-executor
b4393fbcf3
feat(02-03): strings module + text-only command surface with Malay aliases (D-01..D-05)
...
- src/i18n/strings.ts: single copy source of truth, en + ms identical
key-sets, clinical/honest start + privacy copy, pickLocale fallback rule
- /start /mula, /help, /privacy /privasi handlers: plain text replies with
link previews disabled, zero menu/button surface (D-02, grep-gated)
- createBot(env) factory registers exactly the phase command stack
- scripts/register-commands.mjs: one-time setMyCommands, two scopes
(default + language_code ms), descriptions derived from helpMenu —
no inline copy, no future-command stubs (D-03/D-05)
- test/commands.test.mjs: CS1-CS6 gates — locale parity, pickLocale
matrix, PRIV-01 copy gate vs never-facts + TTL wording, D-02 structural
grep, D-03 menu gap-freedom, D-04 alias completeness (27 passing)
2026-10-22 11:48:50 +08:00
araharah-executor
632ae70ad2
docs(02-02): complete initData validator + TTL-only KV sessions plan
2026-10-22 11:44:12 +08:00
araharah-executor
e9aec5833b
feat(02-02): TTL-only KV sessions with rotate-on-new + PRIV-02 storage gates (D-06/D-07/D-08/D-14)
...
- sessions.ts: mintSession (crypto.randomUUID opaque token, T-02-05), rotate-on-new deletes prior session record via chat pointer (D-07), both puts carry expirationTtl: SESSION_TTL_SECONDS on the call line (PRIV-02)
- SESSION_TTL_SECONDS = 900 pairs the session envelope with the D-13 freshness window
- SessionClaim is exactly D-08: user_id, chat_id, issued_at, language_code — nothing else serializes to storage
- sessions.test.mjs: in-memory KV fake asserting finite expirationTtl on every put; D-08 key-set equality; rotate removes old token; expired-token → null (D-14 class)
- privacy.test.mjs: PG1 same-line expirationTtl source gate (auto-tightens to webhook.ts when plan 03 adds it) + PG2 no persistence-shaped exports
- 18/18 PASS across initdata + sessions + privacy suites; full plan GREEN
2026-10-22 11:43:20 +08:00
araharah-executor
54bffe728c
feat(02-02): validateInitData — SubtleCrypto HMAC core with rejection classes (D-13, D-14)
...
- GREENs the plan-01 RED vector suite: T1-T7 all PASS (10/10 cases)
- Telegram-verified two-step key derivation: secretKey = HMAC(botToken, key=salt), checkHex = HMAC(dataCheckString, secretKey bytes)
- Sort by field name, hash/signature excluded, values decoded once with '+' literal (no URLSearchParams)
- Rejection precedence: malformed (hash/user.id/auth_date) -> tampered (timing-safe hex compare) -> stale (>900s, D-13)
- Hand-rolled WebAppInitUser/WebAppInitChat types (grammy ships none); zero deps of any kind — pure (raw, botToken, opts)
2026-10-22 11:41:46 +08:00
araharah-executor
1f15ad202b
docs(02-01): complete bot scaffold + RED initdata suite plan
2026-10-22 11:39:09 +08:00
araharah-executor
fc5001a4eb
test(02-01): hand-rolled harness + RED initdata vector suite (D-12, TDD RED)
...
- bot/test/harness.mjs: zero-dep registry (test(name, fn))
- bot/test/runner.mjs: auto-discovers *.test.mjs, suite-load failure -> FAIL case, exit 0 iff all green
- bot/test/initdata.test.mjs: T1-T7 vector contract signed via node:crypto in-suite
(T1 known-good, T2 tampered, T3 stale 3600s, T4 boundary 899/901, T5 order-independence,
T6a-c malformed, T7 RFC-4231 node:crypto independence pin)
- demonstrated RED: 8 FAILs / exit 1 against missing src/security/initdata.ts; GREEN lands in plan 02
2026-10-22 11:38:06 +08:00
araharah-executor
c9b6ba402d
feat(02-01): bot workspace scaffold with Env contract (D-09/D-10/D-11/D-15)
...
- bot/ npm workspace sibling to theme/: grammy ^1.46.0, wrangler ^4.151.3, TS ^5.9.3
- src/config.ts exports Env (BOT_TOKEN, WEBHOOK_SECRET, chat_sessions KVNamespace)
- wrangler.jsonc: main src/webhook.ts + chat_sessions KV binding (id filled in plan 03)
- .gitignore ships .dev.vars/.wrangler/ in the same commit as .dev.vars.example (D-17)
- root delegate scripts bot:test/typecheck/dev/deploy/commands
2026-10-22 11:35:54 +08:00
araharah-executor
43b7d991e4
fix(01-design-tokens-rams-foundation): WR-05 static server docroot guard ends prefix with separator
2026-10-22 09:39:30 +08:00
araharah-executor
5e254cb851
fix(01-design-tokens-rams-foundation): WR-04 audit spacing + typography numerics per D-13 (token scales, font-face exempt)
2026-10-22 09:39:16 +08:00
araharah-executor
ee48e760f8
fix(01-design-tokens-rams-foundation): WR-03 audit named colors, modern color functions, text-shadow
2026-10-22 09:37:38 +08:00
araharah-executor
5e95741364
fix(01-design-tokens-rams-foundation): WR-02 repair familiesFromShorthand + flag literal font: shorthands
2026-10-22 09:36:34 +08:00
araharah-executor
689bc9ff4b
fix(01-design-tokens-rams-foundation): WR-01 scope @source to mockup files + disable deprecated bare shadow/blur keys
2026-10-22 09:35:41 +08:00
araharah-executor
61d15c28a8
fix(01-design-tokens-rams-foundation): CR-01 drive bare rounded via deprecated --radius key (0px)
2026-10-22 09:34:45 +08:00
araharah-executor
67df693268
docs(01-04): finalize summary — DSGN-02 approved, plan complete (3/3)
...
- status banner: tasks 3/3; DSGN-02 APPROVED (verbatim 'approved', no fix list)
- requirements-completed: [DSGN-02] (REQUIREMENTS.md/STATE.md/ROADMAP.md marking
deferred to the orchestrator per wave-parallel convention, matching 01-01/02/03)
- task 3 commits: f51e714 (approval record) + 7d6845a (gallery script wiring)
- deviation #4 documented: [Rule 1] broken root gallery delegate repaired
- duration 22min total; self-check PASSED (5 files, 7 commits, no deletions)
2026-10-22 08:54:57 +08:00
araharah-executor
7d6845a05b
fix(01-04): wire theme gallery script — repair root delegate per 01-01 contract
...
- root 'npm run gallery' delegate pointed at a missing theme script since wave 1
(01-01 contract: plan 04 wires the 'gallery' slot; tasks 1-2 wired audit/capture only)
- gallery = one-command DSGN-02 review loop: build -> capture -> serve theme/ on :8123
(fresh-checkout safe: dist + captures regenerate; fallback contract intact per D-06)
- verified: JSON valid in both manifests; resolution from root + theme; build 114ms;
CAPTURE OK 6/6 non-blank (sheet + basemap byte-identical to approved set, mockups
<=107B render variance, zero fallbacks); AUDIT CLEAN (354 declarations, 0 off-token);
serve link proven live (basemap:preview serving gallery.html 200 on :8123)
2026-10-22 08:53:22 +08:00
araharah-executor
f51e7148df
docs(01-04): record DSGN-02 user approval — fidelity bar + basemap direction approved
...
- verbatim response "approved"; no fix list — checkpoint passed
- provenance: reviewed URLs, approved artifact commits (waves 1-3 + 01-04 tasks 1-2), capture manifest
- evidence re-verified at record time: build OK, audit CLEAN (354 declarations, 0 off-token), 6/6 captures >= 10KB
- gate consequence: DSGN-02 PASSED for Phase 1; later UI phases extend the gallery mechanism (D-12)
- notes post-approval wiring: theme gallery script (01-01 contract slot) follows next
2026-10-22 08:52:25 +08:00
araharah-executor
c3d802a646
docs(01-04): audit + capture + gallery plan summary — DSGN-02 checkpoint pending
...
- 16/16 audit TDD green, real build AUDIT CLEAN (354 declarations, 0 off-token)
- 6/6 non-blank Playwright captures; gallery mechanism (D-12) committed
- tasks 1-2 complete; task 3 (blocking DSGN-02 approval) awaiting user verdict
2026-10-22 08:33:26 +08:00
araharah-executor
b462936678
feat(01-04): Playwright capture toolchain + DSGN-02 approval gallery (D-14, D-12)
...
- screenshot.mjs: committed real-browser capture tool — tiny node static
server (theme/ docroot), sheet fullPage capture (390px), 4 mockup captures
via file:// (network CDN renders; committed screen.png fallback on failure —
mockups never edited, D-06), basemap capture gated on the proof page's
RAMS-BASEMAP-READY console signal + 2s tile settle (1280x800); blank gate
>=10KB per capture; wired as root+theme `capture`
- gallery.html: the DSGN-02 mechanism template — 4 mockup-vs-sheet comparison
rows + basemap direction row + token ledger (13 typography specimens + 6 hero
color swatches, names only per D-07) + approval scope strip; CDN-free, built
from dist/rams.css + var()-only page shell; every later UI phase extends
this same page
- audit.mjs: gallery.html registered as an implementation page — audit
covers its <style> block + style attributes + class harvest (354
declarations, still 0 off-token)
- verified: CAPTURE OK 6/6 (45KB-1.2MB), gallery render check 0 failed
requests / all 6 images decode, AUDIT CLEAN
2026-10-22 08:31:14 +08:00
araharah-executor
0b3eebf7d0
feat(01-04): audit inline style attributes — close D-13 evasion path (GREEN)
...
- implementation pages' style="…" attributes are rendered CSS: every
declaration checked like <style>-block CSS, violations reported as
file:line: style attribute { prop: value }
- token-var references pass by construction; only off-token literals flag
- 16/16 audit tests green; real build still AUDIT CLEAN
2026-10-22 08:28:43 +08:00
araharah-executor
9ba73f207d
test(01-04): add failing inline-style-attribute audit test (RED)
...
- T8: style="color: #00ff00" on an implementation page currently passes
silently — an evasion path around the <style>-block scan (Rule 2 hole
in the D-13 evidence: the gallery itself will use style attributes)
2026-10-22 08:28:30 +08:00
araharah-executor
b39317de64
feat(01-04): automated off-token audit (GREEN) — D-13
...
- audit.mjs: zero-dep rendered-CSS scanner — flags off-token hex/rgb()/hsl()
literals, non-sanctioned font families, non-zero border-radius, box-shadow,
backdrop-filter, blur/drop-shadow; violations printed as file:line: declaration
- drift guards (exit 2): <40 color tokens, any non-zero --radius-* token,
missing token sheet / registered page / CSS input — no silent passes (T-1-07)
- scope adjudication: framework layers + @property --tw-* skipped; @layer
utilities audited only for classes used by implementation pages (mockup
vocabulary is reference material, D-06; sheet/basemap pages are the registry)
- token-hue+alpha 8-digit forms sanctioned; rounded-full sanctioned as circle
primitive (spec geometry — puck/medallion signets); 50% radius stays flagged
- wired: theme npm audit + test scripts (root audit delegate resolves)
2026-10-22 08:26:57 +08:00
araharah-executor
6a7c256c62
test(01-04): add failing off-token audit tests (RED)
...
- TDD harness for the D-13 audit: 13 checks across 7 test groups
- clean/dirty/drift/components-layer/used-utilities fixtures under /tmp/opencode
- real-build integration test (npm run build + default dist audit → exit 0)
- contract: exit 0 clean, 1 violations (file:line: declaration), 2 token drift
2026-10-22 08:23:40 +08:00
araharah-executor
1544b92b31
docs(01-design-tokens-rams-foundation-03): complete Rams cartography basemap plan
...
- 2/2 tasks: build script + token-derived style JSON, browser proof page with signal-orange route placeholder
- real-browser render proof 8/8: grayscale grounding pixel-verified, zero accent leaks, route accent on top
- D-08/D-09/D-10 satisfied; 3 Rule-1 deviations documented (rail regex, line-join spec, preview docroot)
2026-10-22 08:11:33 +08:00
araharah-executor
2332779ad6
feat(01-design-tokens-rams-foundation-03): browser proof page — Rams basemap + signal-orange route placeholder at KL metro
...
- index.html: MapLibre GL v4 viewer loading ./liberty-rams.json at the KLCC anchor (101.6958, 3.1513, zoom 13); page chrome token-only (var(--color-*) via ../dist/rams.css, self-hosted Geist/Space Grotesk per D-10/D-16)
- placeholder route vector: 6px signal-orange polyline + 1px matte-black dashed centerline (mockup route ribbon), color read from the token package at runtime (var(--color-signal-orange)); route layers added LAST (accent lives above grayscale, never inside it); README comment marks the vector as consumed by Phase 5
- basemap:preview script: python3 -m http.server 8123 (cwd=theme serves /basemap/ + /dist/rams.css + /fonts within one docroot — plan's cd-variant was doubly broken; open http://localhost:8123/basemap/ )
- real-browser render proof (scratch, plan 04 owns committed capture tooling): 8/8 checks pass — maplibre style validation clean, zero failed requests/non-200s, 296 sampled orange route pixels, 0 saturated non-red-hue pixels (grayscale grounding proven pixel-level), 100% warm-gray map area, header chrome rgb(26,26,26)
2026-10-22 08:10:05 +08:00
araharah-executor
891caa1c5f
feat(01-design-tokens-rams-foundation-03): Rams cartography basemap — liberty fork derived from token package
...
- build.mjs: fetches OpenFreeMap liberty style, parses theme/src/tokens.css, derives the full role palette in-script via desaturate(tokenHex, satMultiplier, lightnessPerRole) — no hand-tuned cartography hex (D-09)
- liberty-rams.json (110 layers): grayscale/muted land + water, desaturated roads (hierarchy by weight only), muted matte-black labels at reduced opacity, zero-radius aesthetic enforced (halo-blur zeroed, building-3d faux-3D removed) (D-08)
- accent guard: build fails if #EB8008/#ED3F1C/#736B1E (or rgb forms) leak into layers — route accent reserved for Phase 5
- D-10 font fallback: Space Grotesk/Geist probed on glyphs endpoint (404) → Noto Sans Bold/Regular substituted, recorded in style.metadata rams-font-substitutions
- raster relief desaturated (raster-saturation -1); derivation provenance embedded in style.metadata rams-cartography
- theme/package.json: basemap script
2026-10-22 08:05:54 +08:00
araharah-executor
d345e8c1aa
docs(01-design-tokens-rams-foundation-02): complete component-sheet plan
...
- 01-02-SUMMARY.md: component layer + rendered sheet, 41/41 real-browser
token audit, 4 auto-fixed deviations, plan-04 readiness notes
2026-10-22 07:54:41 +08:00
araharah-executor
baab797b42
fix(01-design-tokens-rams-foundation-02): name signal-orange token in sheet doc comment
...
- must-have artifact marker: sheet.html now references --color-signal-orange
in its documentation comment (token name only, no values — D-07)
- sheet markup unchanged; 41/41 computed-style audit re-verified
2026-10-22 07:54:19 +08:00
araharah-executor
e95f4043b9
feat(01-design-tokens-rams-foundation-02): rendered component sheet — all mockup-derived families via token package
...
- sheet.html: typography specimen (all 13 scale entries), buttons, inputs, chips (CONGESTION / CRASH / BLOCK / POLICE RADAR), telemetry card (SEC-04 // SPEED), maneuver banner, checkbox + two-way toggle
- consumes built dist/rams.css only; markup uses component classes, no utility soup; inline SVG icons (no icon-font CDN, D-16); shell consumes --shell-bg/--shell-on-surface slots (D-04)
- package.json: sheet script (build + open hint)
- real-browser computed-style audit: 41/41 checks render from tokens; woff2 fonts verified loaded
2026-10-22 07:52:56 +08:00
araharah-executor
84066fde65
feat(01-design-tokens-rams-foundation-02): component layer — Rams component classes built only from tokens
...
- components.css: btn-primary/btn-secondary, input-field, card (+header/ref/content), chip-traffic/hazard/safe, maneuver-banner/arrow, checkbox, toggle, full text-* helper scale
- every value is a var(--color-*)/var(--spacing-*)/var(--type-*) reference; zero hex, zero non-zero radius; only sanctioned border geometry (1/2/3px) and the 18x18 checkbox square as literals
- theme.css: @import ./components.css as last import (D-11 mockup-derived scope)
2026-10-22 07:50:31 +08:00
araharah-executor
95fe82b04e
docs(01-design-tokens-rams-foundation-01): complete design-tokens foundation plan 01-01
...
- Token package (104 verbatim tokens) + self-hosted fonts + v4 build verified
- 3/3 tasks, 4 task commits, 3 auto-fixed deviations (send cp target, ./tokens.css import, git identity)
- STATE.md/ROADMAP.md intentionally untouched (orchestrator owns wave-parallel writes)
2026-10-22 07:39:00 +08:00
araharah-executor
0009cc47e4
docs(01-design-tokens-rams-foundation-01): supersede root DESIGN.md specifics; point README at token package
...
- DESIGN.md: 3-line SUPERSEDED-FOR-SPECIFICS banner at very top (D-05) — token package is the single source of truth; conflicting typography claims (Helvetica/Inter, 5-color palette) explicitly superseded; Rams philosophy prose kept
- README.md: Design system section — theme/ token package, consume via theme/src/tokens.css import or npm run build; no numeric values restated (D-07)
2026-10-22 07:37:35 +08:00
araharah-executor
2b36b37df1
feat(01-design-tokens-rams-foundation-01): Telemetry Rams token package — tokens, self-hosted fonts, v4 build
...
- tokens.css: @theme static with the full verbatim vocabulary from telemetry_rams/DESIGN.md — 55 colors, 10 spacing (8px grid), 4 font-family aliases, 9 zero-radius tokens; typography scale as :root compound vars (--type-*, 13 tokens x font shorthand + tracking companion)
- theme.css: @import tailwindcss + tokens, @source the mockup screens (vocabulary candidates, D-02/D-06) + safelisted font-geist/font-space-grotesk, 7 self-hosted @font-face blocks (Geist 400/500/600/700, Space Grotesk 400/600/700, woff2 from Fontsource, font-display block), Telegram light/dark shell slots (D-04)
- fonts: 7 woff2 files under theme/fonts/ (D-16 — no Google Fonts CDN)
- package-lock.json: pins tailwindcss 4.3.3 + @tailwindcss/cli 4.3.3 + playwright 1.64.1
2026-10-22 07:37:18 +08:00
araharah-executor
8dea270bbe
chore(01-design-tokens-rams-foundation-01): scaffold npm workspace + theme package
...
- Root package.json: araharah, private, type module, workspaces [theme], scripts delegating to theme (build/sheet/gallery/audit/capture)
- theme/package.json: @araharah/theme with tailwindcss v4 + @tailwindcss/cli v4 devDeps, playwright dep (plan 03/04 captures), build + send scripts (D-15, D-17 local-only)
2026-10-22 07:33:18 +08:00
araharah-executor
506ff68976
chore(01-design-tokens-rams-foundation-01): commit design baseline — Rams docs, mockups, agent skills
...
- Root Rams design docs (DESIGN.md, IDEAS.md) and GSD install-fix notes (GSD_FIX.md, gsd-fix.sh)
- Four Telemetry Rams mockup screens + telemetry_rams/DESIGN.md (canonical token frontmatter)
- .agents/ project skills (design-taste-frontend) + skills-lock.json
- .gitignore: node_modules/dist/env secrets/OS junk; .planning stays local-only; Zone.Identifier scrubbed (9 files deleted)
2026-10-22 07:33:04 +08:00