@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.
Files changed (151) hide show
  1. package/.claude/commands/TechieFlow/agents/analyst.md +97 -0
  2. package/.claude/commands/TechieFlow/agents/architect.md +84 -0
  3. package/.claude/commands/TechieFlow/agents/flow-master.md +217 -0
  4. package/.claude/commands/TechieFlow/agents/verifier.md +72 -0
  5. package/.claude/commands/TechieFlow/tasks/_metrics-emit-gate.md +138 -0
  6. package/.claude/commands/TechieFlow/tasks/_smoke-test-policy.md +98 -0
  7. package/.claude/commands/TechieFlow/tasks/_status-update-gate.md +78 -0
  8. package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +77 -0
  9. package/.claude/commands/TechieFlow/tasks/advanced-elicitation.md +117 -0
  10. package/.claude/commands/TechieFlow/tasks/amend-docs.md +149 -0
  11. package/.claude/commands/TechieFlow/tasks/author-brd.md +79 -0
  12. package/.claude/commands/TechieFlow/tasks/build-phase.md +231 -0
  13. package/.claude/commands/TechieFlow/tasks/create-deep-research-prompt.md +278 -0
  14. package/.claude/commands/TechieFlow/tasks/create-doc.md +101 -0
  15. package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +507 -0
  16. package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +224 -0
  17. package/.claude/commands/TechieFlow/tasks/devguide.md +224 -0
  18. package/.claude/commands/TechieFlow/tasks/document-project.md +343 -0
  19. package/.claude/commands/TechieFlow/tasks/execute-checklist.md +86 -0
  20. package/.claude/commands/TechieFlow/tasks/facilitate-brainstorming-session.md +136 -0
  21. package/.claude/commands/TechieFlow/tasks/fix-issues.md +134 -0
  22. package/.claude/commands/TechieFlow/tasks/generate-html.md +115 -0
  23. package/.claude/commands/TechieFlow/tasks/handoff-phase.md +126 -0
  24. package/.claude/commands/TechieFlow/tasks/index-docs.md +173 -0
  25. package/.claude/commands/TechieFlow/tasks/kb-mode-interaction.md +75 -0
  26. package/.claude/commands/TechieFlow/tasks/log-miss.md +160 -0
  27. package/.claude/commands/TechieFlow/tasks/metrics-report.md +143 -0
  28. package/.claude/commands/TechieFlow/tasks/mockups.md +122 -0
  29. package/.claude/commands/TechieFlow/tasks/productguide.md +105 -0
  30. package/.claude/commands/TechieFlow/tasks/refresh-status.md +135 -0
  31. package/.claude/commands/TechieFlow/tasks/render-workflow-docs.md +117 -0
  32. package/.claude/commands/TechieFlow/tasks/shard-doc.md +185 -0
  33. package/.claude/commands/TechieFlow/tasks/split-brd.md +131 -0
  34. package/.claude/commands/TechieFlow/tasks/triage-issues.md +157 -0
  35. package/.claude/commands/TechieFlow/tasks/verify-phase.md +579 -0
  36. package/.claude/commands/generate-html.md +124 -0
  37. package/.codex/config.toml +46 -0
  38. package/.codex/hooks.json +63 -0
  39. package/.codex/rules/techieflow.rules +8 -0
  40. package/.opencode/command/generate-html.md +129 -0
  41. package/.opencode/plugin/techieflow.js +350 -0
  42. package/.tfcore/TOKEN-GUIDE.md +59 -0
  43. package/.tfcore/agents/analyst.md +97 -0
  44. package/.tfcore/agents/architect.md +84 -0
  45. package/.tfcore/agents/flow-master.md +217 -0
  46. package/.tfcore/agents/verifier.md +72 -0
  47. package/.tfcore/checklists/architect-checklist.md +438 -0
  48. package/.tfcore/core-config.yaml +47 -0
  49. package/.tfcore/data/brainstorming-techniques.md +36 -0
  50. package/.tfcore/data/elicitation-methods.md +154 -0
  51. package/.tfcore/data/techieflow-kb.md +807 -0
  52. package/.tfcore/data/technical-preferences.md +3 -0
  53. package/.tfcore/enhanced-ide-development-workflow.md +248 -0
  54. package/.tfcore/hooks/block-git.sh +301 -0
  55. package/.tfcore/hooks/codex-adapter.py +248 -0
  56. package/.tfcore/hooks/guard-artifacts.sh +101 -0
  57. package/.tfcore/hooks/guard-status-html.sh +102 -0
  58. package/.tfcore/hooks/guard-status.sh +124 -0
  59. package/.tfcore/hooks/guard-verify.sh +108 -0
  60. package/.tfcore/hooks/metrics-session.sh +129 -0
  61. package/.tfcore/hooks/session-pointer.sh +52 -0
  62. package/.tfcore/hooks/sweep-artifacts.sh +198 -0
  63. package/.tfcore/install-manifest.yaml +231 -0
  64. package/.tfcore/routing.yaml +105 -0
  65. package/.tfcore/tasks/_metrics-emit-gate.md +138 -0
  66. package/.tfcore/tasks/_smoke-test-policy.md +98 -0
  67. package/.tfcore/tasks/_status-update-gate.md +78 -0
  68. package/.tfcore/tasks/_yolo-mode.md +77 -0
  69. package/.tfcore/tasks/advanced-elicitation.md +117 -0
  70. package/.tfcore/tasks/amend-docs.md +149 -0
  71. package/.tfcore/tasks/author-brd.md +79 -0
  72. package/.tfcore/tasks/build-phase.md +231 -0
  73. package/.tfcore/tasks/create-deep-research-prompt.md +278 -0
  74. package/.tfcore/tasks/create-doc.md +101 -0
  75. package/.tfcore/tasks/day1-brownfield.md +507 -0
  76. package/.tfcore/tasks/day1-greenfield.md +224 -0
  77. package/.tfcore/tasks/devguide.md +224 -0
  78. package/.tfcore/tasks/document-project.md +343 -0
  79. package/.tfcore/tasks/execute-checklist.md +86 -0
  80. package/.tfcore/tasks/facilitate-brainstorming-session.md +136 -0
  81. package/.tfcore/tasks/fix-issues.md +134 -0
  82. package/.tfcore/tasks/generate-html.md +115 -0
  83. package/.tfcore/tasks/handoff-phase.md +126 -0
  84. package/.tfcore/tasks/index-docs.md +173 -0
  85. package/.tfcore/tasks/kb-mode-interaction.md +75 -0
  86. package/.tfcore/tasks/log-miss.md +160 -0
  87. package/.tfcore/tasks/metrics-report.md +143 -0
  88. package/.tfcore/tasks/mockups.md +122 -0
  89. package/.tfcore/tasks/productguide.md +105 -0
  90. package/.tfcore/tasks/refresh-status.md +135 -0
  91. package/.tfcore/tasks/render-workflow-docs.md +117 -0
  92. package/.tfcore/tasks/shard-doc.md +185 -0
  93. package/.tfcore/tasks/split-brd.md +131 -0
  94. package/.tfcore/tasks/triage-issues.md +157 -0
  95. package/.tfcore/tasks/verify-phase.md +579 -0
  96. package/.tfcore/telemetry/SCHEMA.md +678 -0
  97. package/.tfcore/telemetry/install-metrics.sh +390 -0
  98. package/.tfcore/telemetry/pre-commit +94 -0
  99. package/.tfcore/telemetry/tf-metrics.sh +1415 -0
  100. package/.tfcore/templates/architecture-tmpl.yaml +650 -0
  101. package/.tfcore/templates/brainstorming-output-tmpl.yaml +156 -0
  102. package/.tfcore/templates/brownfield-architecture-tmpl.yaml +476 -0
  103. package/.tfcore/templates/competitor-analysis-tmpl.yaml +306 -0
  104. package/.tfcore/templates/front-end-architecture-tmpl.yaml +218 -0
  105. package/.tfcore/templates/fullstack-architecture-tmpl.yaml +823 -0
  106. package/.tfcore/templates/market-research-tmpl.yaml +252 -0
  107. package/.tfcore/templates/project-brief-tmpl.yaml +221 -0
  108. package/.tfcore/templates/v4custom/app-agents-md-tmpl.md +61 -0
  109. package/.tfcore/templates/v4custom/app-architecture-tmpl.md +127 -0
  110. package/.tfcore/templates/v4custom/app-brd-tmpl.md +204 -0
  111. package/.tfcore/templates/v4custom/app-checklist-tmpl.md +90 -0
  112. package/.tfcore/templates/v4custom/app-claude-md-tmpl.md +33 -0
  113. package/.tfcore/templates/v4custom/app-devguide-tmpl.md +167 -0
  114. package/.tfcore/templates/v4custom/app-editorconfig-tmpl.editorconfig +44 -0
  115. package/.tfcore/templates/v4custom/app-library-feedback-tmpl.md +31 -0
  116. package/.tfcore/templates/v4custom/app-productguide-tmpl.md +54 -0
  117. package/.tfcore/templates/v4custom/app-project-status-tmpl.md +98 -0
  118. package/.tfcore/templates/v4custom/app-uidesign-tmpl.md +48 -0
  119. package/.tfcore/templates/v4custom/app-usageguide-tmpl.md +67 -0
  120. package/.tfcore/templates/v4custom/build-invocation-ladder.md +190 -0
  121. package/.tfcore/templates/v4custom/html-render-shell.md +502 -0
  122. package/.tfcore/templates/v4custom/metrics-report-template.md +273 -0
  123. package/.tfcore/templates/v4custom/opencode-operating-contract.md +56 -0
  124. package/.tfcore/user-guide.md +633 -0
  125. package/.tfcore/utils/techieflow-doc-template.md +325 -0
  126. package/.tfcore/utils/tf-assets.sh +310 -0
  127. package/.tfcore/utils/tf-codex-bind.py +196 -0
  128. package/.tfcore/utils/tf-codex-telemetry.py +60 -0
  129. package/.tfcore/utils/tf-emit.sh +1075 -0
  130. package/.tfcore/utils/tf-gitignore-audit.sh +281 -0
  131. package/.tfcore/utils/tf-goal.sh +421 -0
  132. package/.tfcore/utils/tf-harness.sh +160 -0
  133. package/.tfcore/utils/tf-mockup-parity.mjs +555 -0
  134. package/.tfcore/utils/tf-mockup-parity.sh +65 -0
  135. package/.tfcore/utils/tf-opencode-audit.py +126 -0
  136. package/.tfcore/utils/tf-perf.sh +241 -0
  137. package/.tfcore/utils/tf-render-html.py +715 -0
  138. package/.tfcore/utils/tf-render-html.sh +28 -0
  139. package/.tfcore/utils/tf-routing-bind.sh +216 -0
  140. package/.tfcore/utils/tf-routing.sh +247 -0
  141. package/.tfcore/utils/tf-yolo.sh +119 -0
  142. package/.tfcore/working-in-the-brownfield.md +606 -0
  143. package/LICENSE +201 -0
  144. package/README.md +1212 -0
  145. package/WORKFLOW.html +1986 -0
  146. package/docs/TechieFlow-Installation.md +299 -0
  147. package/opencode.jsonc +929 -0
  148. package/package.json +60 -0
  149. package/scripts/install.mjs +992 -0
  150. package/scripts/test-install.mjs +505 -0
  151. package/scripts/validate.mjs +155 -0
