@techierathore/techieflow 1.0.1 → 1.0.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.
Files changed (178) hide show
  1. package/.claude/commands/TechieFlow/agents/analyst.md +0 -5
  2. package/.claude/commands/TechieFlow/agents/architect.md +0 -6
  3. package/.claude/commands/TechieFlow/agents/flow-master.md +41 -215
  4. package/.claude/commands/TechieFlow/agents/verifier.md +23 -64
  5. package/.claude/commands/TechieFlow/tasks/_metrics-emit-gate.md +24 -117
  6. package/.claude/commands/TechieFlow/tasks/_smoke-test-policy.md +20 -84
  7. package/.claude/commands/TechieFlow/tasks/_status-update-gate.md +10 -74
  8. package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +20 -58
  9. package/.claude/commands/TechieFlow/tasks/amend-docs.md +20 -143
  10. package/.claude/commands/TechieFlow/tasks/build-phase.md +14 -224
  11. package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +31 -505
  12. package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +28 -213
  13. package/.claude/commands/TechieFlow/tasks/deploy-checklist.md +19 -0
  14. package/.claude/commands/TechieFlow/tasks/devguide.md +10 -219
  15. package/.claude/commands/TechieFlow/tasks/fix-issues.md +10 -129
  16. package/.claude/commands/TechieFlow/tasks/log-miss.md +19 -158
  17. package/.claude/commands/TechieFlow/tasks/metrics-report.md +1 -1
  18. package/.claude/commands/TechieFlow/tasks/mockups.md +12 -117
  19. package/.claude/commands/TechieFlow/tasks/refresh-status.md +9 -130
  20. package/.claude/commands/TechieFlow/tasks/split-brd.md +10 -126
  21. package/.claude/commands/TechieFlow/tasks/triage-and-fix.md +14 -0
  22. package/.claude/commands/TechieFlow/tasks/triage-issues.md +11 -152
  23. package/.claude/commands/TechieFlow/tasks/verify-phase.md +36 -572
  24. package/.opencode/plugin/techieflow.js +39 -12
  25. package/.tfcore/agents/analyst.md +0 -5
  26. package/.tfcore/agents/architect.md +0 -6
  27. package/.tfcore/agents/flow-master.md +41 -215
  28. package/.tfcore/agents/verifier.md +23 -64
  29. package/.tfcore/core-config.yaml +10 -0
  30. package/.tfcore/hooks/block-git.sh +4 -4
  31. package/.tfcore/hooks/guard-artifacts.sh +2 -2
  32. package/.tfcore/hooks/guard-build.sh +76 -0
  33. package/.tfcore/hooks/guard-db.sh +90 -0
  34. package/.tfcore/hooks/guard-metrics.sh +56 -0
  35. package/.tfcore/hooks/guard-status-html.sh +116 -71
  36. package/.tfcore/hooks/guard-status.sh +43 -16
  37. package/.tfcore/hooks/guard-verify.sh +70 -48
  38. package/.tfcore/hooks/sweep-artifacts.sh +2 -2
  39. package/.tfcore/install-manifest.yaml +0 -18
  40. package/.tfcore/routing.yaml +25 -14
  41. package/.tfcore/standards/coding-standards-core.md +61 -0
  42. package/.tfcore/standards/coding-standards-dotnet.md +93 -0
  43. package/.tfcore/tasks/_metrics-emit-gate.md +24 -117
  44. package/.tfcore/tasks/_smoke-test-policy.md +20 -84
  45. package/.tfcore/tasks/_status-update-gate.md +10 -74
  46. package/.tfcore/tasks/_yolo-mode.md +20 -58
  47. package/.tfcore/tasks/amend-docs.md +20 -143
  48. package/.tfcore/tasks/build-phase.md +14 -224
  49. package/.tfcore/tasks/day1-brownfield.md +31 -505
  50. package/.tfcore/tasks/day1-greenfield.md +28 -213
  51. package/.tfcore/tasks/deploy-checklist.md +19 -0
  52. package/.tfcore/tasks/devguide.md +10 -219
  53. package/.tfcore/tasks/fix-issues.md +10 -129
  54. package/.tfcore/tasks/log-miss.md +19 -158
  55. package/.tfcore/tasks/metrics-report.md +1 -1
  56. package/.tfcore/tasks/mockups.md +12 -117
  57. package/.tfcore/tasks/refresh-status.md +9 -130
  58. package/.tfcore/tasks/split-brd.md +10 -126
  59. package/.tfcore/tasks/triage-and-fix.md +14 -0
  60. package/.tfcore/tasks/triage-issues.md +11 -152
  61. package/.tfcore/tasks/verify-phase.md +36 -572
  62. package/.tfcore/telemetry/SCHEMA.md +43 -7
  63. package/.tfcore/telemetry/tf-metrics.sh +152 -17
  64. package/.tfcore/templates/project-brief-tmpl.yaml +1 -1
  65. package/.tfcore/templates/stack-defaults/dotnet.md +35 -0
  66. package/.tfcore/templates/stack-questions.md +77 -0
  67. package/.tfcore/templates/v4custom/app-agents-md-tmpl.md +3 -4
  68. package/.tfcore/templates/v4custom/app-architecture-tmpl.md +107 -115
  69. package/.tfcore/templates/v4custom/app-brd-tmpl.md +108 -184
  70. package/.tfcore/templates/v4custom/app-checklist-tmpl.md +48 -73
  71. package/.tfcore/templates/v4custom/app-claude-md-tmpl.md +1 -1
  72. package/.tfcore/templates/v4custom/app-coding-standards-tmpl.md +52 -0
  73. package/.tfcore/templates/v4custom/app-deployment-checklist-tmpl.md +86 -0
  74. package/.tfcore/templates/v4custom/app-devguide-tmpl.md +69 -146
  75. package/.tfcore/templates/v4custom/app-phases-tmpl.md +35 -0
  76. package/.tfcore/templates/v4custom/app-productguide-tmpl.md +38 -35
  77. package/.tfcore/templates/v4custom/app-project-status-tmpl.md +63 -73
  78. package/.tfcore/templates/v4custom/app-uidesign-tmpl.md +62 -37
  79. package/.tfcore/templates/v4custom/app-usageguide-tmpl.md +69 -54
  80. package/.tfcore/templates/v4custom/build-invocation-ladder.md +17 -180
  81. package/.tfcore/templates/v4custom/build-subagent-prompt.md +17 -0
  82. package/.tfcore/templates/v4custom/metrics-report-template.md +2 -2
  83. package/.tfcore/user-guide.md +0 -23
  84. package/.tfcore/utils/__pycache__/tf-brd-status.cpython-312.pyc +0 -0
  85. package/.tfcore/utils/__pycache__/tf-checklist-edit.cpython-312.pyc +0 -0
  86. package/.tfcore/utils/__pycache__/tf-codex-bind.cpython-312.pyc +0 -0
  87. package/.tfcore/utils/__pycache__/tf-codex-telemetry.cpython-312.pyc +0 -0
  88. package/.tfcore/utils/__pycache__/tf-day1-files.cpython-312.pyc +0 -0
  89. package/.tfcore/utils/__pycache__/tf-devguide-list.cpython-312.pyc +0 -0
  90. package/.tfcore/utils/__pycache__/tf-doc-check.cpython-312.pyc +0 -0
  91. package/.tfcore/utils/__pycache__/tf-log-miss.cpython-312.pyc +0 -0
  92. package/.tfcore/utils/__pycache__/tf-misses-md.cpython-312.pyc +0 -0
  93. package/.tfcore/utils/__pycache__/tf-mockups-locate.cpython-312.pyc +0 -0
  94. package/.tfcore/utils/__pycache__/tf-opencode-audit.cpython-312.pyc +0 -0
  95. package/.tfcore/utils/__pycache__/tf-perf-grade.cpython-312.pyc +0 -0
  96. package/.tfcore/utils/__pycache__/tf-render-html.cpython-312.pyc +0 -0
  97. package/.tfcore/utils/__pycache__/tf-split-brd.cpython-312.pyc +0 -0
  98. package/.tfcore/utils/__pycache__/tf-status-facts.cpython-312.pyc +0 -0
  99. package/.tfcore/utils/__pycache__/tf-triage.cpython-312.pyc +0 -0
  100. package/.tfcore/utils/__pycache__/tf-verify-list.cpython-312.pyc +0 -0
  101. package/.tfcore/utils/__pycache__/tf-verify-verdict.cpython-312.pyc +0 -0
  102. package/.tfcore/utils/tf-brd-status.py +176 -0
  103. package/.tfcore/utils/tf-brd-status.sh +19 -0
  104. package/.tfcore/utils/tf-build-list.py +191 -0
  105. package/.tfcore/utils/tf-build-list.sh +20 -0
  106. package/.tfcore/utils/tf-build.sh +143 -0
  107. package/.tfcore/utils/tf-cdp-relay.ps1 +64 -0
  108. package/.tfcore/utils/tf-checklist-edit.py +133 -0
  109. package/.tfcore/utils/tf-day1-files.py +208 -0
  110. package/.tfcore/utils/tf-day1-files.sh +20 -0
  111. package/.tfcore/utils/tf-devguide-list.py +249 -0
  112. package/.tfcore/utils/tf-devguide-list.sh +18 -0
  113. package/.tfcore/utils/tf-doc-check.py +1267 -0
  114. package/.tfcore/utils/tf-doc-check.sh +29 -0
  115. package/.tfcore/utils/tf-emit.sh +203 -13
  116. package/.tfcore/utils/tf-fix-close.sh +83 -0
  117. package/.tfcore/utils/tf-goal.sh +193 -62
  118. package/.tfcore/utils/tf-harness.sh +4 -9
  119. package/.tfcore/utils/tf-log-miss.py +197 -0
  120. package/.tfcore/utils/tf-log-miss.sh +14 -0
  121. package/.tfcore/utils/tf-misses-md.py +211 -0
  122. package/.tfcore/utils/tf-misses-md.sh +13 -0
  123. package/.tfcore/utils/tf-mockups-locate.py +66 -0
  124. package/.tfcore/utils/tf-mockups-locate.sh +18 -0
  125. package/.tfcore/utils/tf-opencode-audit.py +23 -7
  126. package/.tfcore/utils/tf-perf-grade.py +97 -0
  127. package/.tfcore/utils/tf-perf-grade.sh +12 -0
  128. package/.tfcore/utils/tf-phase.sh +74 -0
  129. package/.tfcore/utils/tf-routing-bind.sh +10 -5
  130. package/.tfcore/utils/tf-routing.sh +6 -7
  131. package/.tfcore/utils/tf-split-brd.py +304 -0
  132. package/.tfcore/utils/tf-split-brd.sh +22 -0
  133. package/.tfcore/utils/tf-status-evidence.sh +68 -0
  134. package/.tfcore/utils/tf-status-facts.py +309 -0
  135. package/.tfcore/utils/tf-status-facts.sh +20 -0
  136. package/.tfcore/utils/tf-triage.py +243 -0
  137. package/.tfcore/utils/tf-triage.sh +16 -0
  138. package/.tfcore/utils/tf-verify-boot.sh +250 -0
  139. package/.tfcore/utils/tf-verify-emit.sh +110 -0
  140. package/.tfcore/utils/tf-verify-env.sh +88 -0
  141. package/.tfcore/utils/tf-verify-list.py +270 -0
  142. package/.tfcore/utils/tf-verify-list.sh +13 -0
  143. package/.tfcore/utils/tf-verify-screens.mjs +283 -0
  144. package/.tfcore/utils/tf-verify-screens.sh +22 -0
  145. package/.tfcore/utils/tf-verify-tests.sh +123 -0
  146. package/.tfcore/utils/tf-verify-verdict.py +283 -0
  147. package/.tfcore/utils/tf-verify-verdict.sh +15 -0
  148. package/.tfcore/utils/tf-yolo.sh +59 -0
  149. package/README.md +114 -1149
  150. package/docs/TechieFlow-Installation.md +27 -7
  151. package/opencode.jsonc +13 -33
  152. package/package.json +4 -7
  153. package/scripts/install.mjs +73 -46
  154. package/scripts/npm-cleanup.mjs +137 -0
  155. package/scripts/npm-postinstall.mjs +49 -0
  156. package/.claude/commands/TechieFlow/tasks/advanced-elicitation.md +0 -117
  157. package/.claude/commands/TechieFlow/tasks/author-brd.md +0 -79
  158. package/.claude/commands/TechieFlow/tasks/document-project.md +0 -343
  159. package/.claude/commands/TechieFlow/tasks/execute-checklist.md +0 -86
  160. package/.claude/commands/TechieFlow/tasks/index-docs.md +0 -173
  161. package/.claude/commands/TechieFlow/tasks/kb-mode-interaction.md +0 -75
  162. package/.claude/commands/TechieFlow/tasks/shard-doc.md +0 -185
  163. package/.codex/config.toml +0 -46
  164. package/.codex/hooks.json +0 -63
  165. package/.codex/rules/techieflow.rules +0 -8
  166. package/.tfcore/hooks/codex-adapter.py +0 -248
  167. package/.tfcore/tasks/advanced-elicitation.md +0 -117
  168. package/.tfcore/tasks/author-brd.md +0 -79
  169. package/.tfcore/tasks/document-project.md +0 -343
  170. package/.tfcore/tasks/execute-checklist.md +0 -86
  171. package/.tfcore/tasks/index-docs.md +0 -173
  172. package/.tfcore/tasks/kb-mode-interaction.md +0 -75
  173. package/.tfcore/tasks/shard-doc.md +0 -185
  174. package/.tfcore/utils/tf-codex-bind.py +0 -196
  175. package/.tfcore/utils/tf-codex-telemetry.py +0 -60
  176. package/WORKFLOW.html +0 -1986
  177. package/scripts/test-install.mjs +0 -505
  178. package/scripts/validate.mjs +0 -163
