12 KiB
AGENTS.md — Tolaria App
1. Development Process
Start working on a task
Before writing a single line of code: read GLS-0101, GLS-0247, and GLS-0844, then inspect the repository-owned validation commands. HoloLake accepts only a GHNQG receipt bound to the exact commit and tree. The only terminal states are GHNQG_PASS_100 and GHNQG_FAIL_0; no external score, account, subscription, badge, or service can authorize or block Guanghu publication.
- Read task description and all comments fully
- For To Rework: the ❌ QA failed comment tells you exactly what to fix
- Check
docs/adr/for relevant architecture decisions before structural choices - Check
docs/ARCHITECTURE.mdanddocs/ABSTRACTIONS.mdfor relevant structural information - For UI tasks: study app visual language and components first. Prioritize reusing existing components, assets, and variables over recreating them.
- If working on a Todoist task, add a comment:
🚀 Starting work on this task. [Brief description of approach]
Commits & pushes
- Local work may happen on
main, in detached HEAD worktrees, or in other temporary local states. The production path is still direct-to-main: final verified work is pushed toorigin/main, with no PR branch flow. - Keep publication paths distinct:
- normal product promotion is verified Git
main -> origin/main; - an explicitly authorized Fifth Domain prototype may publish an allowlisted branch through
HoloLake -> Guanghu Router -> JD-FD-PRIMARY -> code channel, with an exact remote-head check and arepo_push_succeededreceipt; - a Router branch receipt proves repository publication only. It is not a merge to
main, a release, a deployment, or service health.
- normal product promotion is verified Git
- Commit every 20–30 min:
feat:,fix:,refactor:,test:,docs: - Pre-commit is a lightweight lint gate only. Pre-push runs the repository-owned checks, validates the active-authority surfaces, and emits the native GLS-0844 result. Prefer three sidecar lanes for observation and execution speed: frontend lint/build/tests, Rust tests, and Playwright smoke. Sidecars never become quality authorities.
- A production-promotion task is not done until
git push origin mainsucceeds. A scoped Fifth Domain prototype publication is not done until the Router returns the published SHA and a fresh public read-back matches it. If a repository-owned hook blocks, fix the failing check and retry. ⛔ NEVER use --no-verify
TDD (mandatory)
Red → Green → Refactor → Commit. One cycle per commit. For bugs: write failing regression test first, then fix. Exception: pure CSS/layout changes.
Test quality (Kent Beck's Desiderata): Isolated · Deterministic · Fast · Behavioral · Structure-insensitive · Specific · Predictive. Fix flaky tests first. Prefer E2E over unit tests for user flows.
Localization (mandatory for UI copy)
All user-facing UI labels/copy must live in src/lib/locales/en.json and be translated into every target listed in lara.yaml. When adding or changing interface copy:
pnpm l10n:translate
Use pnpm l10n:translate:force only when intentionally regenerating existing translations. Commit src/lib/locales/*.json, lara.yaml/lara.lock changes if produced, and verify placeholders/product names stayed intact.
Product analytics (mandatory for meaningful features)
New features should almost always emit a PostHog event so we can see whether users actually discover and use them. Skip instrumentation only for very small changes where a dedicated event would create noise. Use clear, stable event names, avoid PII or note content, and include only safe metadata that helps evaluate adoption and failures.
When adding or changing a meaningful user-facing feature, include the event name(s) in the Todoist completion comment alongside QA, docs, and code health. If intentionally not instrumenting a feature, explain why in the completion comment.
Guanghu native quality authority (mandatory)
GLS-0844 (GHNQG) is the sole quality authority. Repository-owned lint, type checks, tests, protocol validation, format checks, security invariants, exact source fingerprints, and auditable core coverage are required evidence. Never add // eslint-disable, #[allow(...)], or as any.
- Every required gate is either complete (
100) or incomplete (0). - The aggregate result is
PASS_100only when every required gate is complete; any incomplete gate makes the aggregateFAIL_0. - Percent-above-minimum, weighted scores, waivers, “mostly passing”, and unconfigured-observer states are not acceptance states.
- Coverage is exact only for a declared auditable scope. Undeclared scope is incomplete, not implicitly accepted.
- External services may be used as non-authoritative observations only when a human explicitly requests them. Their configuration and result never enter a HoloLake gate or receipt.
- Before commit, run
bash scripts/test-guanghu-native-authority.sh. Before publication, run the GLS-0844 executor and bind its receipt to the exact commit and tree.
Evidence suite (runs before the native receipt)
pnpm test:native-authority
pnpm lint && pnpm exec tsc --noEmit && pnpm test
cargo test --manifest-path src-tauri/Cargo.toml
For bug fixes, add a regression test when practical. For new behavior, add targeted coverage close to the changed code; do not rely only on broad E2E coverage. Observed coverage may guide work, but only the declared auditable GHNQG core scope can produce the exact native coverage gate.
UI and native QA
Phase 1 — Playwright (only for core user flows):
Write Playwright test in tests/smoke/<slug>.spec.ts only if feature touches: vault open, note create/save/delete, search, wikilink navigation, git commit/push, conflict resolution. Tag a test with @smoke only if it protects a core pre-push workflow. Do NOT tag cosmetic or mock-heavy checks — keep those in the full regression lane. Prefer .chunk/run-playwright-smoke.sh on a Chunk sidecar for the curated smoke lane because local Playwright is expensive; keep pnpm playwright:smoke available for focused local reproduction. The curated smoke suite must stay under 5 minutes when sharded on sidecars; use pnpm playwright:regression for the full Playwright pass.
pnpm dev --port 5201 &
sleep 3
BASE_URL="http://localhost:5201" npx playwright test tests/smoke/<slug>.spec.ts
Phase 2 — Native app QA:
pnpm tauri dev &
sleep 10
bash ~/.openclaw/skills/tolaria-qa/scripts/focus-app.sh laputa
bash ~/.openclaw/skills/tolaria-qa/scripts/screenshot.sh /tmp/qa-native.png
Use computer-use/browser-control style interaction for native UI QA when available: click, hover, drag, select, scroll, and type the way a real user would with the mouse and trackpad. For every UI feature, test the primary mouse-driven path first, then verify any relevant keyboard shortcut or keyboard-first workflow still works. Tolaria is still a keyboard-first app, but QA must not assume users only interact by keyboard.
Use osascript for app focus, keyboard shortcuts, and keyboard-specific checks. ⚠️ WKWebView: osascript keystroke can be blocked inside editor content — use computer use for native editor interaction when possible, and rely on Playwright for deterministic text-input coverage. Write result as Todoist comment (✅ or ❌).
Release-readiness checklist
Before pushing or moving a task to In Review, verify the release gates and add a completion comment to the Todoist task. The comment must include:
- What was implemented (a few lines covering logic and UX/UI).
- QA: what was tested and how (Playwright / native screenshot / osascript).
- Tests/coverage: commands run and final coverage result.
- GHNQG:
PASS_100orFAIL_0, plus the exact commit, tree, receipt path, and declared coverage scope. - Localization: any user-facing copy lives in
src/lib/locales/en.json,pnpm l10n:translatewas run, andpnpm l10n:validatepasses. If no copy changed, say “Localization: no UI copy changes”. - PostHog: meaningful new user actions/events are instrumented with safe metadata; noisy/minor changes explicitly say “PostHog: no event needed because …”.
- Refactoring: any files refactored to satisfy native invariants, or "none needed".
- ADRs: any new/updated ADRs, or "none".
- Docs: any updated docs (
ARCHITECTURE.md,ABSTRACTIONS.md, etc.), or "none". - Demo vault dirt checked:
git status --short -- demo-vault demo-vault-v2is empty unless fixture changes are intentional.
ADRs & docs
ADRs live in docs/adr/. Create in the same commit as the code. Never edit existing — create a new one that supersedes. Use /create-adr. When: new dependency, storage strategy, platform target, core abstraction, cross-cutting pattern. Not for: bug fixes, styling, refactors.
After any Tauri command, new component/hook, data model change, or new integration: update docs/ARCHITECTURE.md, docs/ABSTRACTIONS.md, and/or docs/GETTING-STARTED.md in the same commit.
2. Product Rules
Demo vault hygiene (demo-vault/, demo-vault-v2/)
Default to demo-vault-v2/ for testing.
- Treat
demo-vault/anddemo-vault-v2/as disposable QA fixtures unless the task explicitly changes demo content. - If you create untracked notes, attachments, or other temporary files there for testing, delete them before the task is complete.
- If you modify tracked demo-vault files only to test or QA behavior, revert those edits before the final commit.
- Before declaring a task done, make sure
git status --short -- demo-vault demo-vault-v2is empty unless demo fixture changes are part of the task. - If a fresh run starts and the only local dirt is inside
demo-vault/ordemo-vault-v2/, clean those paths first and continue. That case is recoverable QA residue, not a blocker.
User vault (~/Laputa/)
Default to demo-vault-v2/. If you must use ~/Laputa/ for testing:
- Never commit or push any test notes to the remote vault
- Delete all test notes from disk when done — do not leave untitled or temporary notes on the filesystem. Run
cd ~/Laputa && git checkout -- . && git clean -fdto restore the vault to its last committed state. - Rationale: test notes pollute the local vault over time, making it a collection of nonsensical untitled files. The vault must stay clean on disk, not just on the remote.
UI components — mandatory rules
Always use shadcn/ui components. Never use raw HTML form elements (<input>, <select>, <button>, native <input type="date">, etc.) for user-facing UI. Every interactive element must use the shadcn/ui equivalent:
| Need | Use |
|---|---|
| Text input | Input from shadcn/ui |
| Dropdown/select | Select from shadcn/ui |
| Date picker | Calendar + Popover from shadcn/ui (NOT native <input type="date">) |
| Button | Button from shadcn/ui |
| Autocomplete/combobox | Reuse existing combobox components from the app (check src/components/) |
| Wikilink picker | Reuse the wikilink autocomplete component already used in the editor and Properties panel |
| Emoji picker | Reuse the emoji picker component already used for note/type icons |
| Color picker | Reuse the color swatch picker used for type customization |
| Toggle/switch | Switch or ToggleGroup from shadcn/ui |
| Dialog/modal | Dialog from shadcn/ui |
When in doubt: search src/components/ for an existing component before building new. Visual language: all new UI must feel native to Tolaria — if it looks like a browser default, it's wrong.
3. Reference
macOS / Tauri gotchas
Option+N→ special chars on macOS. Usee.codeorCmd+N- Tauri menu accelerators:
MenuItemBuilder::new(label).accelerator("CmdOrCtrl+1") app.set_menu()replaces the ENTIRE menu bar — include all submenusmock-tauri.tssilently swallows Tauri calls — not a substitute for native testing
QA scripts
bash ~/.openclaw/skills/tolaria-qa/scripts/focus-app.sh Tolaria
bash ~/.openclaw/skills/tolaria-qa/scripts/screenshot.sh /tmp/out.png
bash ~/.openclaw/skills/tolaria-qa/scripts/shortcut.sh "command" "s"
Diagrams
Prefer Mermaid (flowchart, sequenceDiagram, classDiagram, stateDiagram-v2). ASCII only for spatial wireframe layouts.