@@ -0,0 +1,273 @@
1
+ # {AppName} — Development Metrics
2
+
3
+ <!-- Written by .tfcore/tasks/metrics-report.md (`*metrics`). Regenerated on demand,
4
+ never hand-edited. Source: docs/metrics/*.jsonl (append-only) — schema at
5
+ .tfcore/telemetry/SCHEMA.md.
6
+
7
+ THE ONE RULE FOR THIS DOCUMENT: no combined first-pass rate, gate catch
8
+ distribution, escape rate, miss rate, or cost-per-miss across live/backfilled,
9
+ across project_type, across attribution confidence, or across cost attribution.
10
+ No "total" row, no "overall" line, no averaged intro sentence. If you are
11
+ tempted to add one, re-read metrics-report.md §2 — the reason is not
12
+ cosmetic. Commit-derived metrics are exempt from the first two separations. -->
13
+
14
+ **Snapshot as of {date}** · project_type `{app|library|docs|framework}` · schema v1
15
+
16
+ | Stream | Records | Span |
17
+ |---|---|---|
18
+ | `runs.jsonl` | {n} | {first date} → {last date} |
19
+ | `gates.jsonl` | {n} ({b} backfilled) | {first} → {last} |
20
+ | `sessions.jsonl` | {n} | {first} → {last} |
21
+ | `commits.jsonl` | {n} | {first} → {last} |
22
+ | `misses.jsonl` | {n} miss + {n} miss-fix | {first} → {last} |
23
+
24
+ ---
25
+
26
+ ## 1. First-pass rate
27
+
28
+ *What fraction of REQs reach `Verified` on attempt 1.*
29
+
30
+ | Provenance | project_type | REQs scored | First-pass | Rate |
31
+ |---|---|---|---|---|
32
+ | **Live** | app | {n} | {n} | {x%} |
33
+ | **Live** | library | {n} | {n} | {x%} |
34
+ | Backfilled† | app | {n} | {n} | {x%} |
35
+
36
+ <!-- One row per (provenance × project_type). NEVER a "total" or "all projects" row. -->
37
+
38
+ † **Backfilled rows are reconstructed, not recorded.** `attempt` was inferred on
39
+ every one of them — the Requirements Status table is a mutated-in-place snapshot,
40
+ so a REQ that failed three times then passed is indistinguishable from one that
41
+ passed first try. **This column cannot support a published first-pass rate.**
42
+ Fields inferred: {list from the records' `inferred[]`}.
43
+
44
+ **Excluded from the live rate:** {n} REQ(s) that carry backfilled history — their
45
+ live `attempt` numbering restarts at 1, so counting them would import the guess.
46
+ {REQ IDs}.
47
+
48
+ ---
49
+
50
+ ## 2. Gate catch distribution
51
+
52
+ *Of all failures, which gate caught them.*
53
+
54
+ ### Live · `{project_type}` — {n} failures
55
+
56
+ | Gate | Caught | Share |
57
+ |---|---|---|
58
+ | build | {n} | {x%} |
59
+ | acceptance | {n} | {x%} |
60
+ | render (§4a data-render) | {n} | {x%} |
61
+ | visual (§4b visual-truth) | {n} | {x%} |
62
+ | standards | {n} | {x%} |
63
+ | **escaped** — no gate caught it | {n} | {x%} |
64
+
65
+ <!-- A separate table per project_type, and a separate table for backfilled data.
66
+ Never one table with a "combined" column: a library project cannot fail the
67
+ visual gate, so pooling it understates that gate's real catch rate. -->
68
+
69
+ **Most common failure classes:** {failure_class} ×{n}, {failure_class} ×{n}.
70
+
71
+ ---
72
+
73
+ ## 3. Escape rate
74
+
75
+ *What fraction of defective REQs reached UAT/production instead of a gate.*
76
+
77
+ | Provenance | project_type | REQs with any failure | Escaped to UAT/prod | Rate |
78
+ |---|---|---|---|---|
79
+ | **Live** | {type} | {n} | {n} | {x%} |
80
+
81
+ Escapes are the `gate:"escaped"` records written by `*triage-issues` — a human
82
+ found the defect after every gate passed it. A REQ whose `prior_verdict` was
83
+ `Verified` when it escaped is the strongest signal on this page.
84
+
85
+ ---
86
+
87
+ ## 4. Throughput and rework — poolable
88
+
89
+ *These are comparable across `project_type` and across provenance, so they are
90
+ pooled deliberately.*
91
+
92
+ | Metric | Value |
93
+ |---|---|
94
+ | Runs total | {n} ({cmd}={n}, …) |
95
+ | Rework ratio (fix-mode ÷ build-phase runs) | {x%} |
96
+ | Batch size — median REQs per `build-phase` run | {n} |
97
+ | REQ throughput — median REQs/hour | {n} |
98
+ | Sessions / total tokens | {n} / {n} |
99
+ | Tokens per `Verified` REQ | {n} |
100
+ | Commit cadence | {n} commits/active day over {n} days |
101
+
102
+ **Cost in USD is not reported here.** Claude Code transcripts and Codex usage
103
+ payloads carry token counts but no per-message dollar cost, and this framework runs
104
+ on subscriptions where marginal per-token cost is not the real unit. Multiplying
105
+ tokens by a rate card would be an estimate presented as a measurement, so the row
106
+ says tokens and stops. OpenCode runs *do* carry real provider cost — where they
107
+ exist, §5b reports them and names the harness.
108
+
109
+ `commits.jsonl` lags reality by one commit — at `pre-commit` time HEAD is still the
110
+ previous commit, so the newest record ships in the next one. Unavoidable in either
111
+ direction: a record of commit N cannot predate N. The hook reconciles against the
112
+ log rather than appending a single line, so the lag never becomes a loss, and
113
+ commits made on another machine appear after a pull + commit. If this repo's clone
114
+ has no hook installed, `tf-metrics.sh --report` says so — note it in §6 rather than
115
+ treating a thin commit count as a finding (§6). The report also de-duplicates commits on
116
+ `sha`; if it says duplicates were collapsed, that is a normal union merge, not data
117
+ corruption, and needs no comment.
118
+
119
+ ---
120
+
121
+ ## 5. Misses — what was missed, who missed it, what the fix cost
122
+
123
+ <!-- SCHEMA.md §5.5. Delete this whole section if misses.jsonl is empty; do not
124
+ print a table of zeroes. Counts and the class distribution ARE poolable; the
125
+ attribution and cost figures below are NOT — each carries its own exclusion. -->
126
+
127
+ | Metric | Value |
128
+ |---|---|
129
+ | Misses logged | {n} ({o} open, {r} resolved, {w} wont-fix) |
130
+ | Design-miss share (`unspecified-gap`) | {x%} |
131
+ | Found by a human (`owner` / `production`) | {x%} |
132
+
133
+ *Reported **beside** the escape rate in §3, never merged with it: that figure is
134
+ computed from `gates.jsonl` `gate:"escaped"` records by a different definition, and
135
+ one word cannot mean two things on one page.*
136
+
137
+ *`wont-fix` is a decision, not a backlog item, so it is not counted as open. The
138
+ collapse check still treats it as a live defect, so a repeat failure on the same
139
+ REQ will not open a duplicate record — the two predicates differ deliberately.*
140
+
141
+ **Miss classes** — *what* was missed
142
+
143
+ | Class | n | Share |
144
+ |---|---|---|
145
+ | {miss_class} | {n} | {x%} |
146
+
147
+ **Why it was missed** — *which practice failed* ({a} of {m} misses assessed)
148
+
149
+ <!-- Optional field (SCHEMA §5.5.6): the denominator is records that CARRY it, never
150
+ all misses. A missing value means "not assessed", never a zero for a category.
151
+ And records written BEFORE the field existed (FIELD_SINCE, 2026-08-28 for
152
+ why_missed) leave the denominator entirely — they had no field to fill, which is
153
+ not the same as leaving one empty. State how many were excluded on that ground;
154
+ never backfill them with a value nobody assessed at the time. -->
155
+
156
+ | Practice | n | Share |
157
+ |---|---|---|
158
+ | {why_missed} | {n} | {x%} |
159
+
160
+ {k} miss(es) predate the field and are outside this denominator.
161
+ {u} escape(s) could have carried it and did not — complete those records with
162
+ `bash .tfcore/utils/tf-emit.sh --amend <miss_id> why_missed <value>` (SCHEMA §5.5.7);
163
+ never by editing `misses.jsonl`.
164
+
165
+ This is the table that says whether your **specification** or your **verification** is
166
+ the weak one — `missing-checklist-item` climbing means the spec has holes;
167
+ `insufficient-verify-method` climbing means the gates are too weak for the defects
168
+ that actually occur; `instruction-ignored` climbing means agents are skipping written
169
+ steps, which no gate change will fix.
170
+
171
+ ### 5a. Attribution — `linked` records only
172
+
173
+ **{a} of {m} misses are attributed; {e} are excluded** because they name a phase no
174
+ `runs.jsonl` record backs, so the model that produced them is unknown.
175
+
176
+ | By | Counts |
177
+ |---|---|
178
+ | Origin phase | {phase}={n}, … |
179
+ | Origin agent | {agent}={n}, … |
180
+ | Origin model | {model}={n}, … |
181
+
182
+ **These are observational, not causal.** Which model gets the hard work is not
183
+ random, so a model at the top of this list may be doing the hardest building rather
184
+ than the worst. Read it as a question to investigate, never as a ranking to route on.
185
+
186
+ ### 5b. Rework cost — measured and apportioned never combine
187
+
188
+ | | Fix records | Tokens out per miss |
189
+ |---|---|---|
190
+ | **Measured** (`sole` — the run fixed only this REQ) | {n} | {n} |
191
+ | Apportioned (`shared:n` — divided equally, **not a measurement**) | {n} | {n} |
192
+ | Unattributable (`none` — no usable token window) | {n} | — |
193
+
194
+ **Dollars.** {Either: "$X per miss — MEASURED, from {n} OpenCode records." Or:
195
+ "No measured dollars. Claude Code and Codex carry `cost_usd: null` permanently —
196
+ no cost source exists on either, and pricing tokens from a rate card here would be
197
+ an estimate presented as a measurement. Tokens are the honest figure."}
198
+
199
+ A miss fixed inline, inside a longer run with no distinct fix record, cannot be
200
+ costed at all. It counts toward the miss count and contributes nothing to the
201
+ money — which is why the "unattributable" row is printed rather than dropped.
202
+
203
+ ---
204
+
205
+ ## 6. Effort per phase — time, tokens, model, fan-out
206
+
207
+ <!-- Source: tf-metrics.sh --phases (or the `phases` block of --report --json).
208
+ SCHEMA.md §2 / §2.5 / §2.6. The unit is the RUN, aggregated by `cmd`.
209
+ This is NOT cycle-time-per-feature — that is a standing non-goal (§0) and no
210
+ stream can produce it honestly. Delete this section if runs.jsonl is empty. -->
211
+
212
+ Aggregated over **{n} live run records**. Token-window coverage:
213
+ `tree {n}` · `main {n}` · `conversation {n}` · `none/absent {n}`.
214
+
215
+ | Phase (`cmd`) | Runs | Wall clock (total / median) | Tokens out | % of all output | Tokens measured on |
216
+ |---|---|---|---|---|---|
217
+ | `{cmd}` | {n} | {total} / {median} | {n} | {n}% | {n} of {n} runs |
218
+
219
+ <!-- Runs whose token window could not be computed are EXCLUDED from the token
220
+ columns, never averaged in as zero. State the excluded count — an unmeasured
221
+ run counted as a free one is the same defect as SCHEMA §5.5.8's, one stream over. -->
222
+
223
+ ### 6a. Which model did the work
224
+
225
+ <!-- The per-model OUTPUT SPLIT, from `model_tokens_out` — not just the dominant
226
+ model's name. A run that spent 90% of its output on one model and 10% on
227
+ another is a different fact from an even split, and `model` alone cannot tell
228
+ them apart. -->
229
+
230
+ | Phase | Model | Output tokens | Share of the phase | Runs |
231
+ |---|---|---|---|---|
232
+ | `{cmd}` | `{model}` | {n} | {n}% | {n} |
233
+
234
+ **This ranking is observational, not causal** — the same warning §5a carries. Which
235
+ model gets the hard phases is not random, so a cost difference between models here
236
+ is at least as much a fact about *what they were asked to do* as about the models.
237
+
238
+ ### 6b. Subagent fan-out — measured, on its own denominator
239
+
240
+ | Phase | Runs observed | Spawns (total / median / max) | Runs that fanned out | Output tokens in subagents | Subagent share |
241
+ |---|---|---|---|---|---|
242
+ | `{cmd}` | {n} of {N} | {n} / {n} / {n} | {n} | {n} | {n}% |
243
+
244
+ **Read the `observed` column before anything else in this table.** Fan-out is only
245
+ visible on a `tokens_scope: "tree"` record — a `main`-scope window never read the
246
+ subagent transcripts at all, so **`0` on such a run means *not looked*, not *none
247
+ ran***. Those runs are outside every figure in this table, and the report states how
248
+ many were excluded and why (not `tree` scope · written before `subagent_runs` existed
249
+ on 2026-08-31 — two different reasons, never merged into one count).
250
+
251
+ **Declared vs measured.** `subagents` is a list of agent *kinds* the task typed into
252
+ its own emit; `subagent_runs` is counted from the harness's own store. Where they
253
+ disagree, **the measured one is right** — and the gap is itself a finding about how
254
+ accurately tasks self-report.
255
+
256
+ {Where a phase declared {n} subagents and {n} were measured, say so on its row.}
257
+
258
+ ---
259
+
260
+ ## 7. What is missing
261
+
262
+ <!-- Name every metric that had no data or too little. A missing number reported as
263
+ missing is worth more than a number nobody can defend. -->
264
+
265
+ - {metric} — `insufficient data (n={n})`; needs ≥3 supporting records.
266
+ - {stream} — empty; {why: framework refresh not run here / hook unavailable / no runs yet}.
267
+
268
+ ---
269
+
270
+ <!-- Privacy: this document may only contain IDs, counts, durations, verdicts and
271
+ file paths — exactly like the streams it summarises. Never requirement text,
272
+ never prompt text, never a commit subject, never a failure description in
273
+ prose. Assume it could become public. -->
@@ -0,0 +1,56 @@
1
+ # OpenCode Operating Contract
2
+
3
+ This file is loaded by OpenCode through `opencode.jsonc`. It is OpenCode-only; do not copy its rules into Claude permissions or settings.
4
+
5
+ ## Runtime First
6
+
7
+ At the beginning of every build, smoke, verify, devguide, or status-recovery task, classify the runtime before choosing a command:
8
+
9
+ - `TF_OPENCODE_DOCKER=1`, or `/usr/local/bin/winrun` plus `TF_WINDOWS_APP_PATH` → OpenCode Docker on Windows (**fallback deployment only** — since 2026-08-20 OpenCode normally runs in WSL, next line).
10
+ - `uname` containing `microsoft` / `WSL` → WSL on Windows (**the expected OpenCode runtime** — behave exactly as Claude Code does here: §B ladder, `~/bin/winrun`, `cmd.exe` interop all available).
11
+ - `Darwin` → native macOS.
12
+ - Other plain Linux → native Linux.
13
+
14
+ In OpenCode Docker:
15
+
16
+ 1. Never probe or invoke `cmd.exe`; it is expected to be absent.
17
+ 2. Never install or check for `maui-tizen` or any MAUI workload in the container.
18
+ 3. Run `winrun "dotnet --info"` before any Windows-head build or run. This is the bridge probe, not a suggestion.
19
+ 4. Use container `dotnet build` / `dotnet test` for standard .NET projects.
20
+ 5. Use `winrun "dotnet build ..."` / `winrun "dotnet test ..."` for a Windows MAUI Blazor Desktop project or a solution containing one.
21
+ 6. Before any package restore, run `test -s "$NUGET_CONFIG_FILE"` and `dotnet nuget list source --configfile "$NUGET_CONFIG_FILE"`. A missing file is a mount/launcher problem; a missing private URL is a config problem; an HTTP `401` is an authentication problem. If restore returns `401`, inspect that mounted Docker config and its source credentials; do not switch to a Windows `C:\...` source, add a PAT to the repository, or declare the application broken.
22
+ 7. For container restore, use `dotnet restore --configfile "$NUGET_CONFIG_FILE"` followed by the build with `--no-restore` when a private feed is involved. Do not let an implicit restore silently select a Windows source.
23
+
24
+ > The two sections below are harness-neutral doctrine; the canonical copies live in `.tfcore/tasks/_smoke-test-policy.md` (§"Smoke is NOT verify", §"Evidence discipline") and `build-phase.md §6`, which BOTH harnesses load through the tasks. They are repeated here because this file is injected into every OpenCode session.
25
+
26
+ ## Build-Phase Completion Contract
27
+
28
+ `*build-phase` is an execution workflow, not a build command. A green compiler is an intermediate checkpoint and must never be reported as phase completion.
29
+
30
+ After the correct build succeeds, continue in the same session without asking the owner to run the next step:
31
+
32
+ 1. Run the mandatory self-smoke from `.tfcore/tasks/build-phase.md §6`: boot the correct head, poll readiness, exercise every REQ cluster, verify data-render truth and visual truth, and clean up the process.
33
+ 2. If smoke fails, fix the affected REQs and repeat build plus smoke. Do not chain verification with known smoke failures.
34
+ 3. When smoke is clean, execute `.tfcore/tasks/verify-phase.md` inline with scope `all`. Do not merely summarize or recommend verification.
35
+ 4. Let the verifier write verdicts to the one Checklist Requirements Status table. Do not self-attest `Verified`.
36
+ 5. Finish the status gate: update `PROJECT-STATUS.md` and its HTML, set the real phase (`Build` or `Verify`), record the actual platform/invocation, and emit the required run telemetry.
37
+ 6. Only then report the phase result and the exact next command. If requirements remain open, the next command must come from the Build → Verify → Handoff ladder, not an invented “done” statement.
38
+
39
+ The following are incomplete outcomes, not successful completion:
40
+
41
+ - “Build is green; run smoke later.”
42
+ - “Bridge exists; user can verify it.”
43
+ - “Tests passed” when only focused unit tests ran and the full phase was not smoked/verified.
44
+ - “Full build blocked” because the agent used direct Linux `dotnet` for a Windows head before trying `winrun`.
45
+
46
+ ## Evidence Discipline
47
+
48
+ State which command actually ran. Distinguish:
49
+
50
+ - container build/test;
51
+ - Windows-host build/run through `winrun`;
52
+ - native Mac build/run;
53
+ - focused tests versus full solution build;
54
+ - self-smoke versus verifier execution.
55
+
56
+ Never convert a successful intermediate command into a full workflow pass.