@@ -1,27 +1,22 @@
1
1
  #!/usr/bin/env bash
2
- # TechieFlow PreToolUse hook — blocks self-attested `Verified` verdicts.
2
+ # TechieFlow PreToolUse hook — a `Verified` cell is written only by an executed verify run.
3
3
  #
4
- # `Verified` is the verifier's verdict, written ONLY by an EXECUTED verify-phase
5
- # run (chained inline by build-phase §6b, or a standalone `*verify`). On
6
- # 2026-07-09 a build orchestrator did its own smoke and wrote `Verified`
7
- # verdicts itself — the prose rule ("chain the verifier") was skipped silently.
8
- # This hook makes the gate MECHANICAL, the same way block-git.sh made the git
9
- # ban mechanical and guard-status.sh made the status shape mechanical.
4
+ # `Verified` is the verifier's verdict. Since Sitting 4c (2026-09-06) the verify run's own script,
5
+ # tf-verify-verdict.sh, writes the cells from the evidence it collected and writes the ledger
6
+ # docs/.last-verify.json with every row's verdict. This hook refuses any Write/Edit/MultiEdit of a
7
+ # *-Checklist.md that INTRODUCES a `Verified` cell unless a ledger dated today lists that row as
8
+ # PASS. Owner decision 2026-09-06: a hand-written Verified the ledger does not list is refused.
9
+ # Two older ledger shapes still unlock: {"mode":"reconcile"} written by *refresh-status for a row
10
+ # whose Remarks already carry dated evidence, and a same-day ledger without a `rows` map from a
11
+ # framework version before this sitting (the row is then checked by date only, as before).
10
12
  #
