@techierathore/techieflow 1.0.4 → 1.1.1
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/flow-master.md +2 -0
- package/.claude/commands/TechieFlow/agents/verifier.md +2 -2
- package/.claude/commands/TechieFlow/tasks/_develop-mode.md +34 -0
- package/.claude/commands/TechieFlow/tasks/_owner-language.md +1 -0
- package/.claude/commands/TechieFlow/tasks/_status-update-gate.md +4 -3
- package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +2 -2
- package/.claude/commands/TechieFlow/tasks/amend-docs.md +2 -2
- package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +3 -3
- package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +5 -5
- package/.claude/commands/TechieFlow/tasks/develop-end-to-end.md +30 -0
- package/.claude/commands/TechieFlow/tasks/fix-issues.md +3 -2
- package/.claude/commands/TechieFlow/tasks/generate-html.md +2 -2
- package/.claude/commands/TechieFlow/tasks/handoff-phase.md +2 -2
- package/.claude/commands/TechieFlow/tasks/mockups.md +2 -2
- package/.claude/commands/TechieFlow/tasks/productguide.md +2 -2
- package/.claude/commands/TechieFlow/tasks/render-workflow-docs.md +1 -1
- package/.claude/commands/TechieFlow/tasks/triage-and-fix.md +2 -2
- package/.claude/commands/TechieFlow/tasks/triage-issues.md +2 -2
- package/.claude/commands/TechieFlow/tasks/verify-phase.md +12 -11
- package/.opencode/plugin/techieflow.js +194 -14
- package/.tfcore/agents/flow-master.md +2 -0
- package/.tfcore/agents/verifier.md +2 -2
- package/.tfcore/core-config.yaml +2 -1
- package/.tfcore/hooks/block-git.sh +4 -2
- package/.tfcore/hooks/guard-build.sh +5 -1
- package/.tfcore/hooks/guard-db.sh +112 -13
- package/.tfcore/hooks/guard-status-html.sh +86 -2
- package/.tfcore/hooks/guard-verify-deps.sh +16 -1
- package/.tfcore/hooks/guard-verify.sh +8 -3
- package/.tfcore/hooks/sweep-artifacts.sh +46 -0
- package/.tfcore/hooks/yolo-allow.sh +27 -0
- package/.tfcore/standards/blazor-zoom.cs.txt +191 -0
- package/.tfcore/standards/coding-standards-dotnet.md +31 -3
- package/.tfcore/standards/owner-words.txt +23 -0
- package/.tfcore/tasks/_develop-mode.md +34 -0
- package/.tfcore/tasks/_owner-language.md +1 -0
- package/.tfcore/tasks/_status-update-gate.md +4 -3
- package/.tfcore/tasks/_yolo-mode.md +2 -2
- package/.tfcore/tasks/amend-docs.md +2 -2
- package/.tfcore/tasks/day1-brownfield.md +3 -3
- package/.tfcore/tasks/day1-greenfield.md +5 -5
- package/.tfcore/tasks/develop-end-to-end.md +30 -0
- package/.tfcore/tasks/fix-issues.md +3 -2
- package/.tfcore/tasks/generate-html.md +2 -2
- package/.tfcore/tasks/handoff-phase.md +2 -2
- package/.tfcore/tasks/mockups.md +2 -2
- package/.tfcore/tasks/productguide.md +2 -2
- package/.tfcore/tasks/render-workflow-docs.md +1 -1
- package/.tfcore/tasks/triage-and-fix.md +2 -2
- package/.tfcore/tasks/triage-issues.md +2 -2
- package/.tfcore/tasks/verify-phase.md +12 -11
- package/.tfcore/telemetry/SCHEMA.md +10 -2
- package/.tfcore/telemetry/install-metrics.sh +3 -2
- package/.tfcore/telemetry/tf-metrics.sh +38 -2
- package/.tfcore/templates/stack-defaults/dotnet.md +3 -1
- package/.tfcore/templates/v4custom/app-agents-md-tmpl.md +6 -0
- package/.tfcore/templates/v4custom/app-architecture-tmpl.md +5 -0
- package/.tfcore/templates/v4custom/app-brd-tmpl.md +7 -4
- package/.tfcore/templates/v4custom/app-checklist-tmpl.md +11 -0
- package/.tfcore/templates/v4custom/app-phase-brd-tmpl.md +94 -0
- package/.tfcore/templates/v4custom/app-phase-uidesign-tmpl.md +60 -0
- package/.tfcore/templates/v4custom/app-phases-tmpl.md +2 -1
- package/.tfcore/templates/v4custom/app-uidesign-tmpl.md +4 -2
- package/.tfcore/templates/v4custom/build-subagent-prompt.md +2 -2
- package/.tfcore/templates/v4custom/html-render-shell.md +6 -2
- package/.tfcore/utils/__pycache__/tf-devguide-list.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-doc-check.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-split-brd.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-status-facts.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-verify-list.cpython-312.pyc +0 -0
- package/.tfcore/utils/tf-appium.mjs +179 -0
- package/.tfcore/utils/tf-assets-browser.mjs +96 -0
- package/.tfcore/utils/tf-assets.sh +97 -12
- package/.tfcore/utils/tf-brd-status.py +14 -5
- package/.tfcore/utils/tf-build-list.py +95 -12
- package/.tfcore/utils/tf-build-list.sh +2 -1
- package/.tfcore/utils/tf-build.sh +163 -15
- package/.tfcore/utils/tf-checklist-edit.py +21 -3
- package/.tfcore/utils/tf-ci-repro.py +685 -0
- package/.tfcore/utils/tf-ci-repro.sh +24 -0
- package/.tfcore/utils/tf-day1-files.py +55 -28
- package/.tfcore/utils/tf-develop.sh +264 -0
- package/.tfcore/utils/tf-devguide-list.py +53 -24
- package/.tfcore/utils/tf-doc-check.py +218 -26
- package/.tfcore/utils/tf-doc-tests.sh +116 -0
- package/.tfcore/utils/tf-emit.sh +132 -45
- package/.tfcore/utils/tf-feedback.sh +13 -0
- package/.tfcore/utils/tf-fix-close.sh +87 -31
- package/.tfcore/utils/tf-goal.sh +12 -12
- package/.tfcore/utils/tf-harness.sh +9 -4
- package/.tfcore/utils/tf-lock.sh +29 -0
- package/.tfcore/utils/tf-log-miss.py +34 -8
- package/.tfcore/utils/tf-login.mjs +167 -0
- package/.tfcore/utils/tf-maccatalyst-check.sh +92 -0
- package/.tfcore/utils/tf-menus.mjs +401 -0
- package/.tfcore/utils/tf-misses-md.py +10 -4
- package/.tfcore/utils/tf-mockup-parity.mjs +763 -71
- package/.tfcore/utils/tf-mockup-parity.sh +25 -2
- package/.tfcore/utils/tf-owner-text.py +233 -0
- package/.tfcore/utils/tf-owner-text.sh +14 -0
- package/.tfcore/utils/tf-phase.sh +38 -4
- package/.tfcore/utils/tf-portable.sh +230 -0
- package/.tfcore/utils/tf-render-html.py +79 -5
- package/.tfcore/utils/tf-req-ids.py +36 -0
- package/.tfcore/utils/tf-selfcheck.sh +39 -6
- package/.tfcore/utils/tf-split-brd.py +11 -1
- package/.tfcore/utils/tf-stack-check.sh +3 -0
- package/.tfcore/utils/tf-status-evidence.sh +11 -9
- package/.tfcore/utils/tf-status-facts.py +160 -45
- package/.tfcore/utils/tf-theme.mjs +189 -0
- package/.tfcore/utils/tf-triage.py +74 -17
- package/.tfcore/utils/tf-triage.sh +2 -0
- package/.tfcore/utils/tf-verify-boot.sh +529 -54
- package/.tfcore/utils/tf-verify-emit.sh +57 -17
- package/.tfcore/utils/tf-verify-env.sh +33 -4
- package/.tfcore/utils/tf-verify-list.py +290 -24
- package/.tfcore/utils/tf-verify-list.sh +3 -1
- package/.tfcore/utils/tf-verify-native.mjs +307 -0
- package/.tfcore/utils/tf-verify-screens.mjs +341 -44
- package/.tfcore/utils/tf-verify-screens.sh +23 -5
- package/.tfcore/utils/tf-verify-tests.sh +310 -19
- package/.tfcore/utils/tf-verify-verdict.py +163 -21
- package/.tfcore/utils/tf-verify-zoom.mjs +193 -0
- package/.tfcore/utils/tf-verify-zoom.sh +29 -0
- package/.tfcore/utils/tf-yolo-alias.sh +84 -0
- package/.tfcore/utils/tf-yolo-perms.py +135 -0
- package/.tfcore/utils/tf-yolo-start.sh +44 -0
- package/.tfcore/utils/tf-yolo.sh +31 -3
- package/.tfcore/utils/tf_defect.py +27 -0
- package/.tfcore/utils/tf_feedback.py +272 -0
- package/.tfcore/utils/tf_roadmap.py +35 -0
- package/.tfcore/utils/tf_stack_check.py +93 -0
- package/README.md +6 -2
- package/docs/TechieFlow-Installation.md +5 -3
- package/opencode.jsonc +6 -2
- package/package.json +1 -1
- package/scripts/install.mjs +13 -2
- package/.tfcore/utils/__pycache__/tf-brd-status.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-codex-bind.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-codex-telemetry.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-day1-files.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-log-miss.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-misses-md.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-mockups-locate.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-opencode-audit.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-render-html.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-triage.cpython-312.pyc +0 -0
- package/.tfcore/utils/__pycache__/tf-verify-verdict.cpython-312.pyc +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# _yolo-mode (shared rule — YOLO / goal mode: run unattended to completion)
|
|
2
2
|
|
|
3
|
-
YOLO means all permissions and all access are granted: run one command to completion and never stop to check in. It never crosses an owner review into the next phase; `*day1-greenfield` runs one stage, and stage 2 needs `--stage2`. `*build-phase` and `*verify` are in YOLO by default; every other command honours it when it is on.
|
|
3
|
+
YOLO means all permissions and all access are granted: run one command to completion and never stop to check in. It never crosses an owner review into the next phase; `*day1-greenfield` runs one stage, and stage 2 needs `--stage2`. The one command that does is `*develop-end-to-end`, under its own rule (`_develop-mode.md`). `*build-phase` and `*verify` are in YOLO by default; every other command honours it when it is on.
|
|
4
4
|
|
|
5
5
|
## When it is on
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ YOLO means all permissions and all access are granted: run one command to comple
|
|
|
14
14
|
|
|
15
15
|
## What changes
|
|
16
16
|
|
|
17
|
-
- Deletes and `sudo` run without a prompt. Read-only git is allowed. Git writes stay refused in every mode; the owner commits.
|
|
17
|
+
- Nothing asks. Deletes and `sudo` run without a prompt; `tf-yolo.sh on` also makes OpenCode stop asking (from its next session) and the `yolo-allow.sh` hook approves every Claude Code call. Claude Code's own safety checks still ask unless the session was started with `tfyolo` (`tfyolo -c` keeps the conversation); say that in one line when one asks. Read-only git is allowed. Git writes stay refused in every mode; the owner commits.
|
|
18
18
|
- No question, confirmation or pause: take the documented default and record it in the checklist Remarks. The one question that survives is a new test user (`_smoke-test-policy.md`): use a documented account; if none exists, create one named `{App}-yolo-tester`, record it in the UsageGuide, and continue.
|
|
19
19
|
- Never end a turn with a question, a plan or "shall I". End only when the command is complete or everything left is owner-only.
|
|
20
20
|
- A failed build, a dead port, a stopped service: fix it and continue. A `429` from a sub-agent or an API: wait 60 seconds, retry once, then route around it.
|
|
@@ -18,10 +18,10 @@ First: `bash .tfcore/utils/tf-phase.sh start amend-docs {App}` prints the start
|
|
|
18
18
|
4. BRD. ADD: append a ledger item with the next id, its screen, its mockup link and its acceptance line "When <actor> <does what> on <screen>, then <observable result>"; a new screen gets a row in the Screens and flow table and a Planned row in the Development status table. MODIFY: edit the item in place, same id. REMOVE: `~~BRD-N~~ (removed {date}: reason)`, never deleted. If the additions would take a Small project past 50 requirements, raise it to Medium: `bash .tfcore/utils/tf-day1-files.sh {App} --size M` and the Size in every document header. If they would take a Medium project, or one phase, past 100 requirements or 20 screens, stop and propose a phase split: a new row in `docs/{App}-Phases.md` (written with `--size L` when absent) and a new `docs/{App}-Pn-BRD.md`, instead of growing this one.
|
|
19
19
|
5. Architecture, when in scope and ARCH items exist: edit the affected sections in place, and add a Decisions log row (date, decision, why, status `planned` naming the BRD item) for every new decision or package. A reversed decision gets a new row; the old row stays.
|
|
20
20
|
6. Mockups: when a screen was added or changed, run `.tfcore/tasks/mockups.md` with `--update`, so every screen in the BRD has a current mockup before the checklist changes.
|
|
21
|
-
7. Checklist, only if it exists. ADD: `bash .tfcore/utils/tf-split-brd.sh {App} --add-missing` appends rows for the new items; correct their class. MODIFY: set the rows derived from that item to `Needs re-verify` with a Remark saying what changed. REMOVE: set
|
|
21
|
+
7. Checklist, only if it exists. ADD: `bash .tfcore/utils/tf-split-brd.sh {App} --add-missing` appends rows for the new items; correct their class. MODIFY: set the rows derived from that item to `Needs re-verify` with a Remark saying what changed. REMOVE: set Status to `N/A`, `%` to `0` and the Remark to `removed {date}: <reason>`, and keep the rows; the check does not ask a removed row for an acceptance line, BRD item, mockup or detail entry. Where the mapping from an item to its rows is unclear, ask, do not guess. If the checklist does not exist yet, the next day-1 stage 2 picks everything up.
|
|
22
22
|
8. If the amendment changed code-level flows, say that `*devguide {App} --update` is due after the next build.
|
|
23
23
|
9. Close what this amendment fixed: `bash .tfcore/utils/tf-emit.sh --open-misses {App} --artifact-class doc` lists the open misses whose deficient artifact is a document. Close the ones this amendment resolves in one call: `bash .tfcore/utils/tf-fix-close.sh {App} --misses <id>,<id> --fix-cmd amend-docs --verdict Verified`. Where the mapping from a miss to this amendment is unclear, ask, do not guess. Without this a document miss can never close: `*fix-issues` and `*build-phase` close off checklist rows the verifier touched, which a BRD edit never is.
|
|
24
24
|
10. Decide whether this amendment is a miss: should the original documents plainly have said this (a behaviour that was always required, or two sections that contradicted each other)? Then run `*log-miss {App} "<one sentence>"`. A change of mind or a feature decided today is scope arriving late, not a miss.
|
|
25
|
-
11. `bash .tfcore/utils/tf-doc-check.sh --app {App}`; fix every FAIL.
|
|
25
|
+
11. `bash .tfcore/utils/tf-doc-check.sh --app {App}`; fix every FAIL. Then `bash .tfcore/utils/tf-doc-tests.sh <every document this amendment changed>`: a unit test that reads one of them runs, and a `FAIL` means the amendment removed or changed text a test guards. Put it back, or, when the change is meant, the phase stays open and the report names the test for `*triage-and-fix`; never edit the test here (Lekhak TF-016).
|
|
26
26
|
12. Run the status gate (`.tfcore/tasks/_status-update-gate.md`) with `"cmd":"amend-docs"`.
|
|
27
27
|
13. Report: items added (ids), modified, removed, the highest id now, what changed in the Architecture, the checklist rows touched, and the next command from the gate.
|
|
@@ -13,16 +13,16 @@ First, before anything else: `bash .tfcore/utils/tf-phase.sh start day1-brownfie
|
|
|
13
13
|
|
|
14
14
|
## Steps, in this order
|
|
15
15
|
|
|
16
|
-
1. `bash .tfcore/utils/tf-day1-files.sh {App} --size {S|M|L} --kind {app|library}` writes the size
|
|
16
|
+
1. `bash .tfcore/utils/tf-day1-files.sh {App} --size {S|M|L} --kind {app|library}` writes the size and the kind into `core-config.yaml` and nothing else; for Large it also writes `docs/{App}-Phases.md`, whose table you fill first: one row per phase, each within Medium, every screen in exactly one phase. Before rewriting any document that already exists, `bash .tfcore/utils/tf-day1-files.sh --archive <file> ...` moves it to `docs/OldDocs/`. Never write a `-v2` variant.
|
|
17
17
|
2. `bash .tfcore/utils/tf-mockups-locate.sh` moves every mockup found elsewhere in the repository into `docs/mockups/`, the only mockup folder, and lists what is there.
|
|
18
18
|
3. Architecture: `docs/{App}-Architecture.md` from `.tfcore/templates/v4custom/app-architecture-tmpl.md`, in the template's order, Status "Current". Harvest architecture material from the hint documents first, attributed; scan the code only for what they do not cover. Stack decisions come from the project files, citing the source per row; the Solution structure from the projects; the Component map from project references; the Data model from the migrations or entity classes; the Decisions log opens with "current stack as-is" and adds a `planned` row for every structural change the BRD calls for. Scan the instance fields for the dominant naming style; if none reaches about 80 percent, record the drift under Open questions. Quote every mermaid label; never use `end` as a node id.
|
|
19
19
|
4. BRD, first half: `docs/{App}-BRD.md` from `app-brd-tmpl.md`: the header (App, Kind, Size, Stack answer set, Status, Date), Summary, Scope, Users and roles, and the Screens and flow table, one row per routed page found in the code. A dialog is a row under its parent screen with `on /route` in the Route column.
|
|
20
20
|
5. Mockups: run `.tfcore/tasks/mockups.md` for `{App}`. It links the mockups already in `docs/mockups/` to their screens and produces one for every screen that has none, from the code and the running application. Every screen ends with a mockup.
|
|
21
21
|
6. BRD, second half: the Requirements ledger, one `BRD-N` per thing the verifier will test, each naming its screen, linking its mockup and carrying one acceptance line "When <actor> <does what> on <screen>, then <observable result>". Harvested documents come first: every "the system shall" or "the user can" line becomes an item, attributed, and every table, screen inventory and workflow they hold carries in, never compressed to a one-liner. Then the code: what it already does becomes items too. Mark inferred items `<!-- inferred — please verify -->`. The Non-functional table takes a `perf-budget:` only where the owner stated a number, and the logging requirement from the answer set, recorded as met when the scan found it wired. The Development status table has one row per screen with Verified and Open counts from the strongest evidence. If the count would pass the size cap, propose a phase split instead of merging items.
|
|
22
|
-
Large: steps 4 to 6 run once per phase of the Phases table, phase 1 in `docs/{App}-BRD.md` and `docs/{App}-UIDesign.md`, phase n in `docs/{App}-Pn-BRD.md` and `docs/{App}-Pn-UIDesign.md`, each header carrying `Phase | n of m` and its own Size, ids running on across phases.
|
|
22
|
+
Large: steps 4 to 6 run once per phase of the Phases table, phase 1 in `docs/{App}-BRD.md` and `docs/{App}-UIDesign.md`, phase n in `docs/{App}-Pn-BRD.md` (from `app-phase-brd-tmpl.md`: this phase's screens and requirements only, linking back to phase 1) and `docs/{App}-Pn-UIDesign.md` (from `app-phase-uidesign-tmpl.md`, the same way), each header carrying `Phase | n of m` and its own Size, ids running on across phases.
|
|
23
23
|
7. Checklist: run `.tfcore/tasks/split-brd.md` for `{App}` (Large: with `--all-phases`, one checklist per phase). If a phased plan is among the harvested documents, split-brd migrates its statuses; the plan then moves to `docs/OldDocs/`.
|
|
24
24
|
8. Coding Standards: `docs/{App}-Coding-Standards.md` from `app-coding-standards-tmpl.md`. "Standards applied" names `.tfcore/standards/coding-standards-core.md` and the stack file, plus the choices the stack file leaves open. Where the stack file leaves a naming convention open, it follows the drift scan of step 3: the dominant style if one reaches 80 percent, else the stack file's default; a drafting instruction overrides. "Project rules" holds only rules true of this project alone.
|
|
25
|
-
9. `bash .tfcore/utils/tf-day1-files.sh {App} --prefix {obj|none}` writes `.editorconfig`, `AGENTS.md` and `CLAUDE.md`.
|
|
25
|
+
9. `bash .tfcore/utils/tf-day1-files.sh {App} --prefix {obj|none}` writes `.editorconfig`, `AGENTS.md` and `CLAUDE.md` and adds the document paths to `core-config.yaml`.
|
|
26
26
|
10. `bash .tfcore/utils/tf-gitignore-audit.sh . --fix`. Read its output. Any untracking commands it prints go into your summary for the owner to run; agents never run git.
|
|
27
27
|
11. Build once through `.tfcore/templates/v4custom/build-invocation-ladder.md`. A real compile error becomes one line under Known blockers; a wrong-rung error never does.
|
|
28
28
|
12. UsageGuide: `docs/{App}-UsageGuide.md` from `app-usageguide-tmpl.md`. Test users: read the users table through the connection string in the configuration and list the existing accounts, one per role, marked as existing, with "ask owner" where a password is unknown; if the database is unreachable, list the intended accounts as planned. Create no user. The Execution guide from the code; one "How to test" section per screen in navigation order, naming the user, the steps, the expected result and the REQ ids.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# day1-greenfield
|
|
2
2
|
|
|
3
|
-
`*day1-greenfield {App}` starts a product that has no code. It runs in two stages with one owner review between them. Stage 1 produces the Architecture, the mockups and the BRD, then stops for review. `*day1-greenfield {App} --stage2` runs only after the owner has approved them and produces the checklist and the remaining documents. No mode skips the review: YOLO runs one stage to completion, never both.
|
|
3
|
+
`*day1-greenfield {App}` starts a product that has no code. It runs in two stages with one owner review between them. Stage 1 produces the Architecture, the mockups and the BRD, then stops for review. `*day1-greenfield {App} --stage2` runs only after the owner has approved them and produces the checklist and the remaining documents. No mode skips the review: YOLO runs one stage to completion, never both. The one exception is `*develop-end-to-end`, which runs both stages itself (`.tfcore/tasks/_develop-mode.md`).
|
|
4
4
|
|
|
5
5
|
First, before anything else: `bash .tfcore/utils/tf-phase.sh start day1-greenfield {App}` prints the start time and marks the command running.
|
|
6
6
|
|
|
7
7
|
## Stage 1 — Architecture, mockups, BRD
|
|
8
8
|
|
|
9
|
-
Ask once each, and nothing per section:
|
|
9
|
+
Ask once each, and nothing per section (in develop mode ask nothing: `_develop-mode.md` gives every answer):
|
|
10
10
|
|
|
11
11
|
1. `{App}` if missing. PascalCase, no spaces.
|
|
12
12
|
2. The concept: "Describe the app, any length: a sentence, paragraphs, bullets, half-baked notes, comparisons to other apps. You will edit the document afterwards." Read all of it. Never cap or summarise the owner's input.
|
|
@@ -16,12 +16,12 @@ Ask once each, and nothing per section:
|
|
|
16
16
|
|
|
17
17
|
Then, in this order:
|
|
18
18
|
|
|
19
|
-
6. `bash .tfcore/utils/tf-day1-files.sh {App} --size {S|M|L} --kind {app|library}` writes the size
|
|
19
|
+
6. `bash .tfcore/utils/tf-day1-files.sh {App} --size {S|M|L} --kind {app|library}` writes the size and the kind into `core-config.yaml` and nothing else; for Large it also writes `docs/{App}-Phases.md`, whose table you fill first: one row per phase, each within Medium, every screen in exactly one phase. On a re-run of stage 1, first `bash .tfcore/utils/tf-day1-files.sh --archive docs/{App}-BRD.md docs/{App}-Architecture.md docs/{App}-UIDesign.md` moves the old copies to `docs/OldDocs/`. Never write a `-v2` variant; never ask merge-or-new.
|
|
20
20
|
7. Architecture: `docs/{App}-Architecture.md` from `.tfcore/templates/v4custom/app-architecture-tmpl.md`, in the template's order. Stack decisions come from the answer set and the owner's answers, each row citing its source. Harvested notes carry into the sections attributed, never summarised away. Quote every mermaid label; never use `end` as a node id.
|
|
21
21
|
8. BRD, first half: `docs/{App}-BRD.md` from `app-brd-tmpl.md`: the header (App, Kind, Size, Stack answer set, Status, Date), Summary, Scope, Users and roles, and the Screens and flow table. A dialog is a row under its parent screen with `on /route` in the Route column.
|
|
22
22
|
9. Mockups: run `.tfcore/tasks/mockups.md` for `{App}`. It reads the Screens and flow table and produces `docs/{App}-UIDesign.md` and one `docs/mockups/<screen>.html` per screen. An app with no screens records "skipped — no UI".
|
|
23
23
|
10. BRD, second half: the Requirements ledger, one `BRD-N` per thing the verifier will test, each naming its screen, linking its mockup and carrying one acceptance line "When <actor> <does what> on <screen>, then <observable result>"; the Non-functional table (a `perf-budget:` only where the owner gave a number; the logging requirement from the answer set); the Development status table, one row per screen, all Planned. The concept is the primary source: every feature, actor and constraint in it becomes an item. Mark inferred items `<!-- inferred — please verify -->`. Harvested requirements carry in as items, attributed, none dropped. If the count would pass the size cap, propose a phase split instead of merging items.
|
|
24
|
-
Large: steps 8 to 10 run once per phase of the Phases table, phase 1 in `docs/{App}-BRD.md` and `docs/{App}-UIDesign.md`, phase n in `docs/{App}-Pn-BRD.md` and `docs/{App}-Pn-UIDesign.md`, each header carrying `Phase | n of m` and its own Size, ids running on across phases. Every screen gets its mockup now.
|
|
24
|
+
Large: steps 8 to 10 run once per phase of the Phases table, phase 1 in `docs/{App}-BRD.md` and `docs/{App}-UIDesign.md`, phase n in `docs/{App}-Pn-BRD.md` (from `app-phase-brd-tmpl.md`: this phase's screens and requirements only, linking back to phase 1) and `docs/{App}-Pn-UIDesign.md` (from `app-phase-uidesign-tmpl.md`, the same way), each header carrying `Phase | n of m` and its own Size, ids running on across phases. Every screen gets its mockup now.
|
|
25
25
|
11. `bash .tfcore/utils/tf-doc-check.sh --app {App}`; fix every FAIL.
|
|
26
26
|
12. Run the status gate (`.tfcore/tasks/_status-update-gate.md`); the run record carries `"cmd":"day1-greenfield","mode":"stage1"`.
|
|
27
27
|
13. Stop and say: "Stage 1 is complete: BRD, Architecture and mockups are written and rendered. Review them in the HTML files, or edit the markdown. When you approve, run `*day1-greenfield {App} --stage2`. To change a screen, edit the concept and re-run stage 1, or run `*mockups {App} --update`."
|
|
@@ -33,7 +33,7 @@ Only with `--stage2`, and only when `docs/{App}-BRD.md` exists. Ask nothing.
|
|
|
33
33
|
0. If the owner gave corrections at the review, apply them to the stage-1 documents first (ids never renumbered; `bash .tfcore/utils/tf-doc-check.sh --app {App}` must pass), count them, and after this run's record append a `review` record: `{"kind":"review","phase":"day1-review","reviewed_run_id":"<stage 1 started>","correction_run_id":"<this run's started>","corrections":N,"what":"<one sentence>"}` through `tf-emit.sh misses`.
|
|
34
34
|
1. Checklist: run `.tfcore/tasks/split-brd.md` for `{App}` (Large: with `--all-phases`, one checklist per phase). The owner never types `*split-brd`.
|
|
35
35
|
2. Coding Standards: `docs/{App}-Coding-Standards.md` from `app-coding-standards-tmpl.md`. "Standards applied" names `.tfcore/standards/coding-standards-core.md` and the stack file, plus the choices the stack file leaves open, taking that file's stated default for each. "Project rules" stays empty unless the concept demands a rule true of this project alone.
|
|
36
|
-
3. `bash .tfcore/utils/tf-day1-files.sh {App} --prefix {obj|none}` writes `.editorconfig`, `AGENTS.md` and `CLAUDE.md` from their templates.
|
|
36
|
+
3. `bash .tfcore/utils/tf-day1-files.sh {App} --prefix {obj|none}` writes `.editorconfig`, `AGENTS.md` and `CLAUDE.md` from their templates and adds the document paths to `core-config.yaml`.
|
|
37
37
|
4. UsageGuide: `docs/{App}-UsageGuide.md` from `app-usageguide-tmpl.md`. The Test users table lists the intended accounts, one per role, none created. The Execution guide is at roadmap level, marking commands that depend on projects not yet built. One "How to test" section per screen in navigation order, naming the user, the steps, the expected result and the REQ ids.
|
|
38
38
|
5. `bash .tfcore/utils/tf-gitignore-audit.sh . --fix`. Read its output. Any untracking commands it prints go into your summary for the owner to run; agents never run git.
|
|
39
39
|
6. Run the status gate; the run record carries `"mode":"stage2"`. The next command is `*build-phase {App}`.
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# develop-end-to-end
|
|
2
|
+
|
|
3
|
+
`*develop-end-to-end {App} {brief}` takes a brief and develops a new app from it, unattended, to the point where the owner starts UAT: Day 1 (both stages), the build with its inline verify and fixes, and the handoff (UsageGuide, smoke checklist, test users). Greenfield only. No question, no confirmation, no review stop (`.tfcore/tasks/_develop-mode.md`). It commits and pushes after every phase and reports the time and tokens of each phase and of the whole build.
|
|
4
|
+
|
|
5
|
+
## Before it starts
|
|
6
|
+
|
|
7
|
+
The owner has made a git repository for the app with a remote (GitHub) and scaffolded TechieFlow into it. `{brief}` is a file path or the brief's text; text is written to `docs/{App}-Brief.md` as given, never shortened.
|
|
8
|
+
|
|
9
|
+
Refuse, with one line saying what is missing, when: the folder is not a git repository, it has no remote, it already has a `docs/{App}-BRD.md` or source code (this command is greenfield only: use `*build-phase`), or a develop run is already active (`.tfcore/.session/develop.json` exists: offer `--resume`).
|
|
10
|
+
|
|
11
|
+
## Steps
|
|
12
|
+
|
|
13
|
+
First: `bash .tfcore/utils/tf-phase.sh start develop-end-to-end {App}` prints the start time; keep it.
|
|
14
|
+
|
|
15
|
+
1. Write the brief to `docs/{App}-Brief.md` when it was given as text. Then record this launch, before the run starts, so its record never overlaps the phases' own (`.tfcore/tasks/_metrics-emit-gate.md`): `tf-emit.sh runs` with `"cmd":"develop-end-to-end","mode":"launch"`, the start time and no rows, then `bash .tfcore/utils/tf-phase.sh end`. The phases record themselves; the Build Report adds them up.
|
|
16
|
+
2. Start the supervisor detached, so it outlives this session, with the harness this session runs in:
|
|
17
|
+
`bash .tfcore/utils/tf-develop.sh . --app {App} --brief docs/{App}-Brief.md --harness <claude|opencode> --detach`
|
|
18
|
+
(`--model <id>` when the owner named one; `--no-push` only when the owner said not to push.)
|
|
19
|
+
3. Wait until `.tfcore/.session/develop.log` shows `day1 started`, then say, in three lines: the run has started; it is followed in `.tfcore/.session/develop.log`; the result will be `docs/{App}-Build-Report.md`. End the turn. This session does none of the phases itself.
|
|
20
|
+
|
|
21
|
+
`*develop-end-to-end {App} --resume` continues a stopped run: `bash .tfcore/utils/tf-develop.sh . --resume --detach`. A phase already done is not run again.
|
|
22
|
+
|
|
23
|
+
## What the run leaves
|
|
24
|
+
|
|
25
|
+
- One commit per phase (`TechieFlow develop-end-to-end: <phase> done — {App}`), pushed, and a last one with the final report.
|
|
26
|
+
- `docs/{App}-Build-Report.md`: built in how long, how long the agent worked, the tokens, one row per phase.
|
|
27
|
+
- `docs/metrics/develop-report.json`: the same figures for a comparison harness, per phase and in total, by model.
|
|
28
|
+
- The usual run records, misses and PROJECT-STATUS, written by each phase's own commands.
|
|
29
|
+
|
|
30
|
+
A usage limit pauses the run until the limit resets, then it resumes (`tf-goal.sh`). A phase the agent declares blocked stops the run with the blocker in PROJECT-STATUS "Known blockers" and in the report; `--resume` continues once the owner has dealt with it.
|
|
@@ -8,8 +8,9 @@ First: `bash .tfcore/utils/tf-phase.sh start fix-issues {App}` prints the start
|
|
|
8
8
|
|
|
9
9
|
1. Triage first, as `.tfcore/tasks/triage-issues.md` steps 1 to 4: read the evidence, boot (`tf-verify-boot.sh start`), reproduce each issue on its screen with the screens script, map it to its row, and log it with `tf-triage.sh demote` or `new`. Then `bash .tfcore/utils/tf-triage.sh {App} close --started <the step-0 time> --cmd fix-issues` writes the escaped gate records and the misses with the discovery cost. A defect nobody logged has no miss to close, so this step is never skipped.
|
|
10
10
|
2. `bash .tfcore/utils/tf-build-list.sh {App} --prompts` now prints FIX mode with the demoted rows, their clusters and one builder prompt each. Spawn every cluster in one turn, exactly as `.tfcore/tasks/build-phase.md` step 2 says: `[trblazeui]` through `/trblazeui`, `[techierag]` through `/techierag`, the rest through the builder sub-agent. A library gap goes into the library's feedback file and the row becomes `Blocked`; never a workaround.
|
|
11
|
-
3. `bash .tfcore/utils/tf-build.sh` until PASS, then smoke every fixed screen with `tf-verify-screens.sh --screen …` (`.tfcore/tasks/_smoke-test-policy.md`); a screen that still fails re-enters step 2 for its rows.
|
|
12
|
-
4. Execute `.tfcore/tasks/verify-phase.md` inline, scoped to the touched rows
|
|
11
|
+
3. `bash .tfcore/utils/tf-build.sh` until PASS, then smoke every fixed screen with `tf-verify-screens.sh --screen …` (`.tfcore/tasks/_smoke-test-policy.md`); a screen that still fails re-enters step 2 for its rows. When the evidence was a failed CI run, `bash .tfcore/utils/tf-ci-repro.sh` must also print PASS; a local build with warm caches does not prove a CI fix. The report says the fix passed that reproduction and that the owner's next CI run is the final check, never that CI is fixed.
|
|
12
|
+
4. Execute `.tfcore/tasks/verify-phase.md` inline, scoped to the touched rows, with its own step 0; rows of another phase's checklist are a second verify with `--phase N`. Only that run writes `Verified`.
|
|
13
13
|
5. `bash .tfcore/utils/tf-verify-boot.sh stop`, then `bash .tfcore/utils/tf-fix-close.sh {App} --started <the step-0 time> --subagents <what was fanned out> --build <pass|fail>`: the fix-issues run record first, then one miss-fix per touched row with the verifier's verdict from the ledger. A row the verifier left below `Verified` stays open with that verdict on its miss-fix.
|
|
14
|
+
5a. On a library (`metrics.project_type: library` in `core-config.yaml`), the documents the package ships describe this fix before the run ends, so one release carries the code and its documents: `.tfcore/tasks/handoff-phase.md` steps 1, 3, 3a and 4 (the UsageGuide, the HTMLs, the DevGuide with `--update`, the feedback replies), and `docs/{App}-AI-Reference.md` updated for every component or option this run changed. No separate handoff run record; this run's covers it. Write the log row's Phase cell as `fix-issues + handoff` (or `triage-and-fix + handoff`), so the gate offers the release, not `*handoff-phase`. Never tell the owner to run the handoff after the release.
|
|
14
15
|
6. Run the status gate (`.tfcore/tasks/_status-update-gate.md`); the run record is the one step 5 wrote. When this run is the last step of a goal, write the sentinel (`.tfcore/tasks/_yolo-mode.md`).
|
|
15
16
|
7. Report: evidence read, issues by kind, rows fixed and now `Verified`, rows still open and why, library gaps logged, and the next command from the gate.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# generate-html
|
|
2
2
|
|
|
3
|
-
Convert one or more **human-readable** markdown files to self-contained HTML using the shared shell. Use this when you need to render documents that `*render-workflow-docs` does not cover (the UsageGuide, the DevGuide,
|
|
3
|
+
Convert one or more **human-readable** markdown files to self-contained HTML using the shared shell. Use this when you need to render documents that `*render-workflow-docs` does not cover (the UsageGuide, the DevGuide, ad-hoc design notes, legacy/archived docs). Note: suffixed doc variants like `-v2` are banned by the collision policy (day1-brownfield §1.6) — superseded docs live unmodified in `docs/OldDocs/`.
|
|
4
4
|
|
|
5
5
|
**NEVER render an agent working document to HTML.** Two are banned by name and `tf-render-html.sh` refuses both with exit 2: the **requirements checklist** `*-Checklist.md` (and its Requirements Status table), and the **miss log** `*-Misses.md`. Agents read them in markdown; an HTML mirror burns tokens and drifts from the source. If asked to render either, decline and explain it is an agent document; if a stale `*-Checklist.html` or `*-Misses.html` exists from before this rule, delete it. The test for any other file: **if the only reader is an agent, it stays markdown.**
|
|
6
6
|
|
|
@@ -92,7 +92,7 @@ Per shell §9 checklist, for each rendered file confirm:
|
|
|
92
92
|
- No external resource references except the two CDN scripts.
|
|
93
93
|
|
|
94
94
|
**Mermaid validity pass (do this for EVERY diagram — it is the #1 reported bug).** Apply the shell §5.5 self-check to each mermaid block before emitting it:
|
|
95
|
-
- Each node/edge/subgraph label that contains anything other than letters, digits, and spaces (i.e. has `(` `)` `/` `&` `:` `,` `[` `]` `{` `}` `#` `@` `<` `>` `|` `"` etc.) MUST be wrapped in double quotes, with the quotes INSIDE the shape brackets (`API["
|
|
95
|
+
- Each node/edge/subgraph label that contains anything other than letters, digits, and spaces (i.e. has `(` `)` `/` `&` `:` `,` `[` `]` `{` `}` `#` `@` `<` `>` `|` `"` etc.) MUST be wrapped in double quotes, with the quotes INSIDE the shape brackets (`API["Orders API (v2)"]`, `DB[("Main database")]`).
|
|
96
96
|
- No node id is a reserved word (lowercase `end`).
|
|
97
97
|
- If you find a bare label in the source MD, **fix it in the emitted HTML** (quote it) rather than copying through a diagram you know will throw "Syntax error" in the browser. Note any such fix in the output summary so the author can also fix the MD source.
|
|
98
98
|
|
|
@@ -84,11 +84,11 @@ Invoke `render-workflow-docs {AppName}` as a subtask. Specifically:
|
|
|
84
84
|
- `docs/{AppName}-Architecture.html` — if implementation revealed "as-built" deltas from "Target", update Architecture.md first, then re-render. Set status to "Current (post-implementation)" or "Current + planned target" as appropriate.
|
|
85
85
|
- `PROJECT-STATUS.html` — always re-render (just updated in §2)
|
|
86
86
|
|
|
87
|
-
Then re-render the **Usage Guide** (updated in §1) and the **DevGuide** (refreshed in §3a) via `.tfcore/tasks/generate-html.md`: `docs/{AppName}-UsageGuide.md` (+
|
|
87
|
+
Then re-render the **Usage Guide** (updated in §1) and the **DevGuide** (refreshed in §3a) via `.tfcore/tasks/generate-html.md`: `docs/{AppName}-UsageGuide.md` (+ `docs/{AppName}-DevGuide.md`) → sibling `.html`. **Do NOT render the checklist to HTML** — it is an AI-agent working document kept in markdown only; its Status table stays accurate in markdown.
|
|
88
88
|
|
|
89
89
|
### 3a. Refresh the Developer Guide
|
|
90
90
|
|
|
91
|
-
Run `.tfcore/tasks/devguide.md` for `{AppName}` (`*devguide {AppName}`) so the screen-by-screen code map reflects the final as-built code — this is the doc a human developer uses to chase bugs and verify the AI-generated code from page → control → service → data-access → stored proc. If a DevGuide already exists, an incremental `--update` is enough (remap only changed screens). It produces `docs/{AppName}-DevGuide.md
|
|
91
|
+
Run `.tfcore/tasks/devguide.md` for `{AppName}` (`*devguide {AppName}`) so the screen-by-screen code map reflects the final as-built code — this is the doc a human developer uses to chase bugs and verify the AI-generated code from page → control → service → data-access → stored proc. If a DevGuide already exists, an incremental `--update` is enough (remap only changed screens). It produces `docs/{AppName}-DevGuide.md`, one file at any size, and its `.html`; §3 above already lists them in the re-render set.
|
|
92
92
|
|
|
93
93
|
### 4. Consolidate the per-library feedback files
|
|
94
94
|
|
package/.tfcore/tasks/mockups.md
CHANGED
|
@@ -9,9 +9,9 @@ First: `bash .tfcore/utils/tf-phase.sh start mockups {App}` prints the start tim
|
|
|
9
9
|
1. `bash .tfcore/utils/tf-mockups-locate.sh` moves any mockup found elsewhere in the repository into `docs/mockups/` and lists what is there.
|
|
10
10
|
2. Read the component reference of the UI library named in the Architecture's Stack decisions (for TrBlazeUI, `.trblazeui/TrBlazeUI-AI-Reference.md`; build once if it is absent). Design only with controls that exist. A control the library lacks is logged as an entry in `docs/{App}-<Library>-Feedback.md`, never designed in silently.
|
|
11
11
|
3. Read the BRD's Screens and flow table: every row is a screen, with its route, roles and fields; a dialog row belongs to its parent screen. A screen that already has a mockup in `docs/mockups/` keeps it and is linked. An app with no screens records "skipped — no UI" in the UIDesign and stops.
|
|
12
|
-
4. For each screen without a mockup (fan out one sub-agent per group of screens when there are many): decide the layout regions, map every region to a control, write `docs/mockups/<screen-slug>.html` with realistic placeholder data in the library's visual language, and fill the screen's section in `docs/{App}-UIDesign.md` from `.tfcore/templates/v4custom/app-uidesign-tmpl.md` (mockup link, roles, regions-to-controls table, fields table, the dialogs it opens, the empty, loading and error states). One shell, one theme, one spacing system across the set.
|
|
12
|
+
4. For each screen without a mockup (fan out one sub-agent per group of screens when there are many): decide the layout regions, map every region to a control, write `docs/mockups/<screen-slug>.html` with realistic placeholder data in the library's visual language, and fill the screen's section in `docs/{App}-UIDesign.md` from `.tfcore/templates/v4custom/app-uidesign-tmpl.md` — for phase n of a Large project, `docs/{App}-Pn-UIDesign.md` from `app-phase-uidesign-tmpl.md`, which carries that phase's screens only (mockup link, roles, regions-to-controls table, fields table, the dialogs it opens, the empty, loading and error states). One shell, one theme, one spacing system across the set.
|
|
13
13
|
5. Make the set click through. The entry screen is the sign-in page (or onboarding, or the home page when there is neither). Every link and every navigation button goes to the mockup it names, written as `<a href="screen.html">` or a form action, never as a script (`onclick="location.href=…"` is refused: it dies in any viewer without scripts): sign in opens the home screen, logout returns to sign in, an "Add" button opens the add screen, a row opens its detail, every menu item leads to its screen. Every screen has a way out. A button that does not navigate shows a message with `onclick`. A dialog opens on its parent page. Sign-in needs no credentials: the button alone navigates.
|
|
14
|
-
6. Anchor every element the build must match with `data-testid`, using the names from the regions-to-controls table: the layout regions, every badge and status indicator, every icon button, every card, table and chart, and every value cell whose width matters. The verifier compares only anchored elements; a mockup without anchors is ungradeable.
|
|
14
|
+
6. Anchor every element the build must match with `data-testid`, using the names from the regions-to-controls table: the layout regions, every badge and status indicator, every icon button, every card, table and chart, and every value cell whose width matters. The verifier compares only anchored elements; a mockup without anchors is ungradeable. A box drawn only in another state (an error, a newer version) carries `data-tf-state="<state>"`; a row of sample data a fresh app has none of carries `data-tf-sample`. Draw every menu and drop-down open, its box marked `data-tf-state="popup-open"` inside the anchored control that opens it, each item that opens a screen an `<a href="<that mockup>.html">`, and sample choices (branch names, past chats) `data-tf-sample`: verify opens each, clicks every item, and fails a missing one.
|
|
15
15
|
7. `bash .tfcore/utils/tf-doc-check.sh --app {App}`: it refuses a broken link, an unreachable or dead-end screen, an inert button and an unanchored mockup. Fix every FAIL.
|
|
16
16
|
8. When run on its own (not inside a day-1 task), run the status gate (`.tfcore/tasks/_status-update-gate.md`) with `"cmd":"mockups"`.
|
|
17
17
|
9. Report: screens mocked, screens kept, controls used, library gaps logged, and the files written.
|
|
@@ -26,7 +26,7 @@ The Product Guide documents the real running app. If the repo is doc-only / not
|
|
|
26
26
|
### 2. Gather the screen inventory + screenshots (reuse, don't reinvent)
|
|
27
27
|
|
|
28
28
|
The DevGuide already did the hard discovery work — reuse it:
|
|
29
|
-
- Read the **DevGuide** (`docs/{AppName}-DevGuide.md
|
|
29
|
+
- Read the **DevGuide** (`docs/{AppName}-DevGuide.md`) for the role→menu map, the screen list, the real post-login landing per role (LANDING-TRUTH), and each screen's purpose.
|
|
30
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
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
32
|
|
|
@@ -34,7 +34,7 @@ The DevGuide already did the hard discovery work — reuse it:
|
|
|
34
34
|
|
|
35
35
|
### 3. Decide structure — single doc vs per-role split
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
**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
38
|
|
|
39
39
|
### 4. Write the guide — END-USER voice, screenshot per screen (FAN OUT per role)
|
|
40
40
|
|
|
@@ -6,7 +6,7 @@ Render BRD.html, Architecture.html, and PROJECT-STATUS.html from their markdown
|
|
|
6
6
|
|
|
7
7
|
After day-1 (or any phase that changes BRD/Architecture/PROJECT-STATUS), regenerate the human-readable HTML mirrors. Self-contained single-file HTML with Mermaid rendering, copy buttons on every code block, mermaid toolbar (zoom/fit/1:1/fullscreen/popout), inline TOC, and sidebar TOC for long docs.
|
|
8
8
|
|
|
9
|
-
**If the user has ad-hoc HUMAN-readable docs to render (
|
|
9
|
+
**If the user has ad-hoc HUMAN-readable docs to render (design notes, archived docs, anything else), use `*generate-html @path/to/file.md` instead — this task only handles the three canonical files.** Note: the **checklist is an AI-agent working document and is NEVER rendered to HTML** — do not render `*-Checklist.md` here or via `generate-html`. Nor are the miss log and feedback files.
|
|
10
10
|
|
|
11
11
|
## Inputs
|
|
12
12
|
|
|
@@ -8,7 +8,7 @@ First: `bash .tfcore/utils/tf-phase.sh start triage-and-fix {App}` prints the st
|
|
|
8
8
|
|
|
9
9
|
1. Compare. `bash .tfcore/utils/tf-verify-list.sh {App} all`, `tf-verify-boot.sh start`, then `tf-verify-screens.sh --list … --base <url>` and `tf-mockup-parity.sh --base <url> --screen … --json-out tests/.artifacts/verify/parity.json` over every screen. Every screen that renders empty, looks broken or drifts from its mockup is an issue, added to the owner's evidence with its screenshot.
|
|
10
10
|
2. Triage. `.tfcore/tasks/triage-issues.md` steps 3 and 4 on the combined issue list, then `tf-triage.sh {App} close --started <the step-0 time> --cmd fix-issues`.
|
|
11
|
-
3. Fix. `.tfcore/tasks/fix-issues.md` steps 2 to 5 on the demoted rows (the builders, the build, the smoke, the verify, `tf-fix-close.sh`).
|
|
11
|
+
3. Fix. `.tfcore/tasks/fix-issues.md` steps 2 to 5 on the demoted rows (the builders, the build, the smoke, the verify, `tf-fix-close.sh`), with `--cmd triage-and-fix` on `tf-fix-close.sh`: it writes this run's record, filed under this command, around the verify it chained. On a library (`metrics.project_type: library`), `fix-issues.md` step 5a too: the shipped documents are brought up to date now, before the gate.
|
|
12
12
|
4. Metrics. Execute `.tfcore/tasks/metrics-report.md`.
|
|
13
|
-
5. Run the status gate (`.tfcore/tasks/_status-update-gate.md`)
|
|
13
|
+
5. Run the status gate (`.tfcore/tasks/_status-update-gate.md`); the run record is the one step 3 wrote, so do not emit another (one over the same window is refused). When this run is the last step of a goal, write the sentinel (`.tfcore/tasks/_yolo-mode.md`).
|
|
14
14
|
6. Summary, one short section per step: screens compared and what the comparison found; root causes found and logged, each with its miss id and discovery cost; fixes made and logged, each with its verdict and fix cost; rows re-verified by status; metrics refreshed, the report's path; the next command from the gate.
|
|
@@ -6,9 +6,9 @@ First: `bash .tfcore/utils/tf-phase.sh start triage-issues {App}` prints the sta
|
|
|
6
6
|
|
|
7
7
|
## Steps
|
|
8
8
|
|
|
9
|
-
1. Read every screenshot and the notes; from a written list take one issue per symptom in the reporter's words. Build the issue list: screen, role, symptom, evidence path, a first guess of kind (`layout`, `render-empty`, `data-logic`, `rag`).
|
|
9
|
+
1. Read every screenshot and the notes; from a written list take one issue per symptom in the reporter's words. Build the issue list: screen, role, symptom, evidence path, a first guess of kind (`layout`, `render-empty`, `data-logic`, `rag`). A failed CI run (its id, link or log) is evidence too: its issue is the failing step and its first error.
|
|
10
10
|
2. `bash .tfcore/utils/tf-verify-boot.sh start` boots the application (dependent services first, from their own configuration). Sign in as a UsageGuide test user (`.tfcore/tasks/_smoke-test-policy.md`). NONE means the issues are logged from the evidence alone and the report says the app was not booted.
|
|
11
|
-
3. Reproduce each issue on its screen; `bash .tfcore/utils/tf-verify-screens.sh --screen <name>=<route> … --base <url>` gives the render and visual evidence and a screenshot. Settle the kind from what you see and map the issue to its row in the checklist (the acceptance line's screen; the DevGuide's screen list). Print the triage table: issue, row, kind, action.
|
|
11
|
+
3. Reproduce each issue on its screen; `bash .tfcore/utils/tf-verify-screens.sh --screen <name>=<route> … --base <url>` gives the render and visual evidence and a screenshot. Settle the kind from what you see and map the issue to its row in the checklist (the acceptance line's screen; the DevGuide's screen list). Print the triage table: issue, row, kind, action. A CI failure is reproduced with `bash .tfcore/utils/tf-ci-repro.sh [<workflow>] [--job <id>]`, never by running the workflow's commands here: this machine's package caches and build output hide what a fresh runner hits (Lekhak TF-019: a runtime pack only the local NuGet cache held). Its FAIL line is the reproduction; a PASS means it could not be reproduced here, logged with `note`.
|
|
12
12
|
4. Log each issue with `bash .tfcore/utils/tf-triage.sh {App} …`: `demote <REQ> "<symptom>" --kind … --evidence <path>` for a defect inside a row's scope, whatever its status; `new "<title>" "<When … on <screen>, then …>" --section "<screen>"` for a defect no row covers (a Not Started row with `BRD-pending`; new scope rather than a defect is still logged, and the report names `*amend-docs`); `note <REQ> "<what was tried>"` when it could not be reproduced. `--source production` for a live report. Whose gap it was is recorded as `--sort` (the four questions of `.tfcore/tasks/log-miss.md` step 1); without it a demoted row is `weak-check` (its line existed and the check let it through) and a new row is `spec`.
|
|
13
13
|
5. With `verify`: execute `.tfcore/tasks/verify-phase.md` inline, scoped to the demoted rows' siblings on the same screens and any scope the owner named. Without it, the verifier does not run and nothing is re-checked informally.
|
|
14
14
|
6. `bash .tfcore/utils/tf-verify-boot.sh stop`, then `bash .tfcore/utils/tf-triage.sh {App} close --started <the step-0 time>`: one escaped gate record per row (no check caught it), one miss per row in the reporter's words with the discovery cost, the run record, and a warning plus a miss if any code file changed during the run.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# verify-phase
|
|
2
2
|
|
|
3
|
-
`*verify {scope} {App}` proves every checklist row in scope against the running application and writes the verdicts. Scope is `ui`, `functional`, `all` or a list of ids; a caller that chains this task passes its scope and nothing is asked. YOLO is its default mode. The application runs on this machine, never on a cloud host. This task never edits source, the BRD or the mockups. It writes tests under `tests/verify/`, evidence under `tests/.artifacts/verify/`, the ledger `docs/.last-verify.json`, and the checklist cells through the verdict script only: a `Verified` written by hand is refused by the hook.
|
|
3
|
+
`*verify {scope} {App} [--phase N|all]` proves every checklist row in scope against the running application and writes the verdicts. Scope is `ui`, `functional`, `all` or a list of ids; a caller that chains this task passes its scope and nothing is asked. YOLO is its default mode. The application runs on this machine, never on a cloud host. This task never edits source, the BRD or the mockups. It writes tests under `tests/verify/`, evidence under `tests/.artifacts/verify/`, the ledger `docs/.last-verify.json`, and the checklist cells through the verdict script only: a `Verified` written by hand is refused by the hook.
|
|
4
4
|
|
|
5
5
|
First: `bash .tfcore/utils/tf-phase.sh start verify-phase {App}` prints the start time; keep it. Then `bash .tfcore/utils/tf-yolo.sh on --source verify` unless YOLO is already on.
|
|
6
6
|
|
|
@@ -10,11 +10,11 @@ Applied to every row in this order; the first that fails is the row's verdict.
|
|
|
10
10
|
|
|
11
11
|
| Check | Question | Tool |
|
|
12
12
|
|---|---|---|
|
|
13
|
-
| build | does the application build and boot | `tf-verify-boot.sh` |
|
|
13
|
+
| build | does the application build and boot, and does its code reference every package the Architecture's `Required packages:` line lists | `tf-verify-boot.sh`; the verdict runs `tf-stack-check.sh` itself |
|
|
14
14
|
| acceptance | does the test carrying the row's id pass | `tf-verify-tests.sh` |
|
|
15
15
|
| render | does every control the mockup anchors show something, no header-only table, no blank page, no error | `tf-verify-screens.sh` |
|
|
16
16
|
| assets | did every stylesheet and script the screen declares arrive | `tf-assets.sh` |
|
|
17
|
-
| visual | nothing overlaps, nothing clipped or off-screen, no sideways scroll, a stylesheet loaded | `tf-verify-screens.sh` |
|
|
17
|
+
| visual | nothing overlaps, nothing clipped or off-screen, no sideways scroll, a stylesheet loaded, text readable (3.0 : 1) in light and in dark mode, no light panel in dark mode | `tf-verify-screens.sh` |
|
|
18
18
|
| mockup | does the built screen carry the structure its mockup draws | `tf-mockup-parity.sh` |
|
|
19
19
|
| speed | within the row's `perf-budget:` line, only when the row declares one | `tf-perf.sh`, `tf-perf-grade.sh` |
|
|
20
20
|
|
|
@@ -22,22 +22,23 @@ Standards has no script yet and is never listed as run. A row is `Verified` only
|
|
|
22
22
|
|
|
23
23
|
## Read
|
|
24
24
|
|
|
25
|
-
The phase's checklist, UIDesign and `docs/mockups
|
|
25
|
+
The phase's checklist, UIDesign and `docs/mockups/`; the UsageGuide's test users. The phase is `--phase N` when given, else `appPhase` in `core-config.yaml`. `--phase all` grades every phase's checklist in turn, phase 1 first: `tf-verify-list.sh {App} {scope} --phase all` prints `PHASES 1 2 3`, then steps 1 and 4 to 6 run once per phase, each with `--phase <n>`, on one boot (steps 2, 3 and 7 once). Each pass writes only its own phase's checklist; the ledger and telemetry name the phase.
|
|
26
26
|
|
|
27
27
|
## Steps
|
|
28
28
|
|
|
29
|
-
1. `bash .tfcore/utils/tf-verify-list.sh {App} {scope}
|
|
29
|
+
1. `bash .tfcore/utils/tf-verify-list.sh {App} {scope} --phase <n>` prints the rows to grade with their acceptance line, screen, route, mockup and perf budget, the screens to drive, and the test users; it writes `tests/.artifacts/verify/list.json`. Every row in scope is graded whatever its status; only N/A is skipped, so a `Verified` row is re-confirmed and an old `Done` claim is tested. NOTHING means run the status gate and stop. A row without an acceptance line cannot be graded: fix the checklist first. A dialog is listed under its parent screen and checked there; never give a dialog a route so it can be tested.
|
|
30
30
|
2. `bash .tfcore/utils/tf-verify-env.sh` prints READY, or the one command the owner must run once.
|
|
31
|
-
3. `bash .tfcore/utils/tf-verify-boot.sh start` boots the head it finds (`--head` or `--project` when there are several) and prints BOOTED with a URL, or a CDP URL for an embedded-browser desktop head, which the browser tools attach to. A dependent service (database, API) is yours to start first, from its own configuration, in order. NONE `kind=build-error`: every row fails the build check; go to step 6. NONE `kind=host` or `kind=no-driver` (an Android
|
|
32
|
-
4. Tests. Every UI and functional row has one test whose title starts with its id, written from the acceptance line, black box, under `tests/verify/`; an NFR row without a screen has a unit test carrying its id in the test project, or is not observable. Reuse a test that exists. Fan out one test-writer sub-agent per screen group in one turn, each with its rows, their acceptance lines, the URL and the test user; a test writer touches no source. Sign in as a UsageGuide test user (`.tfcore/tasks/_smoke-test-policy.md`).
|
|
31
|
+
3. `bash .tfcore/utils/tf-verify-boot.sh start` boots the head it finds (`--head` or `--project` when there are several) and prints BOOTED with a URL, or a CDP URL for an embedded-browser desktop head, which the browser tools attach to. A dependent service (database, API) is yours to start first, from its own configuration, in order. NONE `kind=build-error`: every row fails the build check; go to step 6. NONE `kind=host` or `kind=no-driver` (an Android or iOS head): go to step 6 as well; those rows are written "not verified" with the reason. A Mac desktop head is booted on a Mac and prints `mode=appium` with the Appium address; when a project also has a web head the default stays `web`, so pass `--head maccatalyst` when the owner asked for the Mac head. A Mac head whose screens are drawn in a web view is checked without control names (blank, error bar, overlap, screenshot), and its rows say the names were not measured. Never a static-only pass, never "the owner should start it".
|
|
32
|
+
4. Tests. Every UI and functional row has one test whose title starts with its id, written from the acceptance line, black box, under `tests/verify/`; an NFR row without a screen has a unit test carrying its id in the test project, or is not observable. Reuse a test that exists. A screen whose mockup draws data a fresh app lacks gets `tests/verify/seed/<mockup name>.sh`, which puts the running app (`$TF_BASE`) in the drawn state; `tf-verify-screens.sh` runs it first. Fan out one test-writer sub-agent per screen group in one turn, each with its rows, their acceptance lines, the URL and the test user; a test writer touches no source. Sign in as a UsageGuide test user (`.tfcore/tasks/_smoke-test-policy.md`).
|
|
33
33
|
5. Run the checks, with `<url>` from step 3 and, on a signed-in app, the session cookie from the test login for the tools that take `--cookie`:
|
|
34
34
|
- `bash .tfcore/utils/tf-verify-tests.sh --base <url>`
|
|
35
|
-
- `bash .tfcore/utils/tf-verify-screens.sh --list tests/.artifacts/verify/list.json --base <url>` (or `--cdp <url>`; `--login-path /login --user … --password …` when the app has a sign-in page)
|
|
35
|
+
- `bash .tfcore/utils/tf-verify-screens.sh --list tests/.artifacts/verify/list.json --base <url>` (or `--cdp <url>`; or `--appium <url>` for a Mac desktop head, whose anchors are the controls' accessibility identifiers and whose mockup and asset checks do not run; `--login-path /login --user … --password …` when the app has a sign-in page)
|
|
36
36
|
- `bash .tfcore/utils/tf-assets.sh --base <url> --paths "<every screen route, comma-separated>" --json-out tests/.artifacts/verify/assets.json`
|
|
37
|
-
- `bash .tfcore/utils/tf-mockup-parity.sh --base <url> --screen <name>=<route> … --json-out tests/.artifacts/verify/parity.json` (
|
|
37
|
+
- `bash .tfcore/utils/tf-mockup-parity.sh --base <url> --screen <name>=<route> … --json-out tests/.artifacts/verify/parity.json` (the `Mockup parity:` line step 1 printed; a screen whose route takes a value is added with the value filled in, `--screen <mockup name>=/processes/6/run`; skip on a project with no mockups). Screens and parity both run in light and, when the app has one, dark mode (`--themes` forces it). A driven screen with a mockup and no comparison fails the mockup check
|
|
38
38
|
- for each row with a `perf-budget:` line: `bash .tfcore/utils/tf-perf.sh --base <url> --paths "<its screen's route>" --levels <its concurrency> --requests 24 --build-config <Release or Debug, as booted> --json-out tests/.artifacts/verify/perf/<REQ>.json`
|
|
39
|
+
- for the rows ending `zoom-check:` (a desktop head drawn in a web view; the stack's standard says how it zooms), on each booted head: `bash .tfcore/utils/tf-verify-zoom.sh --appium <url>` (or `--cdp <url>`) `--leave 3 --json-out tests/.artifacts/verify/zoom/<the keys row>.json`; stop and start the head; then the same with `--expect-restored 1.3 --json-out tests/.artifacts/verify/zoom/<the kept row>.json`
|
|
39
40
|
Open every failing screenshot under `tests/.artifacts/verify/screens/` and look at it before step 6.
|
|
40
|
-
6. `bash .tfcore/utils/tf-verify-verdict.sh {App} --apply --started <the step-0 time>` applies the seven checks in order, writes the ledger and rewrites the Status, % and Remarks cells of every graded row, and prints the verdict table. Then `bash .tfcore/utils/tf-verify-emit.sh {App} --started <the step-0 time>` appends the gate records, one miss per newly failing row, and this run's record.
|
|
41
|
+
6. `bash .tfcore/utils/tf-verify-verdict.sh {App} --apply --started <the step-0 time>` applies the seven checks in order, writes the ledger and rewrites the Status, % and Remarks cells of every graded row, and prints the verdict table. Both read the phase from `list.json`. Then `bash .tfcore/utils/tf-verify-emit.sh {App} --started <the step-0 time>` appends the gate records, one miss per newly failing row, and this run's record.
|
|
41
42
|
7. `bash .tfcore/utils/tf-verify-boot.sh stop`.
|
|
42
43
|
8. Run the status gate (`.tfcore/tasks/_status-update-gate.md`); its run record is the one step 6 wrote. A head that could not be driven is named under "Known blockers". When this run is the last step of a goal, write the sentinel (`.tfcore/tasks/_yolo-mode.md`). When the verifier was chained by a build or a fix, that caller runs the gate.
|
|
43
|
-
9. Report: what was booted (head, rung, URL); rows by verdict; the first-failing-check counts; screens driven and screenshots; the parity coverage line (screens graded, failed, ungradeable, without a mockup); the speed lines only for rows that carry a budget; every not-verified row with its reason; the evidence folder; the next command from the gate.
|
|
44
|
+
9. Report: what was booted (head, rung, URL); rows by verdict, per phase; the first-failing-check counts; screens driven and screenshots; the parity coverage line (screens graded, failed, ungradeable, without a mockup); the speed lines only for rows that carry a budget; every not-verified row with its reason; the evidence folder; the next command from the gate.
|
|
@@ -93,7 +93,7 @@ So `tf-emit.sh` detects it and injects it. **Never write `harness` into an emit
|
|
|
93
93
|
|
|
94
94
|
| Field | Type | Values / notes |
|
|
95
95
|
|---|---|---|
|
|
96
|
-
| `cmd` | string | `day1-brownfield` \| `day1-greenfield` \| `split-brd` \| `mockups` \| `build-phase` \| `verify-phase` \| `fix-issues` \| `triage-issues` \| `log-miss` \| `devguide` \| `productguide` \| `handoff-phase` \| `refresh-status` \| `amend-docs` \| `deploy-checklist` (added 2026-09-06) \| `metrics-report` \| `generate-html` \| `render-workflow-docs` \| `triage-and-fix` \| `framework-reset` (framework maintenance, D-19; all five added 2026-09-07, after FR-37's check was built and found 27 records already carrying a value the schema did not list). A value outside this list is a defect in the emitting task, not in the reader: the reader keeps it. |
|
|
96
|
+
| `cmd` | string | `day1-brownfield` \| `day1-greenfield` \| `split-brd` \| `mockups` \| `build-phase` \| `verify-phase` \| `fix-issues` \| `triage-issues` \| `log-miss` \| `devguide` \| `productguide` \| `handoff-phase` \| `refresh-status` \| `amend-docs` \| `deploy-checklist` (added 2026-09-06) \| `metrics-report` \| `generate-html` \| `render-workflow-docs` \| `triage-and-fix` \| `develop-end-to-end` (added 2026-10-08: only its launch; each phase records itself) \| `framework-reset` (framework maintenance, D-19; all five added 2026-09-07, after FR-37's check was built and found 27 records already carrying a value the schema did not list). A value outside this list is a defect in the emitting task, not in the reader: the reader keeps it. |
|
|
97
97
|
| `mode` | string \| null | `build` \| `fix`. `build-phase` already distinguishes these (FIX mode) — capture it; the ratio is the rework metric. `null` for commands with no mode. |
|
|
98
98
|
| `started` | string | ISO-8601 UTC. When the task began — the timestamp you noted at step 0, not "now minus a guess". |
|
|
99
99
|
| `ended` | string | ISO-8601 UTC. Normally equal to `ts`. |
|
|
@@ -105,6 +105,7 @@ So `tf-emit.sh` detects it and injects it. **Never write `harness` into an emit
|
|
|
105
105
|
| `build_result` | string \| null | `pass` \| `fail` \| `not-run`. |
|
|
106
106
|
| `harness` | string \| null | Injected by `tf-emit.sh` (§1). **Do not emit it yourself.** |
|
|
107
107
|
| `yolo` | bool | Whether YOLO / goal mode was on for this run (D-12, FR-35; added 2026-09-05). Written by the task from the flag file at the status gate; wired into every task in Session 4c. |
|
|
108
|
+
| `app_phase` | int | **`verify-phase` only, added 2026-10-11 (Sevak TF-005).** The phase whose checklist this pass graded: 1 is `docs/<App>-Checklist.md`, n is `docs/<App>-P<n>-Checklist.md`. Absent on older records, which graded `appPhase`. One `*verify --phase all` writes one run record per phase, each starting where the one before ended (§2.7b). |
|
|
108
109
|
|
|
109
110
|
---
|
|
110
111
|
|
|
@@ -236,6 +237,7 @@ Failure:
|
|
|
236
237
|
| `gates_run` | string[] | Which gates actually executed this pass — subset of `["build","acceptance","render","assets","visual","mockup-parity","perf","standards"]`, in execution order. A gate absent here did **not** run and cannot be credited or blamed. For `perf`, `assets` and `mockup-parity` this carries real weight: see §3.5. |
|
|
237
238
|
| `failure_class` | string \| null | Controlled vocabulary only, §3.3. `null` on a pass. |
|
|
238
239
|
| `prior_verdict` | string \| null | The Status cell value **before** this run wrote over it. `null` if the row is new. |
|
|
240
|
+
| `app_phase` | int | The phase whose checklist holds `req_id` and was written by this pass (added 2026-10-11, Sevak TF-005); see §2. Absent on older records. |
|
|
239
241
|
| `proof` | string \| null | Optional, §3.4. |
|
|
240
242
|
|
|
241
243
|
### 3.1 `attempt` — the field first-pass rate depends on entirely
|
|
@@ -281,7 +283,9 @@ Get this right; everything else on the record is secondary.
|
|
|
281
283
|
|
|
282
284
|
### 3.3 `failure_class` — controlled vocabulary, no free text
|
|
283
285
|
|
|
284
|
-
`blank-data` · `zero-rows` · `overlap` · `clipped` · `offscreen` · `slow-ttfb` · `slow-load` · `timeout` · `exception` · `assert-fail` · `naming` · `build-error` · `missing-asset` · `mockup-drift` · `other`
|
|
286
|
+
`blank-data` · `zero-rows` · `overlap` · `clipped` · `offscreen` · `low-contrast` · `light-surface` · `slow-ttfb` · `slow-load` · `timeout` · `exception` · `assert-fail` · `naming` · `build-error` · `missing-asset` · `mockup-drift` · `other`
|
|
287
|
+
|
|
288
|
+
`low-contrast` and `light-surface` (added 2026-10-07, Lekhak TF-024) are visual findings: text below the contrast floor against the colour painted behind it, in either theme, and a large light panel in dark mode. The ratio and the colours stay in the run JSON and the Remark.
|
|
285
289
|
|
|
286
290
|
`missing-asset` (added 2026-08-31) names an asset the page **declared** and never received — a 404, a non-200, or a 200 with an empty body on a `<link rel=stylesheet>` or `<script src>`. It says only that; **never** the URL, which is a file path inside the app and is exactly what constraint 7 keeps out of these streams. The path belongs in the checklist Remark a human reads.
|
|
287
291
|
|
|
@@ -659,6 +663,10 @@ The stream is for scripts. The owner reads `docs/<App>-Misses.md`: one row per `
|
|
|
659
663
|
|
|
660
664
|
`tf-emit.sh` rebuilds the file and its HTML through `tf-misses-md.py` after **every** write to the misses stream, whichever door wrote it (log-miss, triage, fix-close, a hand-written record, an amend), so the file is never older than the record. It is **derived**: nothing reads it, nobody edits it, and a wrong row is corrected by a new record. A project whose stream predates the script gets the file by running `bash .tfcore/utils/tf-misses-md.sh` once. The check for FR-31 is in `tests/bugs/run.sh`: the row count equals the record count.
|
|
661
665
|
|
|
666
|
+
### 5.5.11 `kind: "miss-void"` — withdrawing a miss that should never have been written (added 2026-09-22, TrBlazeUI TF-001)
|
|
667
|
+
|
|
668
|
+
§2.7's `run-void`, for this stream. Fields: `miss_id` (the miss withdrawn) and `reason`. Written only by `bash .tfcore/utils/tf-emit.sh --void-miss <miss_id> "<reason>"`, which refuses a miss not on the stream, a second void and an empty reason. Readers: the miss leaves every figure with its fixes and amends (`misses_voided_n`, `misses_voided`; an orphan is `miss_voids_orphaned_n`), `--open-miss` and `--open-misses` skip it, and `docs/<App>-Misses.md` lists it under *Withdrawn*. Proved by `tests/regression/run.sh tb_001`.
|
|
669
|
+
|
|
662
670
|
## 6. Provenance — three separations, one rule applied three times
|
|
663
671
|
|
|
664
672
|
**Data from different provenances never merges.**
|
|
@@ -90,13 +90,14 @@ detect_type() {
|
|
|
90
90
|
# docs: a markdown/spec repo — no source at all
|
|
91
91
|
[[ -z "$projects" ]] && { echo docs; return; }
|
|
92
92
|
|
|
93
|
+
# ($projects is never empty here, so xargs always has input: no GNU-only -r needed.)
|
|
93
94
|
# Packable = genuinely published. IsPackable is usually <IsPackable>false</IsPackable>
|
|
94
95
|
# on test projects, so only an explicit `true` counts.
|
|
95
|
-
packable="$(printf '%s\n' "$projects" | xargs
|
|
96
|
+
packable="$(printf '%s\n' "$projects" | xargs grep -lE \
|
|
96
97
|
'<(PackageId>|GeneratePackageOnBuild>[[:space:]]*true|IsPackable>[[:space:]]*true)' 2>/dev/null)"
|
|
97
98
|
|
|
98
99
|
# A shipped executable/hostable head: console/desktop (Exe), MAUI, or ASP.NET/Blazor host.
|
|
99
|
-
heads="$(printf '%s\n' "$projects" | xargs
|
|
100
|
+
heads="$(printf '%s\n' "$projects" | xargs grep -lE \
|
|
100
101
|
'<OutputType>[[:space:]]*Exe|<UseMaui>[[:space:]]*true|Sdk="Microsoft\.NET\.Sdk\.(Web|BlazorWebAssembly)"' 2>/dev/null)"
|
|
101
102
|
|
|
102
103
|
# THE DECIDING TEST: is a packaged project the product, or merely a helper?
|
|
@@ -375,6 +375,11 @@ def analyse_misses(misses):
|
|
|
375
375
|
|
|
376
376
|
Raw counts and the miss-class distribution ARE poolable: a miss counts as a miss
|
|
377
377
|
whoever missed it; only its attribution is confidence-bounded."""
|
|
378
|
+
# a miss withdrawn by a miss-void leaves every figure, with its fixes and amends (§5.5.11)
|
|
379
|
+
voids = {m.get("miss_id"): m for m in misses if m.get("kind") == "miss-void"}
|
|
380
|
+
ids = {m.get("miss_id") for m in misses if m.get("kind") == "miss"}
|
|
381
|
+
voided = ["%s — %s" % (k, v.get("reason") or "no reason recorded") for k, v in voids.items() if k in ids]
|
|
382
|
+
misses = [m for m in misses if m.get("miss_id") not in voids or m.get("kind") == "review"]
|
|
378
383
|
opened = [m for m in misses if m.get("kind") == "miss" and not m.get("backfilled")]
|
|
379
384
|
fixes = [m for m in misses if m.get("kind") == "miss-fix" and not m.get("backfilled")]
|
|
380
385
|
amends = [m for m in misses if m.get("kind") == "miss-amend"]
|
|
@@ -566,6 +571,9 @@ def analyse_misses(misses):
|
|
|
566
571
|
"resolved_misses": len(resolved),
|
|
567
572
|
"amendments_applied": amended,
|
|
568
573
|
"orphan_amends": orphan_amends,
|
|
574
|
+
"misses_voided_n": len(voided),
|
|
575
|
+
"misses_voided": voided,
|
|
576
|
+
"miss_voids_orphaned_n": len(voids) - len(voided),
|
|
569
577
|
# Denominator is records that CARRY the field — why_missed is optional (§5.5.6)
|
|
570
578
|
# and a missing value means "not assessed", never a zero for some category —
|
|
571
579
|
# AND records that COULD have carried it: one written before 2026-08-28 had no
|
|
@@ -1243,8 +1251,17 @@ def analyse(repos):
|
|
|
1243
1251
|
voided_runs = 0
|
|
1244
1252
|
void_reasons = []
|
|
1245
1253
|
void_orphans = 0
|
|
1254
|
+
gates_malformed = []
|
|
1246
1255
|
for repo in repos:
|
|
1247
1256
|
g = read_stream(repo, "gates")
|
|
1257
|
+
# A gate record is one REQ verdict (SCHEMA.md §3). A suite-level note with no req_id or no
|
|
1258
|
+
# verdict ({"gate":"verify-suite","result":"pass"}) was counted as a failure, passes
|
|
1259
|
+
# included (Lekhak TF-020). It is scored nowhere and listed as malformed instead.
|
|
1260
|
+
bad_g = [x for x in g if not x.get("req_id") or not x.get("verdict")]
|
|
1261
|
+
if bad_g:
|
|
1262
|
+
g = [x for x in g if x.get("req_id") and x.get("verdict")]
|
|
1263
|
+
gates_malformed += [{"app": app_name(repo), "ts": x.get("ts"), "gate": x.get("gate"),
|
|
1264
|
+
"result": x.get("result")} for x in bad_g]
|
|
1248
1265
|
r, vn, vr, vo = apply_voids(read_stream(repo, "runs"), app_name(repo))
|
|
1249
1266
|
voided_runs += vn; void_reasons += vr; void_orphans += vo
|
|
1250
1267
|
repo_misses = read_stream(repo, "misses")
|
|
@@ -1265,9 +1282,10 @@ def analyse(repos):
|
|
|
1265
1282
|
per_repo.append({"repo": repo, "app": app_name(repo),
|
|
1266
1283
|
"project_type": project_type(repo)[0],
|
|
1267
1284
|
"gates": len(g), "gates_backfilled": sum(1 for x in g if x.get("backfilled")),
|
|
1285
|
+
"gates_malformed": len(bad_g),
|
|
1268
1286
|
"runs": len(r), "sessions": len(s), "commits": len(c),
|
|
1269
|
-
"misses": sum(1 for x in
|
|
1270
|
-
if
|
|
1287
|
+
"misses": sum(1 for x in repo_misses if x.get("kind") == "miss" and x.get("miss_id") not in
|
|
1288
|
+
{v.get("miss_id") for v in repo_misses if v.get("kind") == "miss-void"}),
|
|
1271
1289
|
# A repo reclassified after records were written (most often a
|
|
1272
1290
|
# greenfield project born `docs` and upgraded once it grew a head)
|
|
1273
1291
|
# keeps the OLD value on every existing record — append-only means
|
|
@@ -1330,6 +1348,8 @@ def analyse(repos):
|
|
|
1330
1348
|
"runs_voided_n": voided_runs,
|
|
1331
1349
|
"runs_voided": void_reasons,
|
|
1332
1350
|
"run_voids_orphaned_n": void_orphans,
|
|
1351
|
+
"gates_malformed_n": len(gates_malformed),
|
|
1352
|
+
"gates_malformed": gates_malformed,
|
|
1333
1353
|
"misses": analyse_misses(misses),
|
|
1334
1354
|
"phases": analyse_phases(runs)}
|
|
1335
1355
|
|
|
@@ -1438,6 +1458,13 @@ def print_report(a, repos):
|
|
|
1438
1458
|
print(" Commit telemetry is not being written here. Fix it for good with")
|
|
1439
1459
|
print(" update-framework.sh <repo>, or reconcile what is already in the log:")
|
|
1440
1460
|
print(" .tfcore/telemetry/tf-metrics.sh --backfill-commits <repo>")
|
|
1461
|
+
if a.get("gates_malformed"):
|
|
1462
|
+
print("")
|
|
1463
|
+
print(" ⚠ %d gate record(s) carry no req_id or no verdict, so they are not one REQ's"
|
|
1464
|
+
% a["gates_malformed_n"])
|
|
1465
|
+
print(" verdict and are left out of every figure below (SCHEMA.md §3):")
|
|
1466
|
+
for x in a["gates_malformed"]:
|
|
1467
|
+
print(" %s %s gate=%s result=%s" % (x["app"], x["ts"], x["gate"], x["result"]))
|
|
1441
1468
|
print("")
|
|
1442
1469
|
|
|
1443
1470
|
for label in ("live", "backfilled"):
|
|
@@ -1795,6 +1822,15 @@ def print_misses(m, W):
|
|
|
1795
1822
|
print(" tokens to apply the corrections : %s (n=%d)"
|
|
1796
1823
|
% (m["review_tokens_correct_mean"] if m["review_tokens_correct_mean"] is not None
|
|
1797
1824
|
else "insufficient data", m["review_tokens_correct_n"]))
|
|
1825
|
+
if m.get("misses_voided_n"):
|
|
1826
|
+
print(" withdrawn : %d miss(es) named by a miss-void, in no figure above:" % m["misses_voided_n"])
|
|
1827
|
+
for line in m["misses_voided"][:6]:
|
|
1828
|
+
print(" " + line)
|
|
1829
|
+
if m["misses_voided_n"] > 6:
|
|
1830
|
+
print(" ... and %d more" % (m["misses_voided_n"] - 6))
|
|
1831
|
+
if m.get("miss_voids_orphaned_n"):
|
|
1832
|
+
print(" ⚠ %d miss-void record(s) name no miss on this stream — nothing was excluded for them"
|
|
1833
|
+
% m["miss_voids_orphaned_n"])
|
|
1798
1834
|
if m["orphan_amends"]:
|
|
1799
1835
|
print(" ⚠ %d miss-amend record(s) name no known miss, or a field outside the"
|
|
1800
1836
|
% m["orphan_amends"])
|
|
@@ -20,11 +20,13 @@
|
|
|
20
20
|
| Q5 | Logging | Serilog, always, with file logging wired at startup before anything else can fail. | No |
|
|
21
21
|
| Q6 | Tests | xUnit, always. A test project exists from day-1. | No |
|
|
22
22
|
| Q7 | Layout and naming | `src/` and `tests/` at the root. The primary executable project is named exactly `<App>`; `<App>.App` is banned. Secondary heads take a descriptive suffix (`<App>.Api`, `<App>.Desktop`). | No |
|
|
23
|
-
| Q8 | User interface | TrBlazeUI for every Blazor head and every MAUI Blazor Hybrid head. Native controls for WinForms, WPF and non-Blazor MAUI heads. Rendering mode is chosen per project and recorded. | Rendering mode only |
|
|
23
|
+
| Q8 | User interface | TrBlazeUI for every Blazor head and every MAUI Blazor Hybrid head: NuGet package `TrBlazeUI.Components` (it brings `TrBlazeUI.Primitives`), icons from `TrBlazeUI.Icons.Lucide`. Native controls for WinForms, WPF and non-Blazor MAUI heads. Rendering mode is chosen per project and recorded. | Rendering mode only |
|
|
24
24
|
| Q9 | Hosting | Web applications run containerised on a Bluehost VPS. The owner supplies a pipeline guidance document at UAT go-ahead, and a deployment checklist is produced from it. | Asked at UAT go-ahead, as the questionnaire specifies |
|
|
25
25
|
| Q10 | Production secrets | Decided when the owner asks for the production pipeline, after UAT. Until then no document states where production secrets live. | Asked after UAT |
|
|
26
26
|
| Q11 | Standing rules and prohibitions | 1. Never add a NuGet package without a line in the Architecture document saying why. 2. Never create a second configuration mechanism. 3. When TechieFlow, TrBlazeUI, TechieRag or any other internal library lacks something, record it in that library's feedback file and hold the feature until the library is fixed. Never implement a workaround. 4. Data access is always Dapper. 5. Database migrations live in a dedicated project named `<App>Db` (console or library) using the DbUp package. The web application runs the migration at startup, or the pipeline runs it after deployment. Never a `database` folder of loose scripts at the repository root. 6. Log files are written under the build output folder (`bin/`), which is git-ignored. Never at the repository root. 7. No unnecessary folders at the repository root (`data`, `database`, `scripts` and the like). Everything sits under `src/` or `tests/` according to what it belongs to. | No |
|
|
27
27
|
|
|
28
|
+
Required packages: `TrBlazeUI.Components` — for a project with a Blazor or MAUI Blazor Hybrid head. The Architecture copies this line into its Stack decisions for each package that applies, and `tf-stack-check.sh` fails the build check when no project file references one of them.
|
|
29
|
+
|
|
28
30
|
---
|
|
29
31
|
|
|
30
32
|
## Notes
|
|
@@ -58,3 +58,9 @@ If `/trblazeui` or `/techierag` is missing: run `dotnet build` (the NuGet target
|
|
|
58
58
|
Under Claude Code, if `/flow-master *render-workflow-docs <App>` returns "Unknown command", use `/TechieFlow:agents:flow-master *render-workflow-docs <App>` instead. (Under OpenCode `/flow-master` is the registered agent name — there is no fuller form to fall back to.)
|
|
59
59
|
|
|
60
60
|
After the agent is loaded, every TechieFlow-native agent (analyst, architect, flow-master, verifier) accepts `*command args` style invocations. trblazeui and techierag are free-form personas — normally `flow-master *build-phase <App>` calls them as sub-agents, but you can also drive them directly with prompts like `Implement REQ-UI-* from docs/<App>-Checklist.md to match the mockups in docs/mockups/.`
|
|
61
|
+
|
|
62
|
+
How to talk to me:
|
|
63
|
+
1. Rate your confidence. Tag any claim you are not sure of: [Certain] with evidence, [Likely] a strong inference, [Guessing] filling a gap. If most of a reply is guessing, say so in the first line.
|
|
64
|
+
2. Uncomfortable answer first. If there is something I will not want to hear, it is the first sentence, not the third paragraph.
|
|
65
|
+
3. No warm-up. No "great question", no "there are several ways to look at this", no restating my question. Start with the most useful sentence.
|
|
66
|
+
4. Disagree with structure: "I disagree because [reason]. I would do [alternative]. The risk in your approach is [downside]." Then do what I decide.
|
|
@@ -22,6 +22,9 @@ rule: decisions-log
|
|
|
22
22
|
<!-- Authoring notes (agent only; never visible text).
|
|
23
23
|
Sections and order are fixed by the schema above. The Stack decisions table answers the stack
|
|
24
24
|
questions (.tfcore/templates/stack-questions.md); answers taken from an answer set cite it.
|
|
25
|
+
The "Required packages:" line copies the answer set's own line, keeping only the packages that
|
|
26
|
+
apply to this project's heads; tf-stack-check.sh fails the build check when the code references
|
|
27
|
+
none of a listed package (a model once replaced the mandated UI library with plain components).
|
|
25
28
|
No Deployment section: hosting is decided after UAT and lives in the Deployment Checklist; how a
|
|
26
29
|
developer runs the app lives in the UsageGuide. Detailed per-screen flows live in the DevGuide.
|
|
27
30
|
A brownfield project describes the code as it is; a planned change is a Decisions log row with
|
|
@@ -54,6 +57,8 @@ One row per stack question. "Source" says where the answer came from: the answer
|
|
|
54
57
|
| Q8 | User interface | {…} | {…} |
|
|
55
58
|
| Q11 | Standing rules | {…} | {…} |
|
|
56
59
|
|
|
60
|
+
Required packages: {each package the answer set requires for this project's heads, in backticks, or "none"}
|
|
61
|
+
|
|
57
62
|
## 2. Solution structure
|
|
58
63
|
|
|
59
64
|
| Project | Kind | Purpose |
|