opencode-skills-collection 4.1.2 → 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundled-skills/.antigravity-install-manifest.json +9 -1
- package/bundled-skills/antigravity-maintainer-batch-release/SKILL.md +15 -1
- package/bundled-skills/deep-research-framework/SKILL.md +81 -0
- package/bundled-skills/five-axis-code-review/SKILL.md +78 -0
- package/bundled-skills/git-commit-message/SKILL.md +76 -0
- package/bundled-skills/idea-to-blueprint/LICENSE +21 -0
- package/bundled-skills/idea-to-blueprint/SKILL.md +260 -0
- package/bundled-skills/idea-to-blueprint/assets/AGENTS.md.template +38 -0
- package/bundled-skills/idea-to-blueprint/assets/CLAUDE.md.template +38 -0
- package/bundled-skills/idea-to-blueprint/assets/DECISIONS.md.template +14 -0
- package/bundled-skills/idea-to-blueprint/assets/PROGRESS.md.template +47 -0
- package/bundled-skills/idea-to-blueprint/assets/session-prompt.md +23 -0
- package/bundled-skills/idea-to-blueprint/references/architecture-decisions.md +202 -0
- package/bundled-skills/idea-to-blueprint/references/blueprint-template.md +259 -0
- package/bundled-skills/idea-to-blueprint/references/code-quality-and-review.md +216 -0
- package/bundled-skills/idea-to-blueprint/references/design-minimal.md +96 -0
- package/bundled-skills/idea-to-blueprint/references/edge-case-catalog.md +239 -0
- package/bundled-skills/idea-to-blueprint/references/intake-questions.md +105 -0
- package/bundled-skills/idea-to-blueprint/references/research-protocol.md +196 -0
- package/bundled-skills/idea-to-blueprint/references/session-protocol.md +133 -0
- package/bundled-skills/idea-to-blueprint/references/stories-ac-tests.md +194 -0
- package/bundled-skills/idea-to-blueprint/references/ux-writing-guide.md +128 -0
- package/bundled-skills/idea-to-blueprint/scripts/lint_blueprint.py +460 -0
- package/bundled-skills/liuguang-banlan-ui/SKILL.md +22 -18
- package/bundled-skills/liuguang-banlan-ui/assets/starter/launcher.css +2 -2
- package/bundled-skills/liuguang-banlan-ui/assets/starter/obsidian/index.html +5 -4
- package/bundled-skills/liuguang-banlan-ui/assets/starter/obsidian/theme-config.js +3 -10
- package/bundled-skills/liuguang-banlan-ui/assets/starter/obsidian/theme.css +48 -62
- package/bundled-skills/liuguang-banlan-ui/assets/starter/opal/index.html +5 -4
- package/bundled-skills/liuguang-banlan-ui/assets/starter/opal/theme-config.js +27 -35
- package/bundled-skills/liuguang-banlan-ui/assets/starter/opal/theme.css +48 -62
- package/bundled-skills/liuguang-banlan-ui/assets/starter/shared/spectral-field.js +135 -148
- package/bundled-skills/liuguang-banlan-ui/references/style-contract.md +26 -7
- package/bundled-skills/liuguang-banlan-ui/references/verification.md +19 -7
- package/bundled-skills/liuguang-banlan-ui/scripts/measure_preview.py +78 -47
- package/bundled-skills/liuguang-banlan-ui/scripts/serve_preview.py +35 -0
- package/bundled-skills/liuguang-banlan-ui/scripts/validate_manifest.py +34 -3
- package/bundled-skills/liuguang-banlan-ui/tests/test_measure_preview.py +119 -0
- package/bundled-skills/liuguang-banlan-ui/tests/test_serve_preview.py +38 -0
- package/bundled-skills/liuguang-banlan-ui/tests/test_validate_manifest.py +73 -0
- package/bundled-skills/loki-mode/examples/todo-app-generated/frontend/package-lock.json +12 -12
- package/bundled-skills/loki-mode/examples/todo-app-generated/frontend/package.json +1 -1
- package/bundled-skills/meeting-notes/SKILL.md +80 -0
- package/bundled-skills/repo-foundation/SKILL.md +166 -0
- package/bundled-skills/repo-foundation/references/LICENSE.md +21 -0
- package/bundled-skills/repo-foundation/references/bootstrap.md +63 -0
- package/bundled-skills/repo-foundation/references/companion.md +9 -0
- package/bundled-skills/repo-foundation/references/continuity.md +50 -0
- package/bundled-skills/repo-foundation/references/evolution.md +60 -0
- package/bundled-skills/repo-foundation/references/migration-examples.md +53 -0
- package/bundled-skills/repo-foundation/references/shared-contracts.md +48 -0
- package/bundled-skills/repo-foundation/references/verification.md +50 -0
- package/bundled-skills/repo-native-refactor/SKILL.md +225 -0
- package/bundled-skills/repo-native-refactor/references/LICENSE.md +21 -0
- package/bundled-skills/repo-native-refactor/references/deterministic-tooling.md +101 -0
- package/bundled-skills/repo-native-refactor/references/error-reliability.md +117 -0
- package/bundled-skills/repo-native-refactor/references/finding-taxonomy.md +181 -0
- package/bundled-skills/repo-native-refactor/references/refactor-examples.md +77 -0
- package/bundled-skills/repo-native-refactor/references/repository-prose.md +157 -0
- package/bundled-skills/repo-native-refactor/references/repository-rehabilitation.md +94 -0
- package/bundled-skills/repo-native-refactor/references/semantic-risk.md +187 -0
- package/bundled-skills/repo-native-refactor/references/shared-contracts.md +48 -0
- package/bundled-skills/repo-native-refactor/references/testing-integrity.md +103 -0
- package/bundled-skills/tech-writing-proofread/SKILL.md +78 -0
- package/bundled-skills/typescript-expert/scripts/ts_diagnostic.py +40 -19
- package/bundled-skills/youtube-summarizer/SKILL.md +3 -3
- package/package.json +1 -1
- package/skills_index.json +254 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Session protocol — one epic per fresh session
|
|
2
|
+
|
|
3
|
+
Contents: 1 Why fresh sessions · 2 What must live in the repo · 3 Session lifecycle · 4 Gates (what "done" requires) · 5 Handoff summary format · 6 PROGRESS.md and DECISIONS.md · 7 Amending the blueprint from a session · 8 Recovery · 9 Claude Code vs Codex notes · 10 `[VERIFY-AT-BUILD]` re-check rule
|
|
4
|
+
|
|
5
|
+
This section is copied (adapted to the product) into section 18 of the blueprint. Its files are in `assets/`.
|
|
6
|
+
|
|
7
|
+
## 1. Why fresh sessions
|
|
8
|
+
|
|
9
|
+
Long agent sessions accumulate drift: forgotten constraints, half-remembered decisions, context compression. Starting each epic in a clean session forces every needed fact to live in the repo, where it is versioned, greppable and reviewable. The cost is that nothing can be assumed to be remembered — so the protocol makes the repo the memory: the blueprint says *what*, PROGRESS.md says *where we are*, DECISIONS.md says *why*, and `check` says *whether it works*.
|
|
10
|
+
|
|
11
|
+
## 2. What must live in the repo (created in Epic 00)
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
docs/BLUEPRINT.md the full blueprint (this document)
|
|
15
|
+
docs/PROGRESS.md state: epic/story status, AC evidence, deviations, next preconditions
|
|
16
|
+
docs/DECISIONS.md decision records DR-nn (from the blueprint + those made during sessions)
|
|
17
|
+
AGENTS.md Codex entry point: points at the three docs and the protocol
|
|
18
|
+
CLAUDE.md Claude Code entry point: same content
|
|
19
|
+
.env.example every variable with a one-line meaning
|
|
20
|
+
<check command> one command that runs format + lint + typecheck + tests (documented in BLUEPRINT §13.4)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`AGENTS.md` and `CLAUDE.md` are identical in content and short (≤ 60 lines): where the docs are, the protocol in ten lines, the `check` command, the commit format, and the rule "if it's not in BLUEPRINT or PROGRESS, ask or record — don't assume".
|
|
24
|
+
|
|
25
|
+
## 3. Session lifecycle
|
|
26
|
+
|
|
27
|
+
**Boot (user)** — open a fresh session in the repo, paste the session prompt for the epic (Appendix A of the blueprint; generated from `assets/session-prompt.md`).
|
|
28
|
+
|
|
29
|
+
**Orient (agent)**
|
|
30
|
+
1. Read `AGENTS.md`/`CLAUDE.md`, then `docs/PROGRESS.md` entirely, then `docs/BLUEPRINT.md` sections 12–16, 18, 21 and the target epic in section 17 (and any flow/screen/copy sections the epic references).
|
|
31
|
+
2. Verify preconditions: previous epics DONE in PROGRESS.md; `git status` clean on the main branch; `check` green on a clean tree; env vars listed in the epic's preconditions present locally; every `[VERIFY-AT-BUILD]` item the epic depends on re-checked (see §10) and the result recorded in PROGRESS.md.
|
|
32
|
+
3. If a precondition fails: stop, report exactly what fails and the fix, do not start building. The user decides.
|
|
33
|
+
|
|
34
|
+
**Plan (agent)**
|
|
35
|
+
4. Restate the epic goal and the story list in ≤ 15 lines. List the ACs that are unclear or reference missing IDs (there should be none; if there are, they are blueprint defects → §7).
|
|
36
|
+
5. Produce the session plan: story order, the tests to write per story (from the story's Tests block), the tasks, and the manual checks the user will need to do at the end. Estimate whether it fits the session; if not, propose which stories to defer to a follow-up epic `E03b` and record it in PROGRESS.md as a deviation.
|
|
37
|
+
6. Wait for "go" unless the user pre-approved ("plan and build without stopping").
|
|
38
|
+
|
|
39
|
+
**Build (agent)** — for each story in order:
|
|
40
|
+
7. Create a branch `epic/E03` (once per epic) if not on trunk-only.
|
|
41
|
+
8. Write the tests for the story's ACs first; run `check`; the new tests must fail.
|
|
42
|
+
9. Implement the tasks; run `check` after each task or story; keep it green. Copy strings come from the copy table by ID — no improvised strings.
|
|
43
|
+
10. Commit per story: `feat(auth): request OTP by phone [E02-S01]` (type/scope per BLUEPRINT §13.7). Record the story as DONE in PROGRESS.md with one evidence line per AC (test name, or manual-check result).
|
|
44
|
+
11. Any decision not covered by the blueprint (a library detail, a schema nuance) → add `DR-nn` to DECISIONS.md in the same commit. Any AC that turns out wrong or impossible → §7, never a silent change.
|
|
45
|
+
|
|
46
|
+
**Verify (agent)**
|
|
47
|
+
12. Run the full `check`; run the epic-level tests (flow e2e) and the whole regression suite; run CI (push and wait, or run the CI script locally).
|
|
48
|
+
12b. **Self-review.** Walk the review checklist (BLUEPRINT §14.4) over the epic's diff, story by story, and answer every item. Do this as if reviewing someone else's work: read the diff, not your memory of writing it. Fix what fails rather than noting it. Report the result in the handoff summary as `reviewed: <n> items, <n> fixed, <n> accepted with reason` — never as a bare ✔. This pass exists because the human reviewer sees a large diff produced quickly, and their attention is the scarcest resource in the whole process; anything you can catch here is worth ten times what it costs.
|
|
49
|
+
12c. If the diff for any story exceeded the size limit in §14.4, say so explicitly in the handoff. It is a signal that the story was mis-sized in the blueprint, and it is worth an amendment for the next epic.
|
|
50
|
+
13. Deploy to staging per BLUEPRINT §13.8 if the epic's DoD requires it; run the smoke checks; record results.
|
|
51
|
+
14. Walk the epic's Definition of Done line by line; each line gets a ✔ with evidence or the epic is not done.
|
|
52
|
+
|
|
53
|
+
**Handoff (agent)**
|
|
54
|
+
15. Update PROGRESS.md: epic status, per-story status, AC evidence, deviations, accepted risks, `[VERIFY-AT-BUILD]` results, next epic's preconditions and any prep the user must do (credentials, accounts).
|
|
55
|
+
16. Update DECISIONS.md and the blueprint Amendments log if anything changed.
|
|
56
|
+
17. Final commit; merge to main if the branch policy says so; confirm CI green.
|
|
57
|
+
18. Print the handoff summary (§5) and say explicitly: "Safe to terminate this session. Next: open a fresh session and paste the E04 prompt."
|
|
58
|
+
|
|
59
|
+
**Terminate (user)** — close the session. Open a new one for the next epic. Repeat.
|
|
60
|
+
|
|
61
|
+
## 4. Gates
|
|
62
|
+
|
|
63
|
+
An epic is DONE only when all of these are true; the agent never marks DONE otherwise:
|
|
64
|
+
|
|
65
|
+
- Every story DONE with an evidence line per AC (an automated test name that passes in `check`, or a recorded manual check with observation and date).
|
|
66
|
+
- `check` green on the final commit; CI green.
|
|
67
|
+
- Epic-level flow tests green; all previous epics' tests green (no regressions).
|
|
68
|
+
- Staging smoke checks passed when required by the DoD.
|
|
69
|
+
- The review checklist (§14.4) applied to every story, with the result recorded — not "reviewed", but which items failed and what was done.
|
|
70
|
+
- No gate rule weakened, disabled or bypassed to reach green; if one was, a DR entry states why and a follow-up story restores it.
|
|
71
|
+
- No `TODO`/`FIXME`/skipped tests introduced without a matching PROGRESS.md "accepted risk" line with reason and owner.
|
|
72
|
+
- No new flaky test; any flake observed is quarantined with a follow-up story, never re-run until green.
|
|
73
|
+
- PROGRESS.md, DECISIONS.md and (if needed) the Amendments log are updated and committed.
|
|
74
|
+
|
|
75
|
+
If a gate cannot be met in the session, the epic stays IN PROGRESS with an exact list of what remains; the next session resumes it (§8). Partial is fine; pretending is not.
|
|
76
|
+
|
|
77
|
+
## 5. Handoff summary format (≤ 20 lines)
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
## Handoff — E03 <Title> — <date>
|
|
81
|
+
Status: DONE | IN PROGRESS (remaining: E03-S04 AC-3, AC-5; staging smoke)
|
|
82
|
+
Stories: E03-S01 DONE · E03-S02 DONE · E03-S03 DONE · E03-S04 IN PROGRESS
|
|
83
|
+
check: green (commit abc123) · CI: green · staging: deployed, smoke 3/3
|
|
84
|
+
Self-review (§14.4): 4 items failed and fixed (missing object-level auth check on API-07; N+1 in
|
|
85
|
+
order list; two tests asserted only length; SCR-04 empty state used an improvised string).
|
|
86
|
+
1 accepted: duplication detector flags the two DTO mappers — kept, extraction is E05's job.
|
|
87
|
+
Diff size: E03-S02 was 620 lines, over the 400 limit — story was mis-sized, amendment A-03 splits it.
|
|
88
|
+
Deviations: E03-S02 AC-4 rate limit changed 5→10 per 10 min — see Amendment A-02, DR-07
|
|
89
|
+
Accepted risks: none | E03-S03 EC-MSG-01 manual only until provider sandbox supports delivery status
|
|
90
|
+
VERIFY-AT-BUILD: INT-sms reachable ✔ (2026-09-05); gateway sandbox ✔
|
|
91
|
+
Decisions added: DR-07, DR-08
|
|
92
|
+
Next epic E04 preconditions: create staging bucket; add STORAGE_KEY to .env; nothing else
|
|
93
|
+
Manual checks for you: open staging SCR-03, request a code on your phone, confirm delivery < 30 s
|
|
94
|
+
Safe to terminate. Next: fresh session, paste E04 prompt.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 6. PROGRESS.md and DECISIONS.md
|
|
98
|
+
|
|
99
|
+
Formats are in `assets/PROGRESS.md.template` and `assets/DECISIONS.md.template`. Principles:
|
|
100
|
+
|
|
101
|
+
- PROGRESS.md is a **state file, not a diary**: current status per epic and story, evidence, deviations, risks, preconditions. Session logs are one line per session at the bottom (date, epic, outcome, commit).
|
|
102
|
+
- Evidence lines are specific: `AC-3 ✔ api/auth_otp_request.test::provider_timeout_returns_503` or `AC-6 ✔ manual 2026-09-05 — Persian digits render on Chrome Android 128`.
|
|
103
|
+
- DECISIONS.md holds `DR-nn` entries: context, options, decision, consequences, date, epic. Blueprint DRs are copied in at Epic 00 so there is one place to look.
|
|
104
|
+
|
|
105
|
+
## 7. Amending the blueprint from a session
|
|
106
|
+
|
|
107
|
+
The blueprint is the source of truth, so when reality disagrees with it, the blueprint changes — explicitly:
|
|
108
|
+
|
|
109
|
+
1. Do not silently implement something different from an AC.
|
|
110
|
+
2. Add an entry to the **Amendments log** (section 18 of the blueprint, table `A-nn | date | epic/story | what changed | why | approved by`).
|
|
111
|
+
3. Edit the affected AC/copy/architecture text in place and mark it `(amended A-nn)`.
|
|
112
|
+
4. If the change affects other epics, add a line to their preconditions.
|
|
113
|
+
5. Scope additions are not amendments — they are new stories in a later epic; record the idea in PROGRESS.md "Parking lot" and move on.
|
|
114
|
+
|
|
115
|
+
Ask the user before amending anything that changes user-visible behaviour, money, data retention or security; smaller technical amendments can be made and reported in the handoff.
|
|
116
|
+
|
|
117
|
+
## 8. Recovery
|
|
118
|
+
|
|
119
|
+
- **Session crashed or was terminated mid-epic**: the next session reads PROGRESS.md, runs `git status` and `git log`, inspects the epic branch, runs `check`, and resumes from the first story/AC without evidence. Uncommitted work is inspected and either committed with a WIP note or discarded, stated in PROGRESS.md.
|
|
120
|
+
- **`check` red at boot**: the previous session violated a gate. Fix the red first as a hotfix story `E03-S00 — restore green` with its own evidence, then continue.
|
|
121
|
+
- **Blueprint defect found** (missing ID, contradictory ACs): treat as §7; if blocking, stop and ask.
|
|
122
|
+
- **Environment broken** (missing service, credentials expired): record in PROGRESS.md, report, stop.
|
|
123
|
+
|
|
124
|
+
## 9. Claude Code vs Codex notes
|
|
125
|
+
|
|
126
|
+
- Both read a root instructions file: Claude Code reads `CLAUDE.md`; Codex reads `AGENTS.md`. Keep both, identical in content, pointing at the docs.
|
|
127
|
+
- Skills: Claude Code discovers `SKILL.md` folders under `.claude/skills/` (project) and `~/.claude/skills/` (personal); Codex discovers the same open skill format from its skills locations (`~/.codex/skills/`, `.codex/skills/`, and `.agents/skills/` in recent versions — confirm against the current Codex docs when installing). The session protocol does not depend on skills at build time; it depends only on the repo files.
|
|
128
|
+
- Invocation: paste the session prompt as the first message in either tool. If the harness exposes an effort/thinking level, set it to the maximum for planning and verification steps.
|
|
129
|
+
- Verification commands must be runnable by the agent without interaction (no prompts, no watch mode). Provide a `check` that exits non-zero on failure.
|
|
130
|
+
|
|
131
|
+
## 10. `[VERIFY-AT-BUILD]` re-check rule
|
|
132
|
+
|
|
133
|
+
Every item tagged `[VERIFY-AT-BUILD]` in the blueprint (service availability, sandbox status, prices, sanctions/blocking status, app-store policy, library latest patch) is listed in section 18 with the epic that first depends on it. At Orient time the agent re-checks the items its epic needs (a search or a request against the sandbox), records `✔ date` or `✘ date + what changed` in PROGRESS.md, and if ✘ stops and reports before building on it.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Stories, acceptance criteria, tests, DoD
|
|
2
|
+
|
|
3
|
+
Contents: 1 Why the format is strict · 2 Story format · 3 Acceptance criteria rules · 4 Edge cases, tests, tasks · 5 Epic template · 6 Epic 00 Foundation contents · 7 Sizing · 8 Worked example · 9 Anti-example
|
|
4
|
+
|
|
5
|
+
## 1. Why the format is strict
|
|
6
|
+
|
|
7
|
+
A coding agent in a fresh session turns each acceptance criterion into a test and then into code. Anything the criterion leaves open, the agent decides silently. So criteria are written to be **testable without interpretation**: concrete inputs, concrete observable outputs, concrete copy IDs, concrete numbers. Adjectives ("fast", "clear", "appropriate", "properly") are defects.
|
|
8
|
+
|
|
9
|
+
## 2. Story format
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
### E03-S02 — <Short imperative title>
|
|
13
|
+
|
|
14
|
+
**Story** — As **P2 (<persona name>)**, I want <capability>, so that <outcome the persona cares about>.
|
|
15
|
+
**Context** — 2–5 sentences: why this exists, what the persona is doing at that moment, what research/benchmark informed it (S-nn), which flow(s) and screen(s) it implements (F-03, SCR-07).
|
|
16
|
+
**Scope** — In: … Out (handled in E05-S01 / non-goal): …
|
|
17
|
+
**Acceptance Criteria**
|
|
18
|
+
- AC-1 (happy path) Given … When … Then …
|
|
19
|
+
- AC-2 (validation) …
|
|
20
|
+
- AC-3 (failure/degraded) …
|
|
21
|
+
- AC-4 (state edge) …
|
|
22
|
+
- AC-5 (permissions) …
|
|
23
|
+
- AC-6 (copy) …
|
|
24
|
+
- AC-7 (accessibility) …
|
|
25
|
+
- AC-8 (observability) …
|
|
26
|
+
**Edge cases** — EC-xxx-nn references plus story-specific ones, each with expected behaviour.
|
|
27
|
+
**Tests** — the tests that prove the ACs (see §4).
|
|
28
|
+
**Tasks** — ordered implementation tasks E03-S02-T1… (see §4).
|
|
29
|
+
**Story DoD** — the checklist that must be true before the story is marked DONE in PROGRESS.md.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Personas are referenced by ID and name; "As a user" is not allowed — if no persona fits, the persona list is incomplete, fix that first. Internal/technical work (migrations, CI) is written as a story for the **builder persona** (define one, e.g., `P0 — Builder (the coding agent / maintainer)`), so the format stays uniform and the linter stays happy.
|
|
33
|
+
|
|
34
|
+
## 3. Acceptance criteria rules
|
|
35
|
+
|
|
36
|
+
Each criterion is `Given <state> When <action> Then <observable result>` and:
|
|
37
|
+
|
|
38
|
+
- Names concrete data ("a phone number of 11 digits starting with 09", "an order with 3 items totalling 450,000 Toman"), not categories.
|
|
39
|
+
- Names the copy line shown (`CP-SCR07-4`), not "an error message".
|
|
40
|
+
- Uses numbers for anything measurable: timeouts, limits, lengths, response times, retry counts, cooldowns.
|
|
41
|
+
- Describes the observable result from the outside (HTTP status and body shape, screen state, stored record fields, emitted event, sent message), not the implementation ("uses a mutex").
|
|
42
|
+
- Is independently testable — one behaviour per criterion; split compound criteria.
|
|
43
|
+
|
|
44
|
+
Minimum coverage per story (skip a category only when it truly cannot apply, and say why in one word, e.g. "AC-5 permissions: n/a — public screen"):
|
|
45
|
+
|
|
46
|
+
| Category | Must answer |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Happy path | The main success case with concrete data |
|
|
49
|
+
| Validation / negative | Empty, malformed, boundary, duplicate input → which copy line, which field, no state change |
|
|
50
|
+
| Failure / degraded | Dependency down, timeout, offline mid-action → what the user sees, what is retried, what is persisted |
|
|
51
|
+
| State edges | Empty state, single item, maximum, pagination boundary, concurrent modification, idempotent repeat |
|
|
52
|
+
| Permissions / auth | Wrong role, expired session mid-action, unauthenticated deep link |
|
|
53
|
+
| Copy | Which CP lines appear in which states (this is how UX writing becomes testable) |
|
|
54
|
+
| Accessibility (UI stories) | Focus order, labels, contrast, touch target size, screen-reader text — as concrete checks |
|
|
55
|
+
| Observability (backend stories) | Which log events (no PII), metrics, error-tracking events are emitted |
|
|
56
|
+
| Data integrity | What is stored, with which fields, audit trail, soft-delete behaviour |
|
|
57
|
+
| Locale (when relevant) | RTL rendering, digits, dates in Jalali with correct month lengths, currency label |
|
|
58
|
+
|
|
59
|
+
## 4. Edge cases, tests, tasks, DoD
|
|
60
|
+
|
|
61
|
+
**Edge cases.** Walk `edge-case-catalog.md` category by category for the story and list every applicable item as either a reference to a global `EC-*` (with any story-specific expected behaviour) or a new story-level item. If the list is empty, the story is trivial or you skipped the walk.
|
|
62
|
+
|
|
63
|
+
**Tests.** For each AC name the test(s) that prove it, at the right level:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
**Tests**
|
|
67
|
+
- Unit: `<module>.<test_name>` — covers AC-2, AC-4 (pure validation and state logic)
|
|
68
|
+
- Integration: `<test file>::<test_name>` — covers AC-1, AC-3, AC-8 (through the real DB/test double for the gateway)
|
|
69
|
+
- E2E (only if this story is on a critical path listed in section 14): `<spec name>` — covers AC-1, AC-6
|
|
70
|
+
- Manual (only what cannot be automated, e.g., real SMS delivery): step list, expected observation, who does it
|
|
71
|
+
- Fixtures/data needed: …
|
|
72
|
+
- Run: `<check command>` must be green; the new tests must fail before the implementation and pass after.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Tasks.** Ordered, small, each naming the indicative files/modules and the test it makes pass:
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
**Tasks**
|
|
79
|
+
- E03-S02-T1 Add `phone` validation to `ENT-User` schema + migration — proves AC-2
|
|
80
|
+
- E03-S02-T2 Implement `POST /auth/otp/request` (API-04) with rate limit 5/10min — proves AC-1, AC-3
|
|
81
|
+
- E03-S02-T3 Wire SCR-03 form states and copy CP-SCR03-1…6 — proves AC-6, AC-7
|
|
82
|
+
- E03-S02-T4 Emit `auth.otp.requested` log event without phone number — proves AC-8
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Story DoD** (default; extend per story):
|
|
86
|
+
- All ACs have passing automated tests (or a completed manual step recorded in PROGRESS.md with evidence).
|
|
87
|
+
- Each of those tests was seen **failing before** the implementation and passing after; PROGRESS.md records that.
|
|
88
|
+
- `check` is green on the whole repo — no gate rule weakened, skipped or ignored to get there (if one was, a DR says why).
|
|
89
|
+
- The **review checklist** (blueprint section 14.4) has been applied end to end and every item answered; unanswered items are fixed, not batched.
|
|
90
|
+
- Copy lines used match the copy table exactly (no improvised strings).
|
|
91
|
+
- Edge cases listed are each covered by a test or explicitly marked "accepted risk" in PROGRESS.md with reason.
|
|
92
|
+
- Every external symbol used traces to a pinned dependency in the stack table — no invented APIs, no unpinned imports.
|
|
93
|
+
- No new dependency without a DR entry.
|
|
94
|
+
- No logic duplicated from elsewhere in the repo (the session searched before writing).
|
|
95
|
+
- Commit(s) reference the story ID.
|
|
96
|
+
- PROGRESS.md updated: story DONE, AC evidence lines, and any deviation from the blueprint.
|
|
97
|
+
|
|
98
|
+
## 5. Epic template
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
## Epic 03 — <Title>
|
|
102
|
+
|
|
103
|
+
**Goal** (one line, outcome-oriented, in the user's language then English if bilingual)
|
|
104
|
+
**Personas served** P1, P2
|
|
105
|
+
**Depends on** E00, E01 (what specifically: tables, endpoints, components)
|
|
106
|
+
**Preconditions for the session** — PROGRESS.md shows E00–E02 DONE; `check` green on clean `main`; env vars X, Y present; `[VERIFY-AT-BUILD]` items for this epic re-checked: INT-sms availability, …
|
|
107
|
+
**Scope** — In: stories below. Out: … (where handled)
|
|
108
|
+
**Flows and screens implemented** F-02, F-03; SCR-03, SCR-04
|
|
109
|
+
**Data and API touched** ENT-User (new fields …), API-04, API-05
|
|
110
|
+
**Risks specific to this epic** R-02 …
|
|
111
|
+
**Stories**
|
|
112
|
+
### E03-S01 — …
|
|
113
|
+
### E03-S02 — …
|
|
114
|
+
**Epic-level tests** — the integration/e2e run that proves the epic as a whole (the flow end to end), plus regression: all previous epics' tests still green.
|
|
115
|
+
**Definition of Done**
|
|
116
|
+
- All stories DONE with evidence in PROGRESS.md
|
|
117
|
+
- Epic-level flow test(s) green; full `check` green; CI green on the merged branch
|
|
118
|
+
- Deployed to staging and smoke-verified (list the 3 manual checks if UI)
|
|
119
|
+
- PROGRESS.md: epic DONE, deviations recorded, next epic's preconditions confirmed
|
|
120
|
+
- DECISIONS.md updated for any decision taken during the session
|
|
121
|
+
- Blueprint Amendments log updated if any AC/scope changed
|
|
122
|
+
**Session handoff checklist** — the ≤20-line summary the agent prints before the user terminates (format in session-protocol.md §5).
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 6. Epic 00 — Foundation: mandatory contents
|
|
126
|
+
|
|
127
|
+
Epic 00 is where "no room for error" is manufactured. Its stories (builder persona) cover:
|
|
128
|
+
|
|
129
|
+
1. Repository init with the chosen layout; language/runtime version pinned (version file); package manager lockfile committed.
|
|
130
|
+
2. Formatter, linter (strict), typechecker (strict flags), test runner configured; `check` command that runs them all and fails on any warning class you decide is an error; documented expected runtime. Also in `check` from day one: coverage floor, dependency/vulnerability audit, secret scanning, and schema-drift check — every gate component listed in blueprint section 14.2 that applies.
|
|
131
|
+
2b. **Module skeleton and fitness functions**: the empty modules from the architecture's module map, plus the architecture tests that enforce the dependency-direction and ownership rules, failing the build on violation. These exist *before* there is any feature code to violate them; retrofitting boundaries after three epics does not work.
|
|
132
|
+
2c. **The review checklist** (blueprint section 14.4) committed to the repo at a fixed path and referenced from `AGENTS.md`/`CLAUDE.md`, so it is in every future session's context.
|
|
133
|
+
3. Test layout with one example unit test, one integration test against a real test database (containerised or local), one e2e smoke test; factories/fixtures pattern established. Mutation testing configured on the critical modules if a maintained tool exists for the stack (blueprint section 14.3 says which, or says none exists).
|
|
134
|
+
4. CI running `check` on every push and blocking merge on red; branch protection configured so the gate cannot be bypassed.
|
|
135
|
+
5. `docs/BLUEPRINT.md` (this document), `docs/PROGRESS.md`, `docs/DECISIONS.md`, `AGENTS.md` and `CLAUDE.md` created from Appendix B; `.env.example` with every variable and a one-line meaning; secrets policy.
|
|
136
|
+
6. Configuration loading with validation at startup (fail fast on missing/invalid env).
|
|
137
|
+
7. Logging with a structured logger, request/correlation ID, PII redaction rule; error-tracking hook (verified service or self-hosted); health endpoint.
|
|
138
|
+
8. Database with migration tooling; first migration; seed script for fixtures.
|
|
139
|
+
9. Hello-world vertical slice: one screen or endpoint through all layers, with i18n/RTL plumbing if the product needs it (locale, direction, font loading, digit formatting, calendar utility), proving the whole stack end to end.
|
|
140
|
+
10. Deployment skeleton to staging (build, run, migrate, health check), with the documented rollback step.
|
|
141
|
+
11. Coding conventions file the agent reads every session (error handling, naming, module boundaries, "no `any`/no untyped", commit format).
|
|
142
|
+
|
|
143
|
+
Every one of these has ACs and tests like any other story. Epic 00 is typically the largest epic; it can be split into E00a/E00b only if sessions are short.
|
|
144
|
+
|
|
145
|
+
## 7. Sizing
|
|
146
|
+
|
|
147
|
+
- Story: 0.5–3 hours of agent work including tests. Larger → split by AC groups.
|
|
148
|
+
- Epic: 3–7 stories for a half-day session; 2–4 for short sessions. Never more than one flow's worth of new surface area per epic.
|
|
149
|
+
- Sprint: 1–3 epics ending in a releasable or demonstrable increment.
|
|
150
|
+
- Mark sizes S/M/L in the epic order table; the user picks session length accordingly.
|
|
151
|
+
|
|
152
|
+
## 8. Worked example (good)
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
### E02-S01 — Request a one-time code by phone number
|
|
156
|
+
|
|
157
|
+
**Story** — As **P1 (Restaurant owner, Tehran, mid-range Android, busy)**, I want to enter my mobile number and receive a one-time code, so that I can sign in without remembering a password.
|
|
158
|
+
**Context** — Phone-first login is the norm in the benchmarked local products (S-09, S-11) and P1 rarely uses email. Implements F-01 steps 1–3 on SCR-03. SMS delivery through INT-sms (sandbox available [VERIFIED — S-16, 2026-09-05] [VERIFY-AT-BUILD]).
|
|
159
|
+
**Scope** — In: number entry, validation, code request, resend cooldown, rate limiting, delivery via provider sandbox in tests. Out: code verification (E02-S02), account creation on first login (E02-S03).
|
|
160
|
+
**Acceptance Criteria**
|
|
161
|
+
- AC-1 (happy) Given SCR-03 is open and no code was requested for `09123456789` in the last 60 s, When the user submits `09123456789`, Then `POST /auth/otp/request` (API-04) returns 200 `{ "expires_in": 120, "resend_after": 60 }`, a 6-digit code is stored hashed with a 120 s expiry, the provider is called once with template `otp_v1`, and SCR-03 shows state "code-sent" with CP-SCR03-4.
|
|
162
|
+
- AC-2 (validation) Given SCR-03, When the user submits `0912345678` (10 digits) or `+989123456789` or `۰۹۱۲۳۴۵۶۷۸۹` (Persian digits), Then Persian digits are normalised to Latin before validation, `+98` is normalised to `0`, a 10-digit input is rejected inline with CP-SCR03-2 under the field, no request is sent, and the submit button stays disabled until 11 valid digits are present.
|
|
163
|
+
- AC-3 (failure) Given the provider returns HTTP 5xx or times out after 5 s, When the user submits a valid number, Then API-04 returns 503 `{ "error": "sms_unavailable" }`, no code is stored, SCR-03 shows CP-SCR03-6 with a retry action, and the error is reported to error tracking with the correlation ID and without the phone number.
|
|
164
|
+
- AC-4 (state edge — rate limit) Given 5 requests for the same number in the last 10 minutes, When a 6th is submitted, Then API-04 returns 429 with `retry_after` seconds, the provider is not called, and SCR-03 shows CP-SCR03-7 including the remaining minutes in Persian digits.
|
|
165
|
+
- AC-5 (permissions) n/a — public endpoint; AC-4 is the abuse control.
|
|
166
|
+
- AC-6 (copy) Given each state of SCR-03 (idle, invalid, sending, code-sent, resend-cooldown, sms-unavailable, rate-limited), Then the exact copy from CP-SCR03-1…7 is shown, digits rendered as Persian digits, layout RTL.
|
|
167
|
+
- AC-7 (accessibility) Given a screen reader, When focus enters the field, Then its label (CP-SCR03-1) is announced; inline errors are announced via a live region; the field has `inputmode="numeric"`; the primary button is ≥ 44×44 px.
|
|
168
|
+
- AC-8 (observability) Given any outcome, Then one structured log event `auth.otp.requested` with `{ outcome, correlation_id, provider_latency_ms }` and no phone number is emitted; a counter `otp_requests_total{outcome}` increments.
|
|
169
|
+
**Edge cases** — EC-INPUT-03 (invisible characters pasted → stripped before validation), EC-INPUT-07 (mixed Persian/Latin digits → normalised), EC-AUTH-02 (double tap submit → single request, button disabled while pending), EC-NET-04 (offline at submit → CP-SCR03-6 without provider call), EC-MSG-01 (provider accepts but never delivers → covered by resend after 60 s, no more than 3 resends per code), EC-IR-02 (number with operator prefix not in the known list → still accepted; operator list is not a validation rule).
|
|
170
|
+
**Tests**
|
|
171
|
+
- Unit: `auth/phone.test` — normalisePhone (Persian digits, +98, spaces, ZWNJ, invisible chars), isValidIranMobile — covers AC-2, EC-INPUT-03/07
|
|
172
|
+
- Unit: `auth/otp_rate_limit.test` — 5-per-10-min window, retry_after computation — covers AC-4
|
|
173
|
+
- Integration: `api/auth_otp_request.test` — success path with provider fake; provider 5xx/timeout; rate limit; idempotent double submit — covers AC-1, AC-3, AC-4, AC-8, EC-AUTH-02
|
|
174
|
+
- E2E: `e2e/login.spec` step "request code" — covers AC-1, AC-6 (critical path #1 in section 14)
|
|
175
|
+
- Manual: send one real code in staging to a test number; confirm delivery within 30 s; recorded in PROGRESS.md
|
|
176
|
+
- Run: `make check` green; new tests red before implementation.
|
|
177
|
+
**Tasks**
|
|
178
|
+
- E02-S01-T1 `normalisePhone` + `isValidIranMobile` in `auth/phone` with unit tests
|
|
179
|
+
- E02-S01-T2 OTP store: hashed code, expiry, attempt counter (ENT-OtpChallenge) + migration
|
|
180
|
+
- E02-S01-T3 Rate limiter keyed by phone (5/10 min) using the shared store
|
|
181
|
+
- E02-S01-T4 API-04 handler with provider client (INT-sms) and 5 s timeout; 503/429 mapping
|
|
182
|
+
- E02-S01-T5 SCR-03 states and copy CP-SCR03-1…7, RTL, Persian digits, live region
|
|
183
|
+
- E02-S01-T6 Log event + counter; error-tracking capture without PII
|
|
184
|
+
**Story DoD** — default DoD + manual staging delivery check recorded.
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## 9. Anti-example (what not to write, and why)
|
|
188
|
+
|
|
189
|
+
```
|
|
190
|
+
As a user I want to log in with my phone so that it's easy.
|
|
191
|
+
AC: user enters phone, gets SMS, sees success message. Errors are handled properly.
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Defects: no persona (voice and constraints unknown); "easy" is untestable; no number format, so the agent invents one; "success message" and "handled properly" leave copy and failure behaviour to the agent; no rate limit, so abuse is unspecified; no tests, so "done" is an opinion; no copy IDs, so the UX writing work is discarded at build time. Every one of these becomes a silent decision in a fresh session.
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# UX writing guide
|
|
2
|
+
|
|
3
|
+
Contents: 1 Principles · 2 Voice from personas · 3 Message formulas · 4 Component copy states · 5 Copy table rules · 6 Terminology · 7 Persian pack · 8 Channel templates (SMS/email/push/bot) · 9 Review checklist
|
|
4
|
+
|
|
5
|
+
## 1. Principles (outcome-driven)
|
|
6
|
+
|
|
7
|
+
Copy exists to move a specific persona to a specific outcome with the least reading. Concretely:
|
|
8
|
+
|
|
9
|
+
- **Say the outcome, not the mechanism.** "سفارش شما ثبت شد و تا ۲۰ دقیقهی دیگر میرسد" beats "Order created successfully". The user wants to know what happens to them next.
|
|
10
|
+
- **One idea per line.** Titles ≤ 6 words, body ≤ 2 short sentences, buttons 1–3 words.
|
|
11
|
+
- **Verb-first CTAs that name the result**: «پرداخت ۴۵۰٬۰۰۰ تومان», «ارسال کد», «ذخیرهی تغییرات» — never «تأیید», «اوکی», «ادامه» alone when a specific verb exists.
|
|
12
|
+
- **Errors: what happened + why (if useful) + what to do now.** Never blame; never expose internals; always leave an action. "کد واردشده درست نیست. دوباره تلاش کنید یا کد جدید بگیرید." not "Invalid OTP".
|
|
13
|
+
- **Confirmations describe the consequence**, not "are you sure?": «این آیتم برای مشتریها هم حذف میشود. حذف کنم؟» with buttons «حذف» / «نگهداشتن».
|
|
14
|
+
- **Empty states orient and offer one action**: what this place is for, what will appear here, one button that creates the first item.
|
|
15
|
+
- **Success confirms the outcome and points to the next step**; don't celebrate ("🎉 Awesome!!!") — inform.
|
|
16
|
+
- **Loading says what is happening** when it takes > 1 s ("در حال بررسی پرداخت…"); use skeletons for < 1 s.
|
|
17
|
+
- **Reversible beats confirm**: prefer "done + Undo" for reversible actions; reserve dialogs for irreversible or costly ones.
|
|
18
|
+
- **Consistency over cleverness**: one word per concept across the product (glossary), same sentence shape for the same kind of message.
|
|
19
|
+
- **Numbers, dates, money, phone numbers are formatted by rule**, never ad hoc (see §7 for Persian).
|
|
20
|
+
- **No filler**: «کاربر گرامی», "Please note that", "Oops!", "Successfully" add reading and no meaning.
|
|
21
|
+
- **Write for the stressed reader**: the person seeing an error is already frustrated; the person paying is anxious. Short, calm, concrete.
|
|
22
|
+
|
|
23
|
+
## 2. Voice from personas
|
|
24
|
+
|
|
25
|
+
Derive voice per persona from the persona sheet, then write a tone matrix.
|
|
26
|
+
|
|
27
|
+
| Persona trait (from section 5) | Copy consequence |
|
|
28
|
+
|---|---|
|
|
29
|
+
| Low tech comfort / reads slowly | Shorter lines, plain words, one action per screen, explicit next steps, no icons without labels |
|
|
30
|
+
| Expert / high frequency | Terse labels, keyboard hints, fewer confirmations, dense tables allowed |
|
|
31
|
+
| Under time pressure (shop floor, driving) | Front-load the key fact, large targets, minimal choices |
|
|
32
|
+
| Anxious about money or data | Show amounts and consequences before the action, explicit "nothing was charged" on failure, receipts |
|
|
33
|
+
| Formal expectation (B2B, older, official) | Formal register («شما», formal verbs), no jokes, no emoji |
|
|
34
|
+
| Casual expectation (young consumers, community) | Warmer, lighter, still respectful; emoji only if the design direction allows and never in errors |
|
|
35
|
+
| Screen-reader user | Every icon has text, every state change is announced, no meaning by colour alone |
|
|
36
|
+
|
|
37
|
+
Tone matrix (write it in the blueprint):
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
| Moment | P1 <name> | P2 <name> | P3 <name> |
|
|
41
|
+
| First run | … | … | … |
|
|
42
|
+
| Core task success | … | … | … |
|
|
43
|
+
| Validation error | … | … | … |
|
|
44
|
+
| System failure | … | … | … |
|
|
45
|
+
| Money moments | … | … | … |
|
|
46
|
+
| Destructive action | … | … | … |
|
|
47
|
+
| Notifications | … | … | … |
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## 3. Message formulas
|
|
51
|
+
|
|
52
|
+
- **Validation error (inline):** `<what is wrong in the field> + <how to fix>` — "شماره باید ۱۱ رقم و با ۰۹ شروع شود."
|
|
53
|
+
- **Operation failure:** `<what didn't happen> + <state of their data/money> + <action>` — "پرداخت انجام نشد. مبلغی از حساب شما کم نشده است. دوباره تلاش کنید."
|
|
54
|
+
- **Empty state:** `<what lives here> + <what to do first>` — "هنوز سفارشی ندارید. اولین آیتم منو را اضافه کنید تا مشتریها بتوانند سفارش بدهند." + button «افزودن آیتم».
|
|
55
|
+
- **Success:** `<outcome> + <next>` — "منو منتشر شد. مشتریها با اسکن QR همین الان میبینند."
|
|
56
|
+
- **Destructive confirm:** `<consequence, incl. who else is affected> + <question>` + buttons `<verb>` / `<keep>`.
|
|
57
|
+
- **Permission/limit:** `<limit reached> + <how to proceed>` — "امروز ۵ بار کد گرفتهاید. ۱۰ دقیقهی دیگر دوباره تلاش کنید."
|
|
58
|
+
- **Offline:** `<you're offline> + <what is saved> + <what happens when back>`.
|
|
59
|
+
- **Session expired:** `<what happened> + <nothing lost> + <action>`.
|
|
60
|
+
|
|
61
|
+
## 4. Component copy states
|
|
62
|
+
|
|
63
|
+
Every component that shows text has these states specified when applicable: label, placeholder (an example, not a repeat of the label), helper text, inline error(s) — one per failure reason, disabled reason (tooltip or helper), loading, success, empty, counter/limit text. A button has: default, loading («در حال ارسال…»), done, disabled-with-reason. A list has: loading, empty (first use), empty (filtered — "no results for …"), error with retry, end-of-list.
|
|
64
|
+
|
|
65
|
+
## 5. Copy table rules
|
|
66
|
+
|
|
67
|
+
- One table per screen (`SCR-nn`) and one per channel (SMS, email, push, in-app notifications, bot). Every state in §4 for every component on the screen has a row — "error message" as a single row is not acceptable; enumerate variants.
|
|
68
|
+
- Columns: `ID | Element | Copy (product language) | English gloss | Persona intent | State / variant | Max length | Notes`.
|
|
69
|
+
- IDs `CP-SCRnn-k` are referenced from acceptance criteria; changing copy later means changing the row, not the ID.
|
|
70
|
+
- Max length is a number derived from the layout (button width, SMS segment, push title limit); the AC tests truncation against it.
|
|
71
|
+
- Persona intent is a half-line: what the reader is trying to do at that moment.
|
|
72
|
+
- Variables in braces `{amount}`, `{minutes}`, with their formatting rule referenced (e.g., "{amount}: Toman, Persian digits, thousands separator ٬").
|
|
73
|
+
- Pluralisation and gender: specify. Persian has no grammatical gender; English glosses avoid gendered pronouns.
|
|
74
|
+
- Never leave copy to the build session; an improvised string in code is a defect (Story DoD).
|
|
75
|
+
|
|
76
|
+
## 6. Terminology
|
|
77
|
+
|
|
78
|
+
Build the product's UI glossary in section 21: one Persian term and one English term per concept, with rejected synonyms listed ("سفارش" — not "درخواست"; "منو" — not "فهرست"). Use loanwords that Persian users actually use in interfaces when they are dominant in the category (benchmark shows), otherwise Persian equivalents; decide once. The same applies to any product language.
|
|
79
|
+
|
|
80
|
+
## 7. Persian pack (users in Iran or Persian-speaking)
|
|
81
|
+
|
|
82
|
+
Typography and characters
|
|
83
|
+
- Use Persian letters ی (U+06CC) and ک (U+06A9), never Arabic ي (U+064A) and ك (U+0643). Normalise user input too (edge case EC-INPUT-08).
|
|
84
|
+
- Use ZWNJ (نیمفاصله, U+200C) correctly: «میروم», «کتابها», «سفارشهای», «تأییدشده» — never a full space or nothing. Search must treat ZWNJ, space and none as equivalent.
|
|
85
|
+
- Persian punctuation: «،» «؛» «؟» and «» for quotes; use «٬» (U+066C) as thousands separator and «٫» (U+066B) as decimal separator when showing Persian digits; a regular space before units («۴۵۰٬۰۰۰ تومان»).
|
|
86
|
+
- Digits: decide once (DR) — Persian digits (۰–۹) in all human-facing text is the common expectation in the benchmarked category; Latin digits in codes users must type into other systems (tracking codes, OTP if typed cross-device?), IDs, and developer surfaces. Never mix within one number. Inputs accept both and normalise.
|
|
87
|
+
- Mixed-direction text: wrap Latin tokens (emails, URLs, codes, brand names) in bidi isolation so punctuation does not jump; test with a string containing Persian + English + digits (EC-L10N-02).
|
|
88
|
+
- Font: a well-maintained open Persian web font with Latin glyph coverage, self-hosted (foreign font CDNs may be blocked or slow from Iran — verify), with a fallback stack; line-height slightly larger than Latin defaults; avoid italics (Persian has none); use weight for emphasis.
|
|
89
|
+
|
|
90
|
+
Register and tone
|
|
91
|
+
- Default to «شما» and polite plural verb forms for all personas unless the persona sheet says casual («تو») is expected by the brand and the segment — and then use it consistently.
|
|
92
|
+
- Plain, contemporary Persian; avoid heavy Arabic-derived formal vocabulary when a common Persian word exists («لطفاً دوباره تلاش کنید» not «مجدداً اقدام فرمایید»).
|
|
93
|
+
- Drop honorific filler («کاربر گرامی»، «با تشکر از شکیبایی شما») unless a formal B2B persona expects it.
|
|
94
|
+
- No exclamation stacking, no emoji in errors or money moments.
|
|
95
|
+
|
|
96
|
+
Formats
|
|
97
|
+
- Dates: Jalali in UI («۱۴۰۵/۰۶/۱۴» or «۱۴ شهریور ۱۴۰۵» — decide once), stored as UTC timestamps; Gregorian only where a foreign counterpart needs it. Relative dates («امروز»، «دیروز»، «۳ روز پیش») follow one rule. Month lengths (31/30/29–30 in Esfand) and leap years handled by a verified library, tested for the current and next year.
|
|
98
|
+
- Times: 24-hour, Asia/Tehran, DST policy verified; show timezone only for cross-country cases.
|
|
99
|
+
- Money: decide Toman vs Rial once (DR) and always label the unit; thousands separator; no decimals; for large sums the category may use «هزار تومان» shorthand — decide and be consistent.
|
|
100
|
+
- Phone: display as «۰۹۱۲ ۳۴۵ ۶۷۸۹» (grouping decided once), accept «+98…», «0098…», Persian digits, spaces, dashes; store E.164.
|
|
101
|
+
- Addresses: province, city, street, plaque («پلاک»), unit («واحد»), postal code (10 digits) — field order and labels as the category norm.
|
|
102
|
+
- National ID (کد ملی): 10 digits, check-digit validated if collected; show why it is needed.
|
|
103
|
+
- Week: Saturday is the first weekday; Friday is the weekend day (Thursday partial in many segments) — pickers, "this week" and scheduling copy follow this.
|
|
104
|
+
|
|
105
|
+
Messaging realities
|
|
106
|
+
- SMS in Persian is Unicode-encoded: segment length is far shorter than Latin SMS (verify provider's limits); OTP templates fit in one segment and lead with the code; include the app name; avoid links unless required.
|
|
107
|
+
- Telegram is widely used under filtering; domestic messengers vary by segment — the channel choice comes from research, and copy is written per channel.
|
|
108
|
+
|
|
109
|
+
## 8. Channel templates
|
|
110
|
+
|
|
111
|
+
Provide rows for each channel with the same table format:
|
|
112
|
+
|
|
113
|
+
- **SMS**: OTP (code first, app name, expiry), order/status updates (what changed + next), reminders; max length = one segment.
|
|
114
|
+
- **Email** (if used): subject ≤ 50 chars, preheader, body, single CTA, plain-text variant.
|
|
115
|
+
- **Push/in-app notification**: title ≤ 40 chars, body ≤ 90 chars, deep link target `SCR-nn`, quiet-hours rule.
|
|
116
|
+
- **Bot messages** (Telegram/Bale/…): message text, keyboard button labels, fallback for unknown input, /start onboarding sequence.
|
|
117
|
+
|
|
118
|
+
## 9. Review checklist for every copy table
|
|
119
|
+
|
|
120
|
+
- Every state of every component on the screen has a row.
|
|
121
|
+
- No adjectives about the system's own quality ("easily", "quickly", "seamlessly").
|
|
122
|
+
- Every error names an action.
|
|
123
|
+
- Every destructive confirm names the consequence and uses verb buttons.
|
|
124
|
+
- Digits, dates, money, phone follow the format rules; variables carry a formatting reference.
|
|
125
|
+
- Register consistent with the tone matrix for the persona(s) on this screen.
|
|
126
|
+
- Max length set and realistic for the layout/channel.
|
|
127
|
+
- Terms match the glossary; no synonyms.
|
|
128
|
+
- English gloss present so the coding agent understands intent.
|