11
- # How it works: verify-phase §6 writes a run ledger `docs/.last-verify.json`
12
- # ({"date","app","scope","booted","gates","evidence"}) immediately before it
13
- # records verdicts — after actually booting the app and running the gates.
14
- # Any Write/Edit/MultiEdit to a `*-Checklist.md` that INTRODUCES a `Verified`
15
- # status cell is blocked unless a same-day ledger sits next to the checklist.
16
- #
17
- # Wired in .claude/settings.json → hooks.PreToolUse (matcher "Write|Edit|MultiEdit").
18
- # Exit 2 + stderr = block the call and feed the message back to the agent.
13
+ # Wired in .claude/settings.json → hooks.PreToolUse (matcher "Write|Edit|MultiEdit") and in the
14
+ # OpenCode plugin. Exit 2 + stderr = block the call and feed the message back to the agent.
19
15
  # Fails OPEN (exit 0) if python3 or parseable JSON is unavailable.
20
16
 
21
17
  INPUT="$(cat)"
22
18
  command -v python3 >/dev/null 2>&1 || exit 0
23
19
 
24
- # stdin feeds python the SCRIPT (heredoc), so the payload travels via env var.
25
20
  TF_HOOK_INPUT="$INPUT" python3 - <<'PY'
26
21
  import datetime, json, os, re, sys
27
22
 
@@ -35,10 +30,19 @@ path = (ti.get("file_path") or "").replace("\\", "/")
35
30
  if not path.rsplit("/", 1)[-1].lower().endswith("-checklist.md"):
36
31
  sys.exit(0)
37
32
 
38
- # A `Verified` STATUS CELL: a table cell holding exactly Verified (optional
39
- # bold / trailing date qualifier). Remarks prose like "VERIFIED 2026-07-07"
40
- # or "Needs re-verify" does not match.
41
33
  CELL = re.compile(r"\|\s*\**Verified\**\s*(?:\([^)|]*\))?\s*\|")
34
+ ROW = re.compile(r"^\s*\|\s*`?(REQ-[A-Z]+-\d+)`?\s*\|", re.I)
35
+
36
+
37
+ def verified_ids(text):
38
+ """the row ids whose STATUS cell reads Verified, in a piece of checklist text"""
39
+ out = set()
40
+ for line in text.splitlines():
41
+ m = ROW.match(line)
42
+ if m and CELL.search(line):
43
+ out.add(m.group(1).upper())
44
+ return out
45
+
42
46
 
43
47
  new_pieces, old_pieces = [], []
44
48
  if isinstance(ti.get("content"), str):
@@ -56,51 +60,69 @@ for e in ti.get("edits") or []:
56
60
 
57
61
  n_new = sum(len(CELL.findall(p)) for p in new_pieces)
58
62
  n_old = sum(len(CELL.findall(p)) for p in old_pieces)
63
+ if isinstance(ti.get("content"), str):
64
+ # a whole-file write: what is Verified on disk already does not count as new
65
+ try:
66
+ with open(path, encoding="utf-8", errors="replace") as f:
67
+ n_old = len(CELL.findall(f.read()))
68
+ except FileNotFoundError:
69
+ n_old = 0
59
70
  if n_new <= n_old:
60
- sys.exit(0) # no NEW Verified cell introduced (demotions, moves, other edits)
71
+ sys.exit(0) # no NEW Verified cell (a demotion, a move, another edit)
72
+
73
+ new_ids = set().union(*(verified_ids(p) for p in new_pieces)) if new_pieces else set()
74
+ old_ids = set().union(*(verified_ids(p) for p in old_pieces)) if old_pieces else set()
75
+ if isinstance(ti.get("content"), str):
76
+ try:
77
+ with open(path, encoding="utf-8", errors="replace") as f:
78
+ old_ids = verified_ids(f.read())
79
+ except FileNotFoundError:
80
+ old_ids = set()
81
+ introduced = new_ids - old_ids
61
82
 
62
- # Introducing `Verified` — require a same-day run ledger next to the checklist.
63
- ledger_path = os.path.join(os.path.dirname(path), ".last-verify.json")
83
+ ledger_path = os.path.join(os.path.dirname(path) or ".", ".last-verify.json")
84
+ today = datetime.date.today().isoformat()
64
85
  try:
65
86
  with open(ledger_path, "r", encoding="utf-8") as f:
66
87
  ledger = json.load(f)
67
- if str(ledger.get("date", "")).strip() == datetime.date.today().isoformat():
68
- sys.exit(0) # fresh ledger — an executed verify-phase (or documented reconcile) unlocked it
69
- stale = f"exists but is dated {ledger.get('date')!r}, not today"
70
88
  except FileNotFoundError:
71
- stale = "does not exist"
89
+ ledger, problem = None, "does not exist"
72
90
  except Exception:
73
- stale = "exists but is not valid JSON"
91
+ ledger, problem = None, "exists but is not valid JSON"
92
+
93
+ if ledger is not None:
94
+ if str(ledger.get("date", "")).strip() != today:
95
+ problem = f"exists but is dated {ledger.get('date')!r}, not today"
96
+ elif ledger.get("mode") == "reconcile":
97
+ sys.exit(0) # *refresh-status reconciling a row to dated evidence already in its Remarks
98
+ elif "rows" not in ledger:
99
+ sys.exit(0) # a same-day ledger from a framework version before Sitting 4c: date unlocks
100
+ else:
101
+ rows = ledger.get("rows") or {}
102
+ not_listed = sorted(i for i in introduced if rows.get(i) != "PASS")
103
+ if not introduced:
104
+ # a Verified cell without a readable row id (a malformed line): refuse, nothing can vouch for it
105
+ not_listed = ["(row id not readable)"]
106
+ if not not_listed:
107
+ sys.exit(0)
108
+ problem = ("lists these rows as " + ", ".join(f"{i}: {rows.get(i, 'absent')}" for i in not_listed)
109
+ + ", not PASS")
74
110
 
