@techierathore/techieflow 1.0.0
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/.claude/commands/TechieFlow/agents/analyst.md +97 -0
- package/.claude/commands/TechieFlow/agents/architect.md +84 -0
- package/.claude/commands/TechieFlow/agents/flow-master.md +217 -0
- package/.claude/commands/TechieFlow/agents/verifier.md +72 -0
- package/.claude/commands/TechieFlow/tasks/_metrics-emit-gate.md +138 -0
- package/.claude/commands/TechieFlow/tasks/_smoke-test-policy.md +98 -0
- package/.claude/commands/TechieFlow/tasks/_status-update-gate.md +78 -0
- package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +77 -0
- package/.claude/commands/TechieFlow/tasks/advanced-elicitation.md +117 -0
- package/.claude/commands/TechieFlow/tasks/amend-docs.md +149 -0
- package/.claude/commands/TechieFlow/tasks/author-brd.md +79 -0
- package/.claude/commands/TechieFlow/tasks/build-phase.md +231 -0
- package/.claude/commands/TechieFlow/tasks/create-deep-research-prompt.md +278 -0
- package/.claude/commands/TechieFlow/tasks/create-doc.md +101 -0
- package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +507 -0
- package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +224 -0
- package/.claude/commands/TechieFlow/tasks/devguide.md +224 -0
- package/.claude/commands/TechieFlow/tasks/document-project.md +343 -0
- package/.claude/commands/TechieFlow/tasks/execute-checklist.md +86 -0
- package/.claude/commands/TechieFlow/tasks/facilitate-brainstorming-session.md +136 -0
- package/.claude/commands/TechieFlow/tasks/fix-issues.md +134 -0
- package/.claude/commands/TechieFlow/tasks/generate-html.md +115 -0
- package/.claude/commands/TechieFlow/tasks/handoff-phase.md +126 -0
- package/.claude/commands/TechieFlow/tasks/index-docs.md +173 -0
- package/.claude/commands/TechieFlow/tasks/kb-mode-interaction.md +75 -0
- package/.claude/commands/TechieFlow/tasks/log-miss.md +160 -0
- package/.claude/commands/TechieFlow/tasks/metrics-report.md +143 -0
- package/.claude/commands/TechieFlow/tasks/mockups.md +122 -0
- package/.claude/commands/TechieFlow/tasks/productguide.md +105 -0
- package/.claude/commands/TechieFlow/tasks/refresh-status.md +135 -0
- package/.claude/commands/TechieFlow/tasks/render-workflow-docs.md +117 -0
- package/.claude/commands/TechieFlow/tasks/shard-doc.md +185 -0
- package/.claude/commands/TechieFlow/tasks/split-brd.md +131 -0
- package/.claude/commands/TechieFlow/tasks/triage-issues.md +157 -0
- package/.claude/commands/TechieFlow/tasks/verify-phase.md +579 -0
- package/.claude/commands/generate-html.md +124 -0
- package/.codex/config.toml +46 -0
- package/.codex/hooks.json +63 -0
- package/.codex/rules/techieflow.rules +8 -0
- package/.opencode/command/generate-html.md +129 -0
- package/.opencode/plugin/techieflow.js +350 -0
- package/.tfcore/TOKEN-GUIDE.md +59 -0
- package/.tfcore/agents/analyst.md +97 -0
- package/.tfcore/agents/architect.md +84 -0
- package/.tfcore/agents/flow-master.md +217 -0
- package/.tfcore/agents/verifier.md +72 -0
- package/.tfcore/checklists/architect-checklist.md +438 -0
- package/.tfcore/core-config.yaml +47 -0
- package/.tfcore/data/brainstorming-techniques.md +36 -0
- package/.tfcore/data/elicitation-methods.md +154 -0
- package/.tfcore/data/techieflow-kb.md +807 -0
- package/.tfcore/data/technical-preferences.md +3 -0
- package/.tfcore/enhanced-ide-development-workflow.md +248 -0
- package/.tfcore/hooks/block-git.sh +301 -0
- package/.tfcore/hooks/codex-adapter.py +248 -0
- package/.tfcore/hooks/guard-artifacts.sh +101 -0
- package/.tfcore/hooks/guard-status-html.sh +102 -0
- package/.tfcore/hooks/guard-status.sh +124 -0
- package/.tfcore/hooks/guard-verify.sh +108 -0
- package/.tfcore/hooks/metrics-session.sh +129 -0
- package/.tfcore/hooks/session-pointer.sh +52 -0
- package/.tfcore/hooks/sweep-artifacts.sh +198 -0
- package/.tfcore/install-manifest.yaml +231 -0
- package/.tfcore/routing.yaml +105 -0
- package/.tfcore/tasks/_metrics-emit-gate.md +138 -0
- package/.tfcore/tasks/_smoke-test-policy.md +98 -0
- package/.tfcore/tasks/_status-update-gate.md +78 -0
- package/.tfcore/tasks/_yolo-mode.md +77 -0
- package/.tfcore/tasks/advanced-elicitation.md +117 -0
- package/.tfcore/tasks/amend-docs.md +149 -0
- package/.tfcore/tasks/author-brd.md +79 -0
- package/.tfcore/tasks/build-phase.md +231 -0
- package/.tfcore/tasks/create-deep-research-prompt.md +278 -0
- package/.tfcore/tasks/create-doc.md +101 -0
- package/.tfcore/tasks/day1-brownfield.md +507 -0
- package/.tfcore/tasks/day1-greenfield.md +224 -0
- package/.tfcore/tasks/devguide.md +224 -0
- package/.tfcore/tasks/document-project.md +343 -0
- package/.tfcore/tasks/execute-checklist.md +86 -0
- package/.tfcore/tasks/facilitate-brainstorming-session.md +136 -0
- package/.tfcore/tasks/fix-issues.md +134 -0
- package/.tfcore/tasks/generate-html.md +115 -0
- package/.tfcore/tasks/handoff-phase.md +126 -0
- package/.tfcore/tasks/index-docs.md +173 -0
- package/.tfcore/tasks/kb-mode-interaction.md +75 -0
- package/.tfcore/tasks/log-miss.md +160 -0
- package/.tfcore/tasks/metrics-report.md +143 -0
- package/.tfcore/tasks/mockups.md +122 -0
- package/.tfcore/tasks/productguide.md +105 -0
- package/.tfcore/tasks/refresh-status.md +135 -0
- package/.tfcore/tasks/render-workflow-docs.md +117 -0
- package/.tfcore/tasks/shard-doc.md +185 -0
- package/.tfcore/tasks/split-brd.md +131 -0
- package/.tfcore/tasks/triage-issues.md +157 -0
- package/.tfcore/tasks/verify-phase.md +579 -0
- package/.tfcore/telemetry/SCHEMA.md +678 -0
- package/.tfcore/telemetry/install-metrics.sh +390 -0
- package/.tfcore/telemetry/pre-commit +94 -0
- package/.tfcore/telemetry/tf-metrics.sh +1415 -0
- package/.tfcore/templates/architecture-tmpl.yaml +650 -0
- package/.tfcore/templates/brainstorming-output-tmpl.yaml +156 -0
- package/.tfcore/templates/brownfield-architecture-tmpl.yaml +476 -0
- package/.tfcore/templates/competitor-analysis-tmpl.yaml +306 -0
- package/.tfcore/templates/front-end-architecture-tmpl.yaml +218 -0
- package/.tfcore/templates/fullstack-architecture-tmpl.yaml +823 -0
- package/.tfcore/templates/market-research-tmpl.yaml +252 -0
- package/.tfcore/templates/project-brief-tmpl.yaml +221 -0
- package/.tfcore/templates/v4custom/app-agents-md-tmpl.md +61 -0
- package/.tfcore/templates/v4custom/app-architecture-tmpl.md +127 -0
- package/.tfcore/templates/v4custom/app-brd-tmpl.md +204 -0
- package/.tfcore/templates/v4custom/app-checklist-tmpl.md +90 -0
- package/.tfcore/templates/v4custom/app-claude-md-tmpl.md +33 -0
- package/.tfcore/templates/v4custom/app-devguide-tmpl.md +167 -0
- package/.tfcore/templates/v4custom/app-editorconfig-tmpl.editorconfig +44 -0
- package/.tfcore/templates/v4custom/app-library-feedback-tmpl.md +31 -0
- package/.tfcore/templates/v4custom/app-productguide-tmpl.md +54 -0
- package/.tfcore/templates/v4custom/app-project-status-tmpl.md +98 -0
- package/.tfcore/templates/v4custom/app-uidesign-tmpl.md +48 -0
- package/.tfcore/templates/v4custom/app-usageguide-tmpl.md +67 -0
- package/.tfcore/templates/v4custom/build-invocation-ladder.md +190 -0
- package/.tfcore/templates/v4custom/html-render-shell.md +502 -0
- package/.tfcore/templates/v4custom/metrics-report-template.md +273 -0
- package/.tfcore/templates/v4custom/opencode-operating-contract.md +56 -0
- package/.tfcore/user-guide.md +633 -0
- package/.tfcore/utils/techieflow-doc-template.md +325 -0
- package/.tfcore/utils/tf-assets.sh +310 -0
- package/.tfcore/utils/tf-codex-bind.py +196 -0
- package/.tfcore/utils/tf-codex-telemetry.py +60 -0
- package/.tfcore/utils/tf-emit.sh +1075 -0
- package/.tfcore/utils/tf-gitignore-audit.sh +281 -0
- package/.tfcore/utils/tf-goal.sh +421 -0
- package/.tfcore/utils/tf-harness.sh +160 -0
- package/.tfcore/utils/tf-mockup-parity.mjs +555 -0
- package/.tfcore/utils/tf-mockup-parity.sh +65 -0
- package/.tfcore/utils/tf-opencode-audit.py +126 -0
- package/.tfcore/utils/tf-perf.sh +241 -0
- package/.tfcore/utils/tf-render-html.py +715 -0
- package/.tfcore/utils/tf-render-html.sh +28 -0
- package/.tfcore/utils/tf-routing-bind.sh +216 -0
- package/.tfcore/utils/tf-routing.sh +247 -0
- package/.tfcore/utils/tf-yolo.sh +119 -0
- package/.tfcore/working-in-the-brownfield.md +606 -0
- package/LICENSE +201 -0
- package/README.md +1212 -0
- package/WORKFLOW.html +1986 -0
- package/docs/TechieFlow-Installation.md +299 -0
- package/opencode.jsonc +929 -0
- package/package.json +60 -0
- package/scripts/install.mjs +992 -0
- package/scripts/test-install.mjs +505 -0
- package/scripts/validate.mjs +155 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# log-miss
|
|
2
|
+
|
|
3
|
+
The **20-second front door** for "you missed this". The owner says what an agent got wrong — in their own words, at the moment they notice it — and this task turns that sentence into a `misses.jsonl` record plus the matching checklist line. It **never boots the app, never reproduces anything, and never touches `src/` or `tests/`.**
|
|
4
|
+
|
|
5
|
+
## Why this exists
|
|
6
|
+
|
|
7
|
+
The framework had three ways to record a defect and all three were expensive. `*fix-issues` fixes it. `*triage-issues` boots the app and reproduces every issue before it writes a word. `*verify` grades a whole scope. All correct for what they do — and all far too heavy for *"the export button ignores the date filter, you missed that"*, which is how most misses are actually reported.
|
|
8
|
+
|
|
9
|
+
So they were not recorded at all. They became a sentence in chat, then a Remark if the owner was patient, then nothing. **An unrecorded miss is the exact problem the miss stream exists to solve**, and the friction of "first, boot the app" is what made it unrecorded. This task removes that friction and nothing else.
|
|
10
|
+
|
|
11
|
+
It is deliberately *not* a mode of `*triage-issues`: the moment logging requires a repro, it stops happening.
|
|
12
|
+
|
|
13
|
+
## Inputs
|
|
14
|
+
|
|
15
|
+
- `{AppName}` (required; or resolve from `core-config.yaml`).
|
|
16
|
+
- `{Description}` — the owner's own words. A sentence is enough. May name a REQ, a screen, a phase, or none of them.
|
|
17
|
+
- Optional: a screenshot path, a REQ id, `--fixed` (see §6).
|
|
18
|
+
|
|
19
|
+
## HARD SCOPE RULE
|
|
20
|
+
|
|
21
|
+
**This task writes records and documentation. Nothing else.** You may read source to identify the owning REQ. You MUST NOT edit `src/` or `tests/`, MUST NOT boot the app, MUST NOT spawn a builder sub-agent, and MUST NOT fix the thing being reported — however obvious the one-liner. If the owner wants it fixed, that is `*fix-issues`, and you say so in the report.
|
|
22
|
+
|
|
23
|
+
You also do not argue. If the owner says something was missed, it was missed. Your job is to classify it accurately, not to assess whether it was reasonable to miss.
|
|
24
|
+
|
|
25
|
+
## SEQUENTIAL Execution
|
|
26
|
+
|
|
27
|
+
### 0. Stamp the start time
|
|
28
|
+
|
|
29
|
+
`date -u +%Y-%m-%dT%H:%M:%SZ` — this run's `started` and its `found_run_id`.
|
|
30
|
+
|
|
31
|
+
### 1. Classify from what the owner said
|
|
32
|
+
|
|
33
|
+
Do not ask questions you can answer from the checklist and the docs. Resolve, in order:
|
|
34
|
+
|
|
35
|
+
1. **The owning REQ.** Match the description against `docs/{AppName}-Checklist.md` (and the DevGuide screen→REQ map if one exists). If the behaviour falls inside an existing REQ's scope, that is the `req_id`. **If nothing owns it, `req_id` is `null`** — that is a real and more interesting finding, not a failure to search hard enough.
|
|
36
|
+
2. **`miss_class`** — the closed enum (SCHEMA.md §5.5.1). The distinction that matters most:
|
|
37
|
+
- The spec said it and the build did not do it → `missed-requirement` / `partial-implementation`, `origin_phase` = the build.
|
|
38
|
+
- The spec never said it → **`unspecified-gap`**, `origin_phase` = the authoring command. This is a *design* miss and it is the one the framework was blind to.
|
|
39
|
+
- It used to work → `regression`. It works but not as specified → `wrong-behaviour`.
|
|
40
|
+
3. **`why_missed`** — which *practice* let it through (SCHEMA §5.5.6): `missing-checklist-item` (nothing covered the behaviour) · `insufficient-verify-method` (acceptance existed; no gate could catch this) · `code-audit-limitation` (never runtime-observable) · `ambiguous-acceptance` · `dependency-not-declared` · **`instruction-ignored`** (a written framework rule existed and was not honoured) · `other`. **Omit rather than guess** — but when `found_by` is `owner`/`production` this is the most valuable field on the record, so answer it. If the owner's sentence names the reason ("you were told to X"), that is usually `instruction-ignored`.
|
|
41
|
+
4. **`artifact`** — `brd` / `architecture` / `uidesign` / `checklist` / `src` / `tests` / `config` / `devguide`.
|
|
42
|
+
5. **`severity`** — `blocker` / `major` / `minor`, by owner-visible impact. Not by how hard it looks to fix.
|
|
43
|
+
6. **`origin_phase` / `origin_agent` / `origin_run_id`** — read `docs/metrics/runs.jsonl` and find the most recent non-backfilled run whose `cmd` matches the responsible phase and whose `reqs_touched` contains the REQ. Pass its `started` as `origin_run_id`. **If you cannot find one, pass nothing** — the emitter marks the record `inferred` and nulls the model, which is the honest outcome.
|
|
44
|
+
|
|
45
|
+
Ask the owner **at most one** question, and only when the classification genuinely turns on it (usually: "was this ever specified?"). In YOLO / goal mode, take the sensible reading, mark it in the report, and continue.
|
|
46
|
+
|
|
47
|
+
### 2. Collapse check — never log the same defect twice
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
bash .tfcore/utils/tf-emit.sh --open-miss REQ-UI-014 # "<miss_id> <miss_class>", or nothing
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If a miss is already open on that REQ with the same `miss_class`, **stop and say so**: "already logged as `MISS-…`, still open." Do not write a second record. Skip this check when `req_id` is `null`.
|
|
54
|
+
|
|
55
|
+
**But do not throw away what the owner just told you.** A repeat report often carries information the first record does not — most often *why* it was missed. If the open record's `why_missed` is `null` and the owner's sentence answers it, complete the record instead of duplicating it:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bash .tfcore/utils/tf-emit.sh --amend MISS-AstroLyfe-20260828-03 why_missed instruction-ignored
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
That appends a `miss-amend` (SCHEMA.md §5.5.7) — it fills a `null` field and refuses to overwrite a value that is already there, so it can never rewrite the original classification. **Never edit `misses.jsonl` by hand** (constraint 5); if `--amend` refuses, report the refusal and leave the stream alone. Say in your report which record you completed and with what.
|
|
62
|
+
|
|
63
|
+
### 3. Emit the miss
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
MID=$(bash .tfcore/utils/tf-emit.sh --next-miss-id)
|
|
67
|
+
cat <<JSON | bash .tfcore/utils/tf-emit.sh misses
|
|
68
|
+
{"kind":"miss","miss_id":"$MID","req_id":"REQ-UI-014","req_class":"UI",
|
|
69
|
+
"miss_class":"partial-implementation","artifact":"src","severity":"major",
|
|
70
|
+
"why_missed":"instruction-ignored",
|
|
71
|
+
"origin_phase":"build-phase","origin_agent":"trblazeui",
|
|
72
|
+
"origin_run_id":"<started, or omit>",
|
|
73
|
+
"found_by":"owner","found_phase":"log-miss","found_gate":null,
|
|
74
|
+
"found_run_id":"<the §0 timestamp>","failure_class":"blank-data"}
|
|
75
|
+
JSON
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`found_by` is `"owner"` unless the owner is relaying a live report, which is `"production"`. **Never write `origin_model`, `origin_harness`, `origin_confidence`, or any token/cost field** — `tf-emit.sh` resolves them from the run you named (`_metrics-emit-gate.md` constraint 10).
|
|
79
|
+
|
|
80
|
+
**The owner's words never enter the record.** Closed vocabularies only; the sentence goes in the checklist Remark, where a human reads it (constraint 7).
|
|
81
|
+
|
|
82
|
+
### 4. Write it into the checklist — the record is not the deliverable on its own
|
|
83
|
+
|
|
84
|
+
**If the repo has no `docs/*-Checklist.md`** — a `framework` or `docs` project, or an app before `*split-brd` has run — there is nothing to demote and no row to add. **Emit the record and skip to §5**, saying so in the report (`Docs: no checklist in this repo — record only`). Do not invent a checklist, do not write the miss into `PROJECT-STATUS.md` instead (the guard hook blocks it, correctly), and do not treat the absence as a reason to skip the record: a framework's own misses are exactly as worth counting as an app's, and the stream is where they belong.
|
|
85
|
+
|
|
86
|
+
Otherwise, in `docs/{AppName}-Checklist.md`:
|
|
87
|
+
|
|
88
|
+
- **Existing REQ:** Status → `Needs re-verify`, % adjusted, plus a dated Remark — `⚠ miss {today}: {the owner's words, kept}` (`⚠ prod bug {today}:` when `found_by` is `production`). Demotions are always permitted; `guard-verify.sh` never blocks one. **NEVER write `Verified` from this task.**
|
|
89
|
+
- **No owning REQ:** append a new row — next free ID in the right prefix — Status `Planned`, Remark `logged via *log-miss {today}`, plus a detail bullet with its `<a id="d-req-…">` anchor stating the **acceptance that would close it**. If it is genuinely new scope rather than a defect, log the row and flag `*amend-docs` in the report; do not invent BRD text here.
|
|
90
|
+
|
|
91
|
+
### 5. Status gate + the run record
|
|
92
|
+
|
|
93
|
+
Update `PROJECT-STATUS.md` **and** re-render `PROJECT-STATUS.html` per `_status-update-gate.md` — next command is the `*fix-issues` pointer naming the REQ. Then:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
cat <<'JSON' | bash .tfcore/utils/tf-emit.sh runs
|
|
97
|
+
{"kind":"run","app":"{AppName}","cmd":"log-miss","mode":null,
|
|
98
|
+
"started":"<start>","ended":"<now>","duration_s":<n>,
|
|
99
|
+
"reqs_touched":["REQ-UI-014"],"reqs_count":1,
|
|
100
|
+
"subagents":[],"files_written":<n>,"build_result":"not-run"}
|
|
101
|
+
JSON
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`build_result` is always `"not-run"` — this task never builds.
|
|
105
|
+
|
|
106
|
+
### 6. `--fixed` — logging a miss that is already repaired
|
|
107
|
+
|
|
108
|
+
Sometimes the owner reports a miss *after* it has been fixed ("that export bug you fixed yesterday — you should never have missed it"). Recording only the fix would lose the miss; recording only the miss would leave it permanently open.
|
|
109
|
+
|
|
110
|
+
With `--fixed`, emit the `miss` as above, then close it:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
FA=$(bash .tfcore/utils/tf-emit.sh --next-fix-attempt "$MID")
|
|
114
|
+
cat <<JSON | bash .tfcore/utils/tf-emit.sh misses
|
|
115
|
+
{"kind":"miss-fix","miss_id":"$MID","req_id":"REQ-UI-014",
|
|
116
|
+
"fix_run_id":"<started of the run that fixed it, from runs.jsonl — or omit>",
|
|
117
|
+
"fix_cmd":"log-miss","fix_attempt":$FA,"verdict_after":"Verified","reopened":false}
|
|
118
|
+
JSON
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
If you can identify the run that actually did the repair, name it and the cost attaches correctly. **If you cannot, omit `fix_run_id`** — the record is costed `none`, which is exactly right: the fix happened, and what it cost is not recoverable. Do not point at a plausible-looking run to make the number appear; that is a fabricated measurement, and one of them discredits every other cost figure in the report.
|
|
122
|
+
|
|
123
|
+
Do **not** demote the checklist row in `--fixed` mode — the REQ's status already reflects reality.
|
|
124
|
+
|
|
125
|
+
### 7. HALT — report
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
# Miss logged — {AppName}
|
|
129
|
+
{MISS-id} {miss_class} / {artifact} / {severity}
|
|
130
|
+
Why missed : {why_missed | not assessed}
|
|
131
|
+
Owning REQ : {REQ-id | none — new Planned row REQ-FN-0NN}
|
|
132
|
+
Attributed : {origin_phase} ({origin_agent}) — {linked to run <ts> | inferred, no run record found}
|
|
133
|
+
Found by : {owner|production}
|
|
134
|
+
Docs : checklist row {demoted to Needs re-verify | added as Planned}, PROJECT-STATUS updated
|
|
135
|
+
Next : /TechieFlow:agents:flow-master *fix-issues {AppName} {REQ-id} (OpenCode: /flow-master)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Say plainly when attribution came out `inferred` — the owner should know that this miss will not appear in the per-model figures, and why.
|
|
139
|
+
|
|
140
|
+
## Hard rules
|
|
141
|
+
|
|
142
|
+
- **Never fix anything.** This task's deliverable is a record and a checklist line. `*fix-issues` fixes.
|
|
143
|
+
- **Never boot the app or reproduce.** That is `*triage-issues`, and requiring it here is what stopped misses being logged at all.
|
|
144
|
+
- **Never write `Verified`.** The ceiling here is a demotion (`guard-verify.sh` enforces it).
|
|
145
|
+
- **Never name a model or a token count.** The emitter resolves attribution and cost, or writes `null`.
|
|
146
|
+
- **Never free-text into telemetry.** Closed vocabularies in the record, the owner's words in the checklist Remark.
|
|
147
|
+
- **Never argue with the report.** Classify it and log it.
|
|
148
|
+
- **Never run git.**
|
|
149
|
+
|
|
150
|
+
## Output Checklist
|
|
151
|
+
|
|
152
|
+
- [ ] Owning REQ resolved from the checklist, or `req_id: null` recorded deliberately
|
|
153
|
+
- [ ] `--open-miss` collapse check run (skipped only when `req_id` is null); duplicate reported instead of re-logged — and if the open record's `why_missed` was null and the owner's words answered it, completed with `--amend` rather than duplicated or hand-edited
|
|
154
|
+
- [ ] `miss_class` / `why_missed` / `artifact` / `severity` chosen from the closed enums — no free text in the record; `why_missed` omitted rather than guessed, but present on any owner/production report
|
|
155
|
+
- [ ] `origin_run_id` resolved from `runs.jsonl`, or deliberately omitted; **no model name written**
|
|
156
|
+
- [ ] `misses.jsonl` record emitted (+ `miss-fix` if `--fixed`)
|
|
157
|
+
- [ ] Checklist updated — demotion with a dated `⚠ miss` Remark, or a new `Planned` row with acceptance (or: no checklist in this repo, stated in the report, record still emitted)
|
|
158
|
+
- [ ] PROJECT-STATUS `.md` **and** `.html` updated with the `*fix-issues` next command
|
|
159
|
+
- [ ] `runs.jsonl` record emitted
|
|
160
|
+
- [ ] Nothing under `src/` or `tests/` changed; app never booted
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# metrics-report
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Turn `docs/metrics/*.jsonl` into a report the owner can read and, more importantly, **defend**. Produces `docs/metrics/METRICS.md` + `docs/metrics/METRICS.html`.
|
|
6
|
+
|
|
7
|
+
This task answers five questions and nothing else:
|
|
8
|
+
|
|
9
|
+
1. **First-pass rate** — what fraction of REQs reach `Verified` on attempt 1?
|
|
10
|
+
2. **Gate catch distribution** — of all failures, which gate caught them?
|
|
11
|
+
3. **Escape rate** — what fraction of defects reached UAT/production instead of being caught by a gate?
|
|
12
|
+
4. **Miss attribution and rework cost** — *what* was missed, *which phase / agent / model* let it through, and *what did fixing it cost*? (SCHEMA.md §5.5)
|
|
13
|
+
5. **Effort per phase** — what did each phase cost in **wall clock**, **tokens**, on **which model**, and with how much **subagent fan-out**? (SCHEMA.md §2.6, added 2026-08-31)
|
|
14
|
+
|
|
15
|
+
Everything else in the report is context for those five.
|
|
16
|
+
|
|
17
|
+
**Question 5 is about the RUN, not the ticket.** It is an aggregate over `runs.jsonl` grouped by `cmd`. It is emphatically **not** cycle-time-per-feature — that remains a non-goal (SCHEMA.md §0), there is no per-feature timing field, and there will not be one. "`*build-phase` runs cost a median of 26 minutes and 39k output tokens" is a phase figure. "REQ-UI-004 took two hours" is not, and nothing in the streams can honestly produce it.
|
|
18
|
+
|
|
19
|
+
Read `.tfcore/telemetry/SCHEMA.md` before you start. Read `.tfcore/tasks/_metrics-emit-gate.md` if you are unsure what may be written where.
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
- `{AppName}` (required; or resolve from `core-config.yaml`).
|
|
24
|
+
- Optional additional repo paths for a cross-project rollup: `*metrics {AppName} /path/to/OtherApp /path/to/Third`.
|
|
25
|
+
|
|
26
|
+
## SEQUENTIAL Execution
|
|
27
|
+
|
|
28
|
+
### 1. Compute the figures — do the arithmetic with the tool, not by eye
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
bash .tfcore/telemetry/tf-metrics.sh --report . --json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
For a cross-project view, pass every repo: `bash .tfcore/telemetry/tf-metrics.sh --rollup . /path/to/OtherApp --json`.
|
|
35
|
+
|
|
36
|
+
The **effort-per-phase** block (question 5) rides in the same payload under `phases`. To read it on its own — a printed table plus the per-phase detail — use:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
bash .tfcore/telemetry/tf-metrics.sh --phases . # or --phases . /path/to/OtherApp --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Same standing as `--report`: read-only, no git, agent-safe.
|
|
43
|
+
|
|
44
|
+
**Use this output. Do not recompute anything by hand.** The provenance separations of §2 are enforced inside that script — it has no code path that emits a combined figure. Hand arithmetic over the raw JSONL is exactly how an indefensible number gets into a report, and it is also how "insufficient data" quietly becomes "0%".
|
|
45
|
+
|
|
46
|
+
`--report` and `--rollup` are read-only and run no git. **Never run `--backfill-commits` or `--backfill-gates`** — those are owner-only, and `--backfill-commits` invokes git, which agents never do.
|
|
47
|
+
|
|
48
|
+
`--json` carries `per_repo[].commit_hook`. When it is `false`, this clone has no commit-telemetry hook (`pre-commit` — the retired `post-commit` form also counts), so commit telemetry is not being written **on this machine** — the commit count is understated for a reason that has nothing to do with how the project is going. Say so in §5 "What is missing" and point at `update-framework.sh <repo>` (or the owner running `--backfill-commits`). **Do not act on it yourself**: installing the hook is a framework refresh, and backfilling it is git.
|
|
49
|
+
|
|
50
|
+
If the streams are empty or the script reports nothing: say so plainly, write no report, and point at re-running `update-framework.sh` on the repo (which sets telemetry up). Do not produce a page of zeroes.
|
|
51
|
+
|
|
52
|
+
### 2. THE PROVENANCE RULE — this is what the task exists to enforce
|
|
53
|
+
|
|
54
|
+
`METRICS.md` must **never** print a combined **first-pass rate**, **gate catch distribution**, or **escape rate** that crosses either provenance boundary:
|
|
55
|
+
|
|
56
|
+
- **live vs backfilled** — records reconstructed after the fact never pool with records written at the moment of the event;
|
|
57
|
+
- **`project_type`** — `app`, `library`, and `docs` never pool with each other;
|
|
58
|
+
- **attribution and cost confidence** (§5.5) — a miss whose `origin_confidence` is not `linked` never enters a per-phase / per-agent / per-model figure, and a `miss-fix` whose `cost_attribution` is not `sole` never enters a headline cost figure.
|
|
59
|
+
|
|
60
|
+
Not as a merged figure. Not as a "total" row. Not as an "overall" summary line. Not as a helpfully-labelled average in the intro paragraph. Data on the wrong side of a boundary may appear in an **adjacent, labelled column** — never summed with the figure beside it.
|
|
61
|
+
|
|
62
|
+
**Every exclusion is printed with the figure it bounds.** The JSON carries `misses.attribution_excluded` and the three `cost_*_n` counts for exactly this: an exclusion the reader cannot see is indistinguishable from a bug, and the reader is entitled to know that a per-model miss rate was computed over 7 of 19 records.
|
|
63
|
+
|
|
64
|
+
**Any table containing backfilled data carries a footnote** naming what was reconstructed and what was inferred (`inferred[]` on the records tells you exactly which fields).
|
|
65
|
+
|
|
66
|
+
**Commit-derived metrics are exempt from both separations.** `git log` is a real append-only log, and commit volume is comparable across project types.
|
|
67
|
+
|
|
68
|
+
**Why this is not cosmetic.** A merged first-pass rate cannot be defended when someone asks how attempts were counted, because backfilled attempts are inferred from a mutable status table that never recorded them. A pooled gate distribution understates the visual gate, because `library` and `docs` projects never had screens to fail on. One indefensible figure contaminates every other number in the report — the reader stops trusting the page, not just the row.
|
|
69
|
+
|
|
70
|
+
If you find yourself wanting to write "overall, across all projects, …" — **that sentence is the thing this task forbids.** Write the segmented figures and let them stand apart.
|
|
71
|
+
|
|
72
|
+
### 3. Honesty rules for every number on the page
|
|
73
|
+
|
|
74
|
+
- **Fewer than 3 supporting records → print `insufficient data (n=…)`, never a number.** A 100% first-pass rate from one REQ is noise wearing a suit.
|
|
75
|
+
- **Never estimate, interpolate, or infer a metric that was not measured.** A missing number is reported as missing. `cost_usd` is `null` on every Claude Code and Codex record (no cost source exists, and inventing one would be an estimate presented as a measurement) — report **tokens**, name the harness, and say why dollars are absent. **Do not multiply tokens by a rate card.** Real dollars appear only on OpenCode records and are never pooled with the others.
|
|
76
|
+
- **Measured cost and apportioned cost are two columns, never one number.** A fix run that repaired three misses has one token window; dividing it three ways is arithmetic. Print `cost_attribution:"sole"` figures as the headline and `shared:<n>` figures beside them, labelled as apportioned. `none` records are counted and costed at nothing.
|
|
77
|
+
- **Never invent a metric that has no stream behind it.** No cycle-time-per-feature: the unit of work in this framework is the run, not the ticket, and that is deliberate.
|
|
78
|
+
- Records with `project_type_inferred: true` are **unclassified** — give them their own row labelled as such. Do not silently fold them into `app`.
|
|
79
|
+
- Name the REQs excluded from the live first-pass rate because they carry backfilled history (the tool lists them). A hidden exclusion is a lie of omission.
|
|
80
|
+
- **Miss counts are poolable; miss *attribution* is not.** A miss counts as a miss whoever missed it, so raw counts and the class distribution may pool freely. The per-phase / per-agent / per-model rates run over `origin_confidence:"linked"` records only, and the excluded count is printed with them.
|
|
81
|
+
- **A per-model miss rate is observational, not causal, and the page must say so once.** Which model gets the hard work is not random, and a reader who takes the ranking at face value will make a routing decision on a confounded number. **The same warning applies to per-phase effort:** `*build-phase` costing more than `*log-miss` is a fact about what those phases *are*, not a finding about either.
|
|
82
|
+
- **Per-phase effort carries three denominators and all three are printed.** Token figures cover only runs whose window was computable (`tokens_measured_n` vs `tokens_unmeasured_n`); **fan-out figures cover `tokens_scope:"tree"` records only**, because a `main` window never read the subagent transcripts and its `0` means *not observed*, not *none ran*; dollars are per harness and never pooled. A phase figure quoted without its denominator is the TF-005 defect wearing a different hat.
|
|
83
|
+
- **Where declared and measured fan-out disagree, the measured one is right, and say both.** `subagents` is a list an agent typed into its own emit; `subagent_runs` is counted from the harness's own store (SCHEMA §2.6). The gap between them is itself a finding about how well tasks self-report.
|
|
84
|
+
|
|
85
|
+
### 4. Write `docs/metrics/METRICS.md`
|
|
86
|
+
|
|
87
|
+
Use `.tfcore/templates/v4custom/metrics-report-template.md` for the shape. Fill only what the data supports; delete sections with no data rather than printing empty tables.
|
|
88
|
+
|
|
89
|
+
**Never write metrics into `PROJECT-STATUS.md`** (`guard-status.sh` blocks any H2 outside the template's section set, correctly) **or into any `*-Checklist.md`** (`guard-verify.sh` inspects those writes; a stray metrics edit risks a false block). The report lives in `docs/metrics/` and nowhere else.
|
|
90
|
+
|
|
91
|
+
**Do not modify any `.jsonl` file.** They are append-only history. Nothing derived is ever written back into a stream.
|
|
92
|
+
|
|
93
|
+
### 5. Render `docs/metrics/METRICS.html`
|
|
94
|
+
|
|
95
|
+
Per `.tfcore/tasks/generate-html.md` using the shared shell (`.tfcore/templates/v4custom/html-render-shell.md`) — theme toggle, never hand-rolled HTML. METRICS is a human doc, so it renders; the checklists still never do.
|
|
96
|
+
|
|
97
|
+
### 6. HALT — report
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
# Metrics — {AppName}
|
|
101
|
+
Streams: runs {r} · gates {g} ({b} backfilled) · sessions {s} · commits {c} · misses {m}
|
|
102
|
+
First-pass rate: {live, per project_type — or "insufficient data"}
|
|
103
|
+
Gate catch: {top gate} {n}% | Escape rate: {x}%
|
|
104
|
+
Misses: {m} logged ({o} open) · design-miss share {d}% · attributed {a}/{m}
|
|
105
|
+
Rework cost: {tokens} tokens per miss (measured, n={s}) {| $X measured, OpenCode only}
|
|
106
|
+
Effort/phase: heaviest {cmd} — {time} wall, {tokens} out ({pct} of all output), fan-out observed on {n}/{N} runs
|
|
107
|
+
Written: docs/metrics/METRICS.md + .html
|
|
108
|
+
{if backfilled records present: "Backfilled data is reported in a separate column and cannot support a published first-pass rate."}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Then stop. Do not run the status gate — this task reports on history, it does not advance the project, and PROJECT-STATUS is not where metrics go.
|
|
112
|
+
|
|
113
|
+
## Hard rules
|
|
114
|
+
|
|
115
|
+
- **No combined figure across live/backfilled, across `project_type`, across attribution confidence, or across cost attribution** — for first-pass rate, gate catch distribution, escape rate, miss rates, or cost per miss. This is the rule the whole task exists for.
|
|
116
|
+
- **The miss stream's escape share is reported BESIDE the `gates.jsonl` escape rate, never merged into it.** They are computed from different records by different definitions; presenting one number for both would make the word meaningless.
|
|
117
|
+
- **Never run git**, and never run `tf-metrics.sh --backfill-*` — owner-only.
|
|
118
|
+
- **Never write into `PROJECT-STATUS.md`, any `*-Checklist.md`, or any `.jsonl` stream.**
|
|
119
|
+
- **`insufficient data` is a legitimate result.** Print it without apology and without a workaround.
|
|
120
|
+
- **Never store or quote requirement text** pulled from a checklist to "make the report readable". REQ IDs only — the constraint that governs the streams governs the report built from them.
|
|
121
|
+
- Do not refactor the streams, re-sort them, or "clean up" a malformed line. Report the line number and move on.
|
|
122
|
+
|
|
123
|
+
## Output Checklist
|
|
124
|
+
|
|
125
|
+
- [ ] `tf-metrics.sh --report --json` run; figures taken from it, not recomputed by hand
|
|
126
|
+
- [ ] Live and backfilled reported separately; `app`/`library`/`docs` reported separately
|
|
127
|
+
- [ ] Miss attribution figures computed over `linked` records only, with the excluded count printed beside them
|
|
128
|
+
- [ ] `why_missed` distribution reported against **records that carry the field** *and* could have carried it — misses predating the field's introduction (`FIELD_SINCE`, SCHEMA §5.5.6) are outside the denominator and their count is stated; escapes lacking it are flagged, with `--amend` named as the remedy
|
|
129
|
+
- [ ] `miss-amend` records folded into their parents before counting; amendments applied and orphaned amends both reported
|
|
130
|
+
- [ ] Open-miss count excludes `wont-fix` (a decision, not a backlog item) and reports it in its own bucket
|
|
131
|
+
- [ ] Measured (`sole`) and apportioned (`shared:n`) rework cost in separate labelled columns — never one blended number
|
|
132
|
+
- [ ] Rework-cost means divide by the records that **carry** `tokens_out` (`tokens_per_miss_measured_n`), with `tokens_unrecorded_sole_n` stated — an unrecorded repair is never averaged in as a free one (SCHEMA §5.5.8)
|
|
133
|
+
- [ ] Effort-per-phase section written from `phases` — per-phase wall clock, tokens, **per-model output split**, and subagent fan-out
|
|
134
|
+
- [ ] Every per-phase token figure carries `tokens_measured_n` / `tokens_unmeasured_n`; every fan-out figure carries `fanout.observed_n` and names why the rest were excluded (not `tree` scope vs predating the field)
|
|
135
|
+
- [ ] Declared (`subagents`) and measured (`subagent_runs`) fan-out both shown where they disagree, with the measured one named as authoritative
|
|
136
|
+
- [ ] No per-feature or per-REQ cycle time anywhere on the page — the unit is the run
|
|
137
|
+
- [ ] Dollars quoted only where a harness measured them; no rate-card estimate anywhere on the page
|
|
138
|
+
- [ ] No "overall" / "total" / "combined" figure for first-pass rate, gate distribution, or escape rate
|
|
139
|
+
- [ ] Every table containing backfilled data carries the inferred-fields footnote
|
|
140
|
+
- [ ] Metrics with n < 3 printed as `insufficient data (n=…)`
|
|
141
|
+
- [ ] Excluded (backfill-tainted) REQs named
|
|
142
|
+
- [ ] `docs/metrics/METRICS.md` written + `METRICS.html` rendered via the shared shell
|
|
143
|
+
- [ ] No `.jsonl` file touched; PROJECT-STATUS and the checklist untouched
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# mockups
|
|
2
|
+
|
|
3
|
+
Produce the **UI design / mockups** for a greenfield app: a per-screen UI Design Spec (`docs/{AppName}-UIDesign.md`) plus **rendered HTML mockups** (`docs/mockups/*.html`) styled to look like TrBlazeUI, each annotated with a `region → TrBlazeUI control` component map. This is the visual design the build is matched against and the verifier's visual-truth gate diffs the live app against.
|
|
4
|
+
|
|
5
|
+
## Why this exists
|
|
6
|
+
|
|
7
|
+
A greenfield app has no code, so its UI is built freehand from prose requirements — which is exactly why a new app's UI comes out broken (overlapping controls, wrong layout, nothing to verify against). Mockups give the build an **approved visual contract** and give `verify-phase.md §4b` a **baseline to diff** the running screen against. They are **TrBlazeUI-replicable by construction**: the analyst designs only with controls the library actually ships, so `/trblazeui` can reproduce them 1:1.
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- **At greenfield day-1** — auto-run by `day1-greenfield §3.6`, after the BRD draft; approved with the BRD + Architecture before build.
|
|
12
|
+
- **On demand** — `*mockups {AppName}` to (re)generate, or `*mockups {AppName} --update` to refresh only changed/new screens after an `*amend-docs` that added UI.
|
|
13
|
+
- **Greenfield only.** Brownfield already has built screens — it uses the DevGuide's captured screenshots (`devguide §5a/§5b`) as its visual baseline instead.
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
- `{AppName}` (required; or resolve from `core-config.yaml`).
|
|
18
|
+
- `{Scope}` — OPTIONAL: `all` (default) · a screen/route · a comma-list. Limits which screens are (re)mocked.
|
|
19
|
+
- `--update` — OPTIONAL: refresh only screens whose BRD feature changed or that are new; preserve unchanged mockups verbatim.
|
|
20
|
+
|
|
21
|
+
## SEQUENTIAL Execution
|
|
22
|
+
|
|
23
|
+
### 1. Read the TrBlazeUI component catalog FIRST (design only with what exists)
|
|
24
|
+
|
|
25
|
+
Before designing anything, learn what the library actually provides:
|
|
26
|
+
- Read `.trblazeui/TrBlazeUI-AI-Reference.md` (the component reference; if absent, run `dotnet build` once to deploy it, or ask the `/trblazeui` agent for its component catalog).
|
|
27
|
+
- Optionally converse with the **`/trblazeui` agent** to confirm which controls exist and how they're composed (it owns the library knowledge).
|
|
28
|
+
- Build a working list of available controls (nav, cards, grids, forms, dialogs, charts, layout shells, inputs). **You design ONLY with these** — a mockup that uses a layout/control TrBlazeUI can't produce is worse than none (it guarantees drift). If a screen genuinely needs something the library lacks, note it and log a `docs/{AppName}-TrBlazeUI-Feedback.md` entry (TR-NNN) so the gap is tracked rather than silently designed-in.
|
|
29
|
+
|
|
30
|
+
### 2. Derive the screen list from the BRD
|
|
31
|
+
|
|
32
|
+
- Read `docs/{AppName}-BRD.md` §9 Feature catalog — its screens-and-routes tables and per-feature workflows are the screen list. Also read `docs/{AppName}-Architecture.md` for the UI host/layout choice.
|
|
33
|
+
- Produce the flat screen list: `screen (route) → role(s) → owning BRD-N`. Echo a one-line count: `N screens to mock`.
|
|
34
|
+
- **No-UI app:** if the concept is purely an API/service with no screens, record `docs/{AppName}-UIDesign.md` = "skipped — no UI in this app" and HALT (this is not an error; `day1-greenfield` treats it as skipped).
|
|
35
|
+
|
|
36
|
+
### 3. Design each screen — spec + rendered mockup (FAN OUT for many screens)
|
|
37
|
+
|
|
38
|
+
Load `.tfcore/templates/v4custom/app-uidesign-tmpl.md`. For each screen (fan out across subagents when there are many — one per screen-cluster — to bound tokens):
|
|
39
|
+
|
|
40
|
+
1. Decide the **layout** (regions: nav, sidebar, content blocks) using TrBlazeUI's layout shell components.
|
|
41
|
+
2. Write the **component map** — every region → the specific TrBlazeUI control that renders it + the data it shows + its empty/loading/error states. This is the build contract.
|
|
42
|
+
3. Produce the **rendered mockup** `docs/mockups/{screen-slug}.html`: a self-contained HTML page that *looks like the real screen* using TrBlazeUI's design language (its CSS tokens / classes where known, or a close visual approximation — spacing, colors, typography, component shapes). Use realistic placeholder data so the layout reads true. Each mockup is a static preview, not wired — but its STRUCTURE (regions, control types, arrangement) must be what the build will produce.
|
|
43
|
+
4. Fill the screen's spec block in `docs/{AppName}-UIDesign.md` (mockup link, component map table, layout one-liner, interaction + state notes).
|
|
44
|
+
|
|
45
|
+
Keep the visual language consistent across screens (one shell, one theme, one spacing system) so the set reads as one app.
|
|
46
|
+
|
|
47
|
+
#### 3b. ANCHOR THE MOCKUP — `data-testid` is what makes it gradeable (MANDATORY since 2026-08-31)
|
|
48
|
+
|
|
49
|
+
A mockup is not only a picture for the owner to approve. Since 2026-08-31 it is **the input to a gate**: `verify-phase` §4b2 compares the built screen against it mechanically, and **it can only compare elements that carry the same `data-testid` on both sides.**
|
|
50
|
+
|
|
51
|
+
**Put a `data-testid` on every element the build must get right**, using the same name the built component will carry:
|
|
52
|
+
|
|
53
|
+
- the layout regions — `app-sidebar`, `app-header`, `main` (match the shell's real names; a mockup that says `sidebar` where the app says `app-sidebar` pairs with nothing and grades nothing);
|
|
54
|
+
- every **badge, pill, chip and status indicator** — these are the single most-escaped class, because a pill flattened to plain text still *has text* and passes every other gate;
|
|
55
|
+
- every **icon or icon button**;
|
|
56
|
+
- each **KPI tile / card**, individually — especially two adjacent cards the design distinguishes (a dashed border meaning *estimate* beside a solid one meaning *measured* is a real distinction the gate now reads, and it can only read it on an anchored element);
|
|
57
|
+
- each **table** and each **chart**;
|
|
58
|
+
- any value cell whose **width is part of the design** — a formatted number that must not break mid-digit.
|
|
59
|
+
|
|
60
|
+
**Why this is worth the keystrokes, stated plainly.** The gate's depth is bounded by what both sides anchor, and the failure mode is **silent and inverted: the less of a screen the gate can see, the cleaner its verdict looks.** A screen the gate cannot reach into does not report "I could not grade this" as a defect — it reports `UNGRADEABLE`, which is honest but buys nothing. Upstream, three columns anchored only at the container level yielded three coarse comparisons and a `PASS`, while a human then found two structural defects on that same screen by eye (TfLens **TF-011**).
|
|
61
|
+
|
|
62
|
+
Two things make this cheaper than it sounds:
|
|
63
|
+
|
|
64
|
+
- **The walker descends any anchored subtree** — card, column, grid, `<dl>`, list, table alike — so an anchor on a *container* now buys real depth, not just one comparison. You do not need an id on every leaf.
|
|
65
|
+
- **The gate tells you what is missing.** Each screen's run output carries `anchor_deficit.add_data_testid_to_mockup`, naming the app testids the mockup lacks. Closing the gap later is a mechanical edit — but doing it here is free.
|
|
66
|
+
|
|
67
|
+
**Do not invent ids the build will not use.** An anchor that pairs with nothing is worse than no anchor: it costs effort and grades nothing. Take the names from the component map you just wrote in step 2, and use the same ones in `*build-phase`.
|
|
68
|
+
|
|
69
|
+
### 4. Assemble + render
|
|
70
|
+
|
|
71
|
+
- Fill the UIDesign header (§"Design system" from §1's catalog — name the layout shell, theme, and the controls inventory the app uses).
|
|
72
|
+
- Regenerate the UIDesign Table of Contents (slug rule `html-render-shell.md §1`; list each `### Screen:` under "Screens").
|
|
73
|
+
- Render `docs/{AppName}-UIDesign.md` → `docs/{AppName}-UIDesign.html` via `.tfcore/tasks/generate-html.md` (shared shell — it's a human doc). The `docs/mockups/*.html` screens are already HTML; leave them as-is.
|
|
74
|
+
- **`--update`:** only (re)write changed/new screens + their mockups; preserve the rest verbatim; re-render the UIDesign HTML.
|
|
75
|
+
|
|
76
|
+
### 5. PROJECT-STATUS note (light touch — NOT the full gate)
|
|
77
|
+
|
|
78
|
+
Add/refresh one line under "Where I am" / artifacts: `Mockups generated {date}: docs/{AppName}-UIDesign.md (+ .html) + docs/mockups/ ({N} screens)`. This task does not change build/verify state — do not touch `current_phase` or `last_verified_build`. (When run inside `day1-greenfield`, that task owns the status write.)
|
|
79
|
+
|
|
80
|
+
### 5a. Emit the run record (telemetry)
|
|
81
|
+
|
|
82
|
+
Same turn as the status/PROJECT-STATUS write. Doctrine + the ten constraints: `.tfcore/tasks/_metrics-emit-gate.md`. Schema: `.tfcore/telemetry/SCHEMA.md` §2. Stamp `started` with `date -u +%Y-%m-%dT%H:%M:%SZ` as your FIRST action of this task — it cannot be reconstructed at the end.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
cat <<'JSON' | bash .tfcore/utils/tf-emit.sh runs
|
|
86
|
+
{"kind":"run","app":"{AppName}","cmd":"mockups","mode":null,
|
|
87
|
+
"started":"<start>","ended":"<now>","duration_s":<n>,
|
|
88
|
+
"reqs_touched":[],"reqs_count":0,
|
|
89
|
+
"subagents":[],"files_written":<n>,"build_result":"not-run"}
|
|
90
|
+
JSON
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`reqs_touched` carries REQ IDs only — never requirement text — and `[]` is correct when this task touched no specific REQ. **Telemetry has no veto:** if the emit fails, the phase still succeeded; do not retry, do not diagnose, do not mention it.
|
|
94
|
+
|
|
95
|
+
### 6. HALT — report
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
# Mockups — {AppName}
|
|
99
|
+
Screens mocked: {N} TrBlazeUI controls used: {list} Library gaps logged: {g}
|
|
100
|
+
Files: docs/{AppName}-UIDesign.md (+ .html) · docs/mockups/*.html ({N} screens)
|
|
101
|
+
Next: review/approve the mockups (open docs/mockups/*.html); they are the visual contract the build matches and the verifier diffs against. Then *split-brd → *build-phase.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Hard rules
|
|
105
|
+
|
|
106
|
+
- **TrBlazeUI-replicable only.** Read the component catalog first; design with controls that exist. A mockup the library can't produce is a defect — flag + log the gap, never design it in silently.
|
|
107
|
+
- **Every screen has a component map** (`region → TrBlazeUI control`). The map is the build contract; a pretty picture with no control mapping is not enough.
|
|
108
|
+
- **Mockups are a HUMAN doc → rendered to HTML.** Unlike the checklist, the UIDesign spec renders to HTML; the mockups are HTML by construction.
|
|
109
|
+
- **Greenfield only.** Do not run for a brownfield app with built screens (use the DevGuide screenshots instead).
|
|
110
|
+
- **Never edit source code.** This task only writes the design docs/mockups.
|
|
111
|
+
- **Incremental on `--update`.** Preserve unchanged screens verbatim; only remock what changed.
|
|
112
|
+
|
|
113
|
+
## Output Checklist
|
|
114
|
+
|
|
115
|
+
- [ ] TrBlazeUI component catalog read FIRST; design uses only existing controls (gaps logged to the feedback file)
|
|
116
|
+
- [ ] Screen list derived from BRD §9 feature catalog (or "skipped — no UI" recorded)
|
|
117
|
+
- [ ] `docs/{AppName}-UIDesign.md` written: per-screen spec with a `region → TrBlazeUI control` component map + state notes
|
|
118
|
+
- [ ] `docs/mockups/{screen}.html` rendered for every screen, styled to look like TrBlazeUI, consistent across the set
|
|
119
|
+
- [ ] **Every mockup anchored with `data-testid` (§3b)** — layout regions under the shell's real names, plus every badge/pill, icon, KPI tile, table, chart and width-critical value cell. Ids taken from the §2 component map so they pair with what the build will render. Without them `verify-phase` §4b2 returns `UNGRADEABLE`, which is not a pass.
|
|
120
|
+
- [ ] `docs/{AppName}-UIDesign.html` rendered (human doc); mockups left as HTML; the checklist is NOT involved here
|
|
121
|
+
- [ ] PROJECT-STATUS got the one-line mockups note (no full status gate)
|
|
122
|
+
- [ ] Report printed; mockups ready for owner approval
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# productguide
|
|
2
|
+
|
|
3
|
+
Generate (or incrementally refresh) the **end-user Product Guide** — the screenshot-illustrated, task-oriented manual that teaches an *external user* how to use the app, screen by screen. It is the user-facing sibling of the DevGuide: same screen inventory and the **same captured screenshots**, but re-told as "what this is for / how to do it" instead of code lineage.
|
|
4
|
+
|
|
5
|
+
Output: `docs/{AppName}-ProductGuide.md` (single doc, small apps) **or** a `docs/productguides/` subfolder with an index + one `docs/productguides/{AppName}-ProductGuide-{Role}.md` per role (large apps) — **always with a sibling `.html`** (it is a human-facing doc, so MD + HTML are both mandatory, every time). Template: `.tfcore/templates/v4custom/app-productguide-tmpl.md`.
|
|
6
|
+
|
|
7
|
+
## When to use
|
|
8
|
+
|
|
9
|
+
- **Whenever you need user-facing documentation** — for onboarding, a help site, a manual, app-store/marketing copy, or handing the product to non-technical users. On-demand by design (`*productguide {AppName}`).
|
|
10
|
+
- **Re-runnable**: `--update` refreshes only changed screens (and re-shoots their screenshots) — cheap to keep current as the UI evolves.
|
|
11
|
+
- It is purely a documentation task — it **never edits source code**.
|
|
12
|
+
|
|
13
|
+
## Inputs
|
|
14
|
+
|
|
15
|
+
- `{AppName}` (required; or resolve from `core-config.yaml`).
|
|
16
|
+
- `{Scope}` — OPTIONAL: `all` (default) · a role name · a screen/route · a comma-list. Limits which screens are (re)written.
|
|
17
|
+
- `--update` — OPTIONAL: incremental refresh — only re-write screens whose UI changed since the guide's last generation (or only `{Scope}`), preserving every unchanged section verbatim.
|
|
18
|
+
- `--single` / `--split` — OPTIONAL: force the structure instead of auto-deciding (same rule as devguide §3).
|
|
19
|
+
|
|
20
|
+
## SEQUENTIAL Execution
|
|
21
|
+
|
|
22
|
+
### 1. Confirm there is a built, runnable UI
|
|
23
|
+
|
|
24
|
+
The Product Guide documents the real running app. If the repo is doc-only / not yet built (e.g. greenfield before any build), HALT: "No built UI yet — the Product Guide documents the running app with real screenshots. Build first, then run `*productguide {AppName}`." (A greenfield app gets its Product Guide AFTER it is built, exactly like its DevGuide.)
|
|
25
|
+
|
|
26
|
+
### 2. Gather the screen inventory + screenshots (reuse, don't reinvent)
|
|
27
|
+
|
|
28
|
+
The DevGuide already did the hard discovery work — reuse it:
|
|
29
|
+
- Read the **DevGuide** (`docs/{AppName}-DevGuide.md`, or the split set under `docs/devguides/`) for the role→menu map, the screen list, the real post-login landing per role (LANDING-TRUTH), and each screen's purpose.
|
|
30
|
+
- Use the **screenshots** the DevGuide's OBSERVE pass captured under `docs/screenshots/{AppName}/` (`{role}-{screen-slug}.png`, + `-mobile` where present). These are the images the guide embeds.
|
|
31
|
+
- Read the **BRD** §9 feature catalog (feature purpose/benefit, personas) and the **UsageGuide** (user flows + known limitations) for the plain-language "what it's for" and "tips".
|
|
32
|
+
|
|
33
|
+
**If screenshots are missing or stale** (no DevGuide ran OBSERVE, or the UI changed): capture them yourself before writing — boot the app and screenshot each in-scope screen via the **verifier render sweep** (`.tfcore/tasks/verify-phase.md §4a`, the same mechanism devguide §5a uses), saving to `docs/screenshots/{AppName}/`. Follow `.tfcore/tasks/_smoke-test-policy.md` (you run it yourself; bring up multi-service stacks; documented test users; "can't run on Linux" is banned). If the app genuinely cannot be booted after the full escalation, HALT and tell the user to bring the stack up — a Product Guide with no real screenshots is not acceptable (do NOT fabricate images or ship a screenshot-less guide silently).
|
|
34
|
+
|
|
35
|
+
### 3. Decide structure — single doc vs per-role split
|
|
36
|
+
|
|
37
|
+
Same rule as devguide §3: **split per role** when `roles ≥ 3` OR `screens > 12` OR any role has `> 8` screens; else single. Honor `--single`/`--split`. A split guide lives in `docs/productguides/` (index + per-role files co-located, so relative links resolve); a single guide is `docs/{AppName}-ProductGuide.md`. On a structure switch (single↔split), move/delete the stale-location copy so only one canonical copy survives.
|
|
38
|
+
|
|
39
|
+
### 4. Write the guide — END-USER voice, screenshot per screen (FAN OUT per role)
|
|
40
|
+
|
|
41
|
+
Fan out one subagent per role (or screen-cluster) to bound tokens, each scoped to its slice. From the template, for each in-scope screen write a `### {Feature / Screen}` block:
|
|
42
|
+
- **What it's for** — the user benefit in plain language (from the BRD feature catalog), NOT code or architecture.
|
|
43
|
+
- **How to use it** — numbered, task-oriented steps a real user follows (click X, enter Y, see Z), in navigation order.
|
|
44
|
+
- **The real screenshot** — embed `` (path relative to where the guide lives: `screenshots/...` from `docs/`, `../screenshots/...` from `docs/productguides/`).
|
|
45
|
+
- **Tips & notes** — gotchas/limits in plain language (translate any UsageGuide "known limitation" into user terms; never expose REQ/defect IDs or internal jargon).
|
|
46
|
+
|
|
47
|
+
Order screens the way a user would actually move through them (the DevGuide menu map). Omit pure-plumbing/internal screens an external user never sees (unless writing the admin-role guide). Fill the template header (Welcome, Getting started with the sign-in shot, Roles at a glance) from the BRD + DevGuide.
|
|
48
|
+
|
|
49
|
+
**Voice rule:** this is for someone who has never seen the code and may not be technical. No file paths, no service/proc names, no REQ IDs, no architecture. If a sentence would only make sense to a developer, it belongs in the DevGuide, not here.
|
|
50
|
+
|
|
51
|
+
For `--update`: locate the existing guide (either layout), re-write only changed/in-scope screens (re-shoot their screenshots), preserve the rest verbatim.
|
|
52
|
+
|
|
53
|
+
### 5. Render to HTML (MANDATORY — both MD and HTML, every time)
|
|
54
|
+
|
|
55
|
+
Render every produced markdown to a sibling `.html` via `.tfcore/tasks/generate-html.md` (shared shell — light/dark theme, TOC). The Product Guide is a human-facing doc, so **MD + HTML are both required**; a markdown-only Product Guide is an incomplete deliverable. For a split guide, render the index + every role file in place inside `docs/productguides/`. (The checklist is the only doc that stays markdown-only; this is not that.)
|
|
56
|
+
|
|
57
|
+
### 6. Note it in PROJECT-STATUS (light touch — NOT the full gate)
|
|
58
|
+
|
|
59
|
+
Add/refresh one line under "Where I am" / artifacts: `Product Guide generated {date}: docs/{AppName}-ProductGuide.md (single) or docs/productguides/ (split) (+ .html); {M} screens, {S} screenshots`. This task does not change build/verify state — do not touch `current_phase` or `last_verified_build`. Re-render `PROJECT-STATUS.html` only if you edited it.
|
|
60
|
+
|
|
61
|
+
### 6a. Emit the run record (telemetry)
|
|
62
|
+
|
|
63
|
+
Same turn as the status/PROJECT-STATUS write. Doctrine + the ten constraints: `.tfcore/tasks/_metrics-emit-gate.md`. Schema: `.tfcore/telemetry/SCHEMA.md` §2. Stamp `started` with `date -u +%Y-%m-%dT%H:%M:%SZ` as your FIRST action of this task — it cannot be reconstructed at the end.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
cat <<'JSON' | bash .tfcore/utils/tf-emit.sh runs
|
|
67
|
+
{"kind":"run","app":"{AppName}","cmd":"productguide","mode":null,
|
|
68
|
+
"started":"<start>","ended":"<now>","duration_s":<n>,
|
|
69
|
+
"reqs_touched":[],"reqs_count":0,
|
|
70
|
+
"subagents":[],"files_written":<n>,"build_result":"not-run"}
|
|
71
|
+
JSON
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`reqs_touched` carries REQ IDs only — never requirement text — and `[]` is correct when this task touched no specific REQ. **Telemetry has no veto:** if the emit fails, the phase still succeeded; do not retry, do not diagnose, do not mention it.
|
|
75
|
+
|
|
76
|
+
### 7. HALT — report
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
# Product Guide — {AppName}
|
|
80
|
+
Structure: {single | split per role (R files)}
|
|
81
|
+
Roles: {list} Screens documented: {M} Screenshots used/captured: {S} (existing {e} / newly captured {c})
|
|
82
|
+
Files: docs/{AppName}-ProductGuide.md (single) — or docs/productguides/{AppName}-ProductGuide.md + -{Role}.md ... — and sibling .html (always)
|
|
83
|
+
Next: open the .html in a browser; run `*productguide {AppName} --update` after UI changes.
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Hard rules
|
|
87
|
+
|
|
88
|
+
- **End-user voice, never developer.** No code paths, service/proc names, REQ/defect IDs, or architecture. If it only makes sense to a developer, it's not Product-Guide content.
|
|
89
|
+
- **Every screen carries a REAL screenshot** (reused from the DevGuide's `docs/screenshots/{AppName}/`, or freshly captured via the verifier render sweep). Never fabricate an image; never ship a screenshot-less guide silently — HALT and ask for the app to be booted if capture genuinely fails.
|
|
90
|
+
- **MD + HTML always.** This is a human-facing doc; both versions are mandatory on every run (unlike the checklist, which is markdown-only).
|
|
91
|
+
- **Never edit source code.** Documentation only.
|
|
92
|
+
- **Reuse the DevGuide's discovery + screenshots** rather than re-deriving the screen map — they share the same screen inventory (developers' view vs users' view of the same screens).
|
|
93
|
+
- **Incremental by default on `--update`.** Preserve unchanged screens verbatim; only re-write + re-shoot what changed.
|
|
94
|
+
- **Boot the app yourself if screenshots are missing** (incl. multi-service stacks; documented test users) per `_smoke-test-policy.md`; asking the user is the last resort. Never run git.
|
|
95
|
+
|
|
96
|
+
## Output Checklist
|
|
97
|
+
|
|
98
|
+
- [ ] Built UI confirmed (HALT if doc-only / not yet built)
|
|
99
|
+
- [ ] Screen inventory + screenshots reused from the DevGuide (`docs/screenshots/{AppName}/`), or freshly captured via the render sweep where missing/stale
|
|
100
|
+
- [ ] Structure decided (single vs split per role) with stated reason / honored `--single`/`--split`
|
|
101
|
+
- [ ] Each screen block: plain-language "what it's for" + numbered "how to use it" + a REAL screenshot + tips — END-USER voice (no code/proc/REQ-ID/architecture)
|
|
102
|
+
- [ ] Header sections (Welcome, Getting started w/ sign-in shot, Roles at a glance) filled from BRD + DevGuide
|
|
103
|
+
- [ ] **Both MD and HTML produced** (index + role files if split) — HTML is mandatory, not optional
|
|
104
|
+
- [ ] PROJECT-STATUS got the one-line Product Guide note (no full status gate)
|
|
105
|
+
- [ ] Report printed with structure, counts, screenshots used/captured
|