75
111
  print(
76
112
  "BLOCKED by TechieFlow policy: this write INTRODUCES a `Verified` status, "
77
- f"but the verify run ledger {ledger_path} {stale}.",
78
- file=sys.stderr,
79
- )
80
- print(
81
- " - `Verified` is the VERIFIER'S verdict. It is written only downstream of an "
82
- "EXECUTED .tfcore/tasks/verify-phase.md run — boot the app, run the scoped "
83
- "tests, apply the §4a data-render + §4b visual-truth gates, write the run "
84
- "ledger (verify-phase §6), THEN record verdicts.",
85
- file=sys.stderr,
86
- )
87
- print(
88
- " - If you are the build orchestrator after your self-smoke: your ceiling is "
89
- "`Implemented` (build-phase §6a / _smoke-test-policy). Chain the verifier by "
90
- "EXECUTING verify-phase inline (build-phase §6b) — summarizing your smoke as "
91
- "a verdict is self-attestation, the exact failure this hook exists to stop.",
113
+ f"but the verify ledger {ledger_path} {problem}.",
92
114
  file=sys.stderr,
93
115
  )
94
116
  print(
95
- " - If you are *refresh-status* reconciling a status column to PRE-EXISTING "
96
- "dated VERIFIED evidence already in that row's Remarks: write the ledger with "
97
- '{"date":"<today>","mode":"reconcile","evidence":"<the pre-existing remark '
98
- 'date>"} first (refresh-status §4).',
117
+ " - `Verified` is written by the verify run's own script from the evidence it collected: "
118
+ "bash .tfcore/utils/tf-verify-verdict.sh <App> --apply, after boot, tests, screens, assets, "
119
+ "parity and perf have run (.tfcore/tasks/verify-phase.md). Writing it by hand is refused.",
99
120
  file=sys.stderr,
100
121
  )
101
122
  print(
102
- " - Writing the ledger WITHOUT having run verify-phase's steps is falsifying "
103
- "the audit record.",
123
+ " - A build, a fix or a smoke reaches at most `Implemented`; chain the verifier by executing "
124
+ "verify-phase.md. *refresh-status may reconcile a row that already carries dated verify evidence "
125
+ 'by writing the ledger {"date":"<today>","mode":"reconcile","evidence":"<that date>"} first.',
104
126
  file=sys.stderr,
105
127
  )
106
128
  sys.exit(2)
@@ -2,7 +2,7 @@
2
2
  # TechieFlow hook — automatic sweep of expired run material (added 2026-08-26).
3
3
  #
4
4
  # Wired as a SessionStart hook in .claude/settings.json (Claude Code), as
5
- # `codex-adapter.py session-start` (Codex) and on the first root
5
+ # on the first root
6
6
  # `session.created` in .opencode/plugin/techieflow.js (OpenCode).
7
7
  #
8
8
  # WHY: verify-phase.md §1 pins every run artifact under tests/.artifacts/ and
@@ -60,7 +60,7 @@ root = os.path.realpath(root)
60
60
  DRY = os.environ.get("TF_SWEEP_DRY_RUN") == "1"
61
61
 
62
62
  # Throttle: at most one sweep per hour per project, whichever harness fires it
63
- # (Codex re-fires session-start on every prompt; a walk of a big tree on every
63
+ # (a harness may re-fire session-start on every prompt; a walk of a big tree on every
64
64
  # turn is waste). TF_SWEEP_FORCE=1 bypasses. Dry runs never touch the stamp.
65
65
  stamp = os.path.join(root, ".tfcore", ".session", "sweep.stamp")
66
66
  if not DRY and os.environ.get("TF_SWEEP_FORCE") != "1":
@@ -91,9 +91,6 @@ files:
91
91
  - path: .tfcore\tasks\test-design.md
92
92
  hash: bcd13a95d296ce22
93
93
  modified: false
94
- - path: .tfcore\tasks\shard-doc.md
95
- hash: a83c900f64ea3d4f
96
- modified: false
97
94
  - path: .tfcore\tasks\risk-profile.md
98
95
  hash: addf5d143cfe6f12
99
96
  modified: false
@@ -106,24 +103,12 @@ files:
106
103
  - path: .tfcore\tasks\nfr-assess.md
107
104
  hash: b9011d038b81a69b
108
105
  modified: false
109
- - path: .tfcore\tasks\kb-mode-interaction.md
110
- hash: 4d6b921c24ba4999
111
- modified: false
112
- - path: .tfcore\tasks\index-docs.md
113
- hash: 70b1d526b19d015e
114
- modified: false
115
106
  - path: .tfcore\tasks\generate-ai-frontend-prompt.md
116
107
  hash: ca4cabd824ea1b60
117
108
  modified: false
118
109
  - path: .tfcore\tasks\facilitate-brainstorming-session.md
119
110
  hash: 38594d876614e077
120
111
  modified: false
121
- - path: .tfcore\tasks\execute-checklist.md
122
- hash: 8a704b6f2bc52e12
123
- modified: false
124
- - path: .tfcore\tasks\document-project.md
125
- hash: 98f8790d20e83cf3
126
- modified: false
127
112
  - path: .tfcore\tasks\create-next-story.md
128
113
  hash: 99e5cc3237a9cffd
129
114
  modified: false
@@ -148,9 +133,6 @@ files:
148
133
  - path: .tfcore\tasks\apply-qa-fixes.md
149
134
  hash: 70e6143a80f7296b
150
135
  modified: false
151
- - path: .tfcore\tasks\advanced-elicitation.md
152
- hash: d39118bf32237a21
153
- modified: false
154
136
  - path: .tfcore\data\test-priorities-matrix.md
155
137
  hash: 1dd5698a46ab054e
156
138
  modified: false
@@ -7,7 +7,7 @@
7
7
  # A phase declares a TIER, never a model. The tiers map resolves a tier to a
8
8
  # per-harness model id (Claude Code aliases: opus|sonnet|haiku|inherit|<id>,
9
9
  # pinnable via ANTHROPIC_DEFAULT_*_MODEL; OpenCode ids: provider/model, list
10
- # with `opencode models`; Codex model slugs: list with `codex debug models`).
10
+ # with `opencode models`).
11
11
  # Routing is declared at the harness boundary and
12
12
  # OBSERVED by telemetry (runs.jsonl model/tier fields) — it is never enforced
13
13
  # mid-turn, because neither harness can switch a running turn's model.
@@ -23,26 +23,36 @@
23
23
  # §5.3/§5.4 and the rollout order in §6. Flipping the flag alone changes
24
24
  # nothing; that is deliberate.
25
25
 
26
- enabled: false
27
-
26
+ # Owner decisions: 2026-09-05, Sonnet for every long-running Claude phase, Haiku for the cheap ones;
27
+ # 2026-09-06, the OpenAI models for OpenCode (gpt-5.6-terra for frontier and standard, gpt-5.6-luna
28
+ # for economy) after the OpenCode Go monthly limit was reached with MiMo.
29
+ #
30
+ # HOW TO CHANGE A MODEL (the plain version; the full guide is docs/TechieFlow-Routing-Guide.md):
31
+ # 1. This file is the FRAMEWORK DEFAULT. A project gets a copy at .tfcore/routing.yaml when it is
32
+ # scaffolded, and update-framework.sh never overwrites that copy. So to change one project,
33
+ # edit the project's copy; to change every future project, edit this one.
34
+ # 2. Edit the model id under `tiers:` for the harness you use (claude: opus|sonnet|haiku or a
35
+ # full id; opencode: provider/model as printed by `opencode models`).
36
+ # 3. In the project folder run: bash .tfcore/utils/tf-routing-bind.sh
37
+ # That regenerates the harness bindings (.claude/agents/*.md, .claude/commands/tf/*.md,
38
+ # .opencode/opencode.json). Nothing changes until it runs.
39
+ # 4. For one unattended run only, pass --model <id> to tf-goal.sh instead; the main agent uses
40
+ # it, the sub-agents still use the bindings from step 3.
41
+ enabled: true
28
42
  # ---------------------------------------------------------------------------
29
43
  # Tier → model id, per harness. STARTING VALUES — the owner tunes these.
30
- # OpenCode ids below are from this machine's `opencode models` (opencode-go /
31
- # Zen gateway); swap for anthropic/* ids if an Anthropic key is configured.
44
+ # OpenCode ids are provider/model as printed by `opencode models` on this machine.
32
45
  # ---------------------------------------------------------------------------
33
46
  tiers:
34
47
  frontier:
35
- claude: opus
36
- opencode: opencode-go/kimi-k3
37
- codex: gpt-5.6
48
+ claude: sonnet
49
+ opencode: openai/gpt-5.6-terra
38
50
  standard:
39
51
  claude: sonnet
40
- opencode: opencode-go/kimi-k2.7-code
41
- codex: gpt-5.6-terra
52
+ opencode: openai/gpt-5.6-terra
42
53
  economy:
43
54
  claude: haiku
44
- opencode: opencode-go/deepseek-v4-flash
45
- codex: gpt-5.6-luna
55
+ opencode: openai/gpt-5.6-luna
46
56
 
47
57
  # ---------------------------------------------------------------------------
48
58
  # Phase → tier. One line each; values: frontier | standard | economy | inherit.
@@ -52,13 +62,14 @@ tiers:
52
62
  phases:
53
63
  day1-greenfield: frontier
54
64
  day1-brownfield: frontier
55
- author-brd: frontier
56
65
  amend-docs: frontier
57
66
  mockups: standard
58
67
  split-brd: standard
59
68
  build-phase: standard
60
69
  fix-issues: frontier
70
+ triage-and-fix: frontier
61
71
  triage-issues: standard
72
+ log-miss: economy
62
73
  verify-phase: standard
63
74
  devguide: standard
64
75
  productguide: economy
@@ -79,7 +90,7 @@ subagents:
79
90
  tf-explorer: economy
80
91
 
81
92
  # ---------------------------------------------------------------------------
82
- # Tier → reasoning effort (used by Claude Code and Codex; ignored by OpenCode).
93
+ # Tier → reasoning effort (used by Claude Code; ignored by OpenCode).
83
94
  # ---------------------------------------------------------------------------
84
95
  effort:
85
96
  frontier: high
@@ -0,0 +1,61 @@
1
+ # TechieFlow — Coding Standards, core
2
+
3
+ <!-- How this file is used and edited.
4
+ Applies to EVERY project, whatever the stack. It is loaded by the build and by the verifier's
5
+ standards check together with the stack file named in the project's Coding Standards document
6
+ (docs/<App>-Coding-Standards.md → "Standards applied"). Rules here are technology-neutral;
7
+ anything that names a language, framework or package belongs in a stack file
8
+ (.tfcore/standards/coding-standards-<stack>.md).
9
+ To change a rule: edit this file in the TechieFlow repository, then run update-framework.sh on
10
+ each project. Projects never edit their .tfcore/ copy. A rule an agent has ignored twice becomes
11
+ a script or a hook, or is deleted; it never gets a second paragraph. -->
12
+
13
+ ## 1. Names
14
+
15
+ - One naming style per kind of thing, declared in the stack file, used everywhere. Never mix styles in one project.
16
+ - Names say what a thing is or does. No abbreviations a newcomer would have to ask about.
17
+ - Files are named after the one type they hold.
18
+
19
+ ## 2. Layout
20
+
21
+ - Source under `src/`, tests under `tests/`. No other folders at the repository root unless the stack file allows one.
22
+ - Log files go under the build output folder, never at the repository root.
23
+ - The primary executable project carries the product name. A project named `<App>.App` is not allowed.
24
+
25
+ ## 3. Dependencies and configuration
26
+
27
+ - No package is added without a row in the Architecture Decisions log saying why.
28
+ - One configuration mechanism per project. A second one is a defect.
29
+ - A missing feature in an internal library (TrBlazeUI, TechieRag, TechieFlow) is recorded in that library's feedback file and the feature is held. No workaround is written.
30
+
31
+ ## 4. Code shape
32
+
33
+ - One type per file. Small methods. Early returns for validation. At most three levels of nesting.
34
+ - Every public member has a documentation comment in the language's own form.
35
+ - No commented-out code. Comments say why, not what.
36
+
37
+ ## 5. Tests
38
+
39
+ - A test project exists from day one.
40
+ - Test names are short; the scenario lives in the test's documentation comment.
41
+ - Arrange, act, assert. One behaviour per test.
42
+
43
+ ## 6. Security
44
+
45
+ - No credentials in code or in committed configuration. Secrets come from the mechanism in Stack Q2.
46
+ - Database access uses parameters, never string-built queries.
47
+ - Every input from outside the process is validated at the boundary. Security events are logged.
48
+
49
+ ## 7. Logging
50
+
51
+ - Every executable head writes a rolling log file, wired at startup before anything else can fail, and logs unhandled exceptions at its boundary.
52
+ - Libraries log through the logging abstraction only; they never reference a logging implementation.
53
+
54
+ ## 8. Testability
55
+
56
+ - Every interactive or data-bound control the verifier must reach carries a stable test id, named by intent (`LoginSubmit`, `EntriesGrid`), never by position.
57
+
58
+ ## 9. Enforcement
59
+
60
+ - The machine-checkable subset lives in the repository's editor configuration and analyzer settings, as the stack file specifies.
61
+ - The verifier's standards check runs the greps listed in the stack file's Enforcement section and records findings in the checklist Remarks and PROJECT-STATUS.
@@ -0,0 +1,93 @@
1
+ # TechieFlow — Coding Standards, .NET
2
+
3
+ <!-- How this file is used and edited.
4
+ The .NET answer set's coding standards. Loaded with coding-standards-core.md when a project's
5
+ Coding Standards document names it. Owners in another stack write their own
6
+ coding-standards-<stack>.md with the same section names.
7
+ Seeded from the framework author's projects (the two sample files in the TechieFlow docs folder).
8
+ To change a rule: edit this file in the TechieFlow repository, then run update-framework.sh on
9
+ each project. Per-project choices this file leaves open are recorded in
10
+ docs/<App>-Coding-Standards.md → "Standards applied"; project-only rules go in "Project rules". -->
11
+
12
+ ## 1. Names
13
+
14
+ **Never use underscores** in any identifier, database object or environment variable name.
15
+
16
+ | Kind | Convention | Example |
17
+ |---|---|---|
18
+ | Classes, records, structs | PascalCase, descriptive | `SqlQueryBuilder`, not `SqlQB` |
19
+ | Interfaces | `I` prefix | `IQueryExecutor` |
20
+ | Methods | PascalCase verb phrase; async methods end in `Async` | `GetConnectionAsync()` |
21
+ | Properties | PascalCase, no prefix | `ConnectionString` |
22
+ | Instance fields | **per-project choice**: `obj` prefix (`objLogger`) or bare PascalCase (`Logger`). Default `obj`. Recorded in the project's Coding Standards | `private readonly ILogger<X> objLogger;` |
23
+ | Static and const fields | PascalCase, no prefix | `MaxRetryCount`, not `MAX_RETRY_COUNT` |
24
+ | Method parameters | `a` prefix + PascalCase | `LoginAsync(string aEmail)` |
25
+ | Local variables | `v` prefix + PascalCase | `var vResponse = …` |
26
+ | Booleans | same prefix, question form | `IsValid`, `vHasRows`, `aCanEdit` |
27
+ | Test methods | short PascalCase; scenario in the XML `<summary>` | `LoginRejectsBadPassword` |
28
+ | Environment variables | PascalCase, no separators; read through `IConfiguration` via a provider that maps them to `Section:Key` | `AppManagerBaseUrl` |
29
+
30
+ Rejected: `_field` prefixes, snake_case, Hungarian type prefixes (`strName`), `Method_State_Result` test names, `UPPER_SNAKE` or `Section__Key` environment variables.
31
+
32
+ Controller actions: the `a` prefix applies to `[FromRoute]`, `[FromQuery]` and `[FromBody]` parameters and flows into the OpenAPI schema. DTO **property** names stay PascalCase without prefix.
33
+
34
+ ## 2. Database
35
+
36
+ - PascalCase, singular table names: `CustomerOrder`. PascalCase columns: `FirstName`.
37
+ - Primary key `<Table>Id`; foreign key `<ReferencedTable>Id`.
38
+ - Stored procedures and functions: verb prefix, PascalCase: `GetCustomerOrders`, `InsertOrder`.
39
+ - Index `IX<Table><Column>` · primary key `Pk<Table>` · foreign key `Fk<Table><Ref>` · unique `Uc<Table><Column>`.
40
+ - Data access is Dapper. Migrations live in a dedicated `<App>Db` project using DbUp, run at application startup or by the pipeline. Never a `database` folder of loose scripts at the root.
41
+
42
+ ## 3. Projects and files
43
+
44
+ - `src/` and `tests/` at the root. The primary head is `src/<App>/<App>.csproj`; `<App>.App` is banned. Secondary heads take a descriptive suffix: `<App>.Api`, `<App>.Desktop`, `<App>.Cli`. Satellites: `<App>.Core`, `<App>UI` (Razor class library), `<App>.Tests`.
45
+ - One class per file; file-scoped namespaces; nullable reference types enabled.
46
+ - File order: usings, namespace, type; inside the type: fields, constructor, properties, methods.
47
+ - Configuration: `appsettings.json` layered by `appsettings.{Environment}.json`; development secrets in `dotnet user-secrets`, with a `secrets.example.json` listing every key. No second mechanism.
48
+
49
+ ## 4. Code
50
+
51
+ - Methods under about 20 lines; single responsibility; at most three levels of nesting; early returns.
52
+ - `async`/`await` for all I/O; `ConfigureAwait(false)` in libraries; no `async void` outside event handlers.
53
+ - LINQ method syntax for simple queries; avoid multiple enumeration.
54
+ - `StringBuilder` in loops; dispose `IDisposable`; cache expensive work.
55
+ - XML documentation on every public member: `<summary>`, `<param>`, `<returns>`, `<exception>`; `<remarks>` where the flow is not obvious.
56
+
57
+ ## 5. Tests
58
+
59
+ - xUnit. A test project from day one.
60
+ - Short PascalCase names, scenario in `<summary>`; arrange, act, assert; one assertion per test where practical.
61
+
62
+ ## 6. Logging
63
+
64
+ - Serilog with a rolling file sink in every executable head (web, API, MAUI, desktop, console, background service), wired before anything else can fail: `Log.Logger = new LoggerConfiguration().MinimumLevel.Information().WriteTo.Console().WriteTo.File("<build output>/logs/<app>-.log", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 14).CreateLogger();` then `builder.Services.AddSerilog()` or `builder.Host.UseSerilog()`; MAUI: `builder.Logging.AddSerilog()` in `MauiProgram`, path under `FileSystem.AppDataDirectory`.
65
+ - `Log.Fatal` around startup, handlers for `AppDomain.CurrentDomain.UnhandledException` and `TaskScheduler.UnobservedTaskException`, `Log.CloseAndFlush()` on exit.
66
+ - Class libraries reference only `Microsoft.Extensions.Logging.Abstractions` and log through `ILogger<T>` with structured templates.
67
+ - Brownfield: an existing structured file-logging stack is compliant; new heads still use Serilog.
68
+
69
+ ## 7. Testability
70
+
71
+ - Blazor: a stable `data-testid` (or element id) on every control the verifier must reach.
72
+ - MAUI: a stable, unique `AutomationId` on every interactive or data-bound control, named by intent (`LoginSubmitButton`, `ClientsGrid`), set on the element whose data the gate asserts.
73
+
74
+ ## 8. Security
75
+
76
+ - No credentials in code. Parameterised queries. Validate inputs. Log security events.
77
+
78
+ ## 9. Enforcement
79
+
80
+ `.editorconfig` at the repository root (created at day-1) enforces: file-scoped namespaces (warning), `Async` suffix (warning), `var` for locals (warning), nullable enabled, no `_` prefix on private fields (custom naming rule, warning). `StyleCop.Analyzers` is optional and off by default.
81
+
82
+ The verifier's standards check runs:
83
+
84
+ ```bash
85
+ # underscore-prefixed fields
86
+ grep -rE "private(\s+readonly)?\s+\w+\s+_[a-z]" src/ 2>/dev/null
87
+ # underscores in test method names
88
+ grep -rE "public\s+(async\s+)?Task\s+\w+_\w+\s*\(" tests/ 2>/dev/null
89
+ # fields missing the obj prefix (obj-style projects only)
90
+ grep -rPE "private(\s+readonly)?\s+\w+\s+(?!obj)[A-Z]\w+\s*[;=]" src/ 2>/dev/null | grep -v "static\|const"
91
+ ```
92
+
93
+ Severity: error for file-scoped namespace and underscore field prefix; warning for nullable and the `Async` suffix; the rest informational.