@techierathore/techieflow 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/TechieFlow/agents/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/_smoke-test-policy.md +7 -5
- package/.claude/commands/TechieFlow/tasks/_yolo-mode.md +2 -2
- package/.claude/commands/TechieFlow/tasks/amend-docs.md +1 -1
- package/.claude/commands/TechieFlow/tasks/day1-brownfield.md +2 -2
- package/.claude/commands/TechieFlow/tasks/day1-greenfield.md +4 -4
- package/.claude/commands/TechieFlow/tasks/develop-end-to-end.md +30 -0
- package/.claude/commands/TechieFlow/tasks/fix-issues.md +1 -0
- package/.claude/commands/TechieFlow/tasks/mockups.md +1 -1
- package/.claude/commands/TechieFlow/tasks/triage-and-fix.md +2 -2
- package/.claude/commands/TechieFlow/tasks/verify-phase.md +12 -11
- package/.opencode/plugin/techieflow.js +15 -7
- 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 +25 -2
- package/.tfcore/hooks/guard-db.sh +106 -9
- package/.tfcore/hooks/guard-status-html.sh +5 -1
- package/.tfcore/hooks/guard-verify-deps.sh +16 -1
- 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/tasks/_develop-mode.md +34 -0
- package/.tfcore/tasks/_smoke-test-policy.md +7 -5
- package/.tfcore/tasks/_yolo-mode.md +2 -2
- package/.tfcore/tasks/amend-docs.md +1 -1
- package/.tfcore/tasks/day1-brownfield.md +2 -2
- package/.tfcore/tasks/day1-greenfield.md +4 -4
- package/.tfcore/tasks/develop-end-to-end.md +30 -0
- package/.tfcore/tasks/fix-issues.md +1 -0
- package/.tfcore/tasks/mockups.md +1 -1
- package/.tfcore/tasks/triage-and-fix.md +2 -2
- package/.tfcore/tasks/verify-phase.md +12 -11
- package/.tfcore/telemetry/SCHEMA.md +6 -2
- package/.tfcore/telemetry/tf-metrics.sh +19 -0
- package/.tfcore/templates/stack-defaults/dotnet.md +5 -1
- package/.tfcore/templates/v4custom/app-architecture-tmpl.md +5 -0
- package/.tfcore/templates/v4custom/app-brd-tmpl.md +2 -1
- package/.tfcore/templates/v4custom/app-checklist-tmpl.md +11 -0
- package/.tfcore/templates/v4custom/app-phases-tmpl.md +2 -1
- package/.tfcore/templates/v4custom/app-usageguide-tmpl.md +4 -1
- package/.tfcore/templates/v4custom/html-render-shell.md +2 -0
- package/.tfcore/utils/__pycache__/tf-checklist-edit.cpython-312.pyc +0 -0
- 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-brd-status.py +10 -1
- package/.tfcore/utils/tf-build-list.py +16 -1
- package/.tfcore/utils/tf-build.sh +75 -0
- package/.tfcore/utils/tf-checklist-edit.py +28 -3
- package/.tfcore/utils/tf-day1-files.py +55 -28
- package/.tfcore/utils/tf-develop.sh +264 -0
- package/.tfcore/utils/tf-devguide-list.py +6 -2
- package/.tfcore/utils/tf-doc-check.py +124 -21
- package/.tfcore/utils/tf-doc-tests.sh +40 -3
- package/.tfcore/utils/tf-emit.sh +40 -10
- package/.tfcore/utils/tf-fix-close.sh +13 -7
- package/.tfcore/utils/tf-maccatalyst-check.sh +92 -0
- package/.tfcore/utils/tf-menus.mjs +401 -0
- package/.tfcore/utils/tf-mockup-parity.mjs +361 -28
- package/.tfcore/utils/tf-mockup-parity.sh +14 -3
- package/.tfcore/utils/tf-owner-text.py +27 -5
- package/.tfcore/utils/tf-phase.sh +24 -4
- package/.tfcore/utils/tf-render-html.py +19 -3
- package/.tfcore/utils/tf-req-ids.py +36 -0
- package/.tfcore/utils/tf-stack-check.sh +3 -0
- package/.tfcore/utils/tf-status-facts.py +90 -15
- package/.tfcore/utils/tf-theme.mjs +189 -0
- package/.tfcore/utils/tf-triage.py +30 -4
- package/.tfcore/utils/tf-verify-boot.sh +296 -21
- package/.tfcore/utils/tf-verify-emit.sh +37 -17
- package/.tfcore/utils/tf-verify-list.py +219 -20
- 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 +184 -20
- package/.tfcore/utils/tf-verify-screens.sh +17 -4
- package/.tfcore/utils/tf-verify-tests.sh +107 -17
- package/.tfcore/utils/tf-verify-verdict.py +118 -15
- 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_feedback.py +86 -18
- package/.tfcore/utils/tf_stack_check.py +93 -0
- package/README.md +2 -2
- package/opencode.jsonc +6 -2
- package/package.json +1 -1
- package/scripts/install.mjs +14 -3
- 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
|
@@ -17,6 +17,7 @@ Each rule lives in one place; these lines only point at it.
|
|
|
17
17
|
- Run to completion in YOLO or goal mode: `.tfcore/tasks/_yolo-mode.md`. `*build-phase` is in it by default.
|
|
18
18
|
- Run the application yourself and never ask the owner to boot or test anything: `.tfcore/tasks/_smoke-test-policy.md`, with `bash .tfcore/utils/tf-build.sh` for building on any host.
|
|
19
19
|
- A smoke is not a verify. `Verified` is written only by an executed `*verify`; the hook refuses it otherwise. Your ceiling as a builder is `Implemented`.
|
|
20
|
+
- A next command you name is the one `tf-status-facts.sh` printed, phase included. Rows waiting in another phase's checklist get `*verify {scope} {App} --phase N`, or `--phase all` when several phases wait; a bare `*verify` grades `appPhase` only.
|
|
20
21
|
- Analyse is not fix. A bug reported without a request to fix it is `*triage-issues`, documents only. Code changes come only from `*build-phase` and `*fix-issues`.
|
|
21
22
|
- A miss is a record. When the owner says something was missed, `*log-miss` writes it to the miss stream in seconds. Never argue, never guess who caused it; the emitter resolves that.
|
|
22
23
|
- Git is manual and the hook refuses it. Evidence is the checklist and the files on disk.
|
|
@@ -25,6 +26,7 @@ Each rule lives in one place; these lines only point at it.
|
|
|
25
26
|
|
|
26
27
|
| Command | What it does | Task file |
|
|
27
28
|
|---|---|---|
|
|
29
|
+
| `*develop-end-to-end {App} {brief}` | a new app from a brief to UAT, unattended: Day 1, build and verify, handoff; commits and pushes each phase; reports time and tokens per phase (greenfield only) | `develop-end-to-end.md` |
|
|
28
30
|
| `*build-phase {App}` | builds every open row of the phase's checklist, smokes, chains the verifier, fixes what fails | `build-phase.md` |
|
|
29
31
|
| `*fix-issues {App} {folder}` | reproduces reported bugs from screenshots and notes, fixes, re-verifies | `fix-issues.md` |
|
|
30
32
|
| `*triage-issues {App} {evidence} [verify]` | reproduces and logs reported bugs; no code | `triage-issues.md` |
|
|
@@ -7,7 +7,7 @@ Vidur, the TechieFlow verifier (icon 🔍): the one persona that proves whether
|
|
|
7
7
|
- A command starts with `*`. `*verify` maps to `.tfcore/tasks/verify-phase.md`; read that file when the command is typed, not before. Read `.tfcore/core-config.yaml` first for the app name, size, kind and phase.
|
|
8
8
|
- On activation, say who you are and print the command table below once. `*help` prints it again.
|
|
9
9
|
- The task begins with `bash .tfcore/utils/tf-phase.sh start verify-phase <App>` and ends with the status gate (`.tfcore/tasks/_status-update-gate.md`) and one run record.
|
|
10
|
-
- "verify the UI" is `*verify ui`, "check everything" is `*verify all`, "re-check these rows" is `*verify REQ-UI-004,REQ-FN-011`. When the scope is unclear, ask once.
|
|
10
|
+
- "verify the UI" is `*verify ui`, "check everything" is `*verify all`, "re-check these rows" is `*verify REQ-UI-004,REQ-FN-011`, "verify phase 1" is `*verify all {App} --phase 1`, "every phase" is `--phase all`. When the scope is unclear, ask once.
|
|
11
11
|
|
|
12
12
|
## Standing rules
|
|
13
13
|
|
|
@@ -26,7 +26,7 @@ Each rule lives in one place; these lines only point at it.
|
|
|
26
26
|
|
|
27
27
|
| Command | What it does | Task file |
|
|
28
28
|
|---|---|---|
|
|
29
|
-
| `*verify {scope} {App}` | boots the app, runs the seven checks on every row in scope, writes the verdicts and the telemetry | `verify-phase.md` |
|
|
29
|
+
| `*verify {scope} {App} [--phase N\|all]` | boots the app, runs the seven checks on every row in scope of that phase's checklist (default `appPhase`; `all` is each phase in turn, phase 1 first), writes the verdicts and the telemetry | `verify-phase.md` |
|
|
30
30
|
| `*report {scope} {App}` | prints the current Status and Remarks of the rows in scope from the checklist, without running anything | |
|
|
31
31
|
| `*help` | prints this table | |
|
|
32
32
|
| `*exit` | leaves the persona | |
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# _develop-mode (shared rule — *develop-end-to-end: a brief to a UAT-ready app, nobody asked)
|
|
2
|
+
|
|
3
|
+
Develop mode is on while `.tfcore/.session/develop.json` exists. `tf-develop.sh` writes it when `*develop-end-to-end` starts and removes it when the run ends. Everything in `_yolo-mode.md` applies, and on top of it:
|
|
4
|
+
|
|
5
|
+
## What changes
|
|
6
|
+
|
|
7
|
+
- **No question to the owner, ever.** Every question a task would ask is answered here, or by the brief (`docs/{App}-Brief.md`), or decided by you. A decision the owner would normally make is written down where the owner will see it: in the Architecture's Stack Decisions, or in the document it belongs to, under a line starting `Decided in develop mode:`, with one reason. Never stop to ask, and never write `done blocked` for a question you could decide.
|
|
8
|
+
- **The mockups are yours.** In this command you drew them on Day 1, so a difference between a mockup and what the stack mandates (a library's own control, a required layout) is never an owner decision: redraw the mockup to match the mandated component, write `Decided in develop mode:` with the reason in the UIDesign, re-render it, and verify again. The same for any document you wrote in this run. Only a thing the owner alone can supply is a blocker.
|
|
9
|
+
- **No owner-review stop.** This is the one command that crosses the reviews: `*day1-greenfield` stage 1 ends without "review them, then run --stage2"; the supervisor starts stage 2 itself. Everything else about each stage is unchanged.
|
|
10
|
+
- **Git is the supervisor's.** `tf-develop.sh` commits and pushes after each phase from its own shell. You still never run a git write: the guard is unchanged, and you do not need to.
|
|
11
|
+
|
|
12
|
+
## Day 1 answers
|
|
13
|
+
|
|
14
|
+
| Question in `day1-greenfield.md` | Answer in develop mode |
|
|
15
|
+
|---|---|
|
|
16
|
+
| 1. The app name | `{App}` from `develop.json` |
|
|
17
|
+
| 2. The concept | `docs/{App}-Brief.md`, all of it |
|
|
18
|
+
| 3. Hints | none, unless the brief names notes or mockups to harvest |
|
|
19
|
+
| 4. The stack | the stack the brief names; when it names none, the owner's answer set under `.tfcore/templates/stack-defaults/` (the one `core-config.yaml` names, or the only one there). Each question that answer set leaves open is decided as below, and every answer is written into the Architecture's Stack Decisions |
|
|
20
|
+
| 5. The size | the size you propose from your count; a Large brief is built as its phase 1 only, and the other phases are listed in the Build Report as not built |
|
|
21
|
+
|
|
22
|
+
Questions an answer set commonly leaves open:
|
|
23
|
+
|
|
24
|
+
- **Authentication.** The mechanism the brief names. When it names none: the app's own sign-in with local accounts, stored in the app's database; a shared identity platform needs credentials an unattended run does not have.
|
|
25
|
+
- **Rendering or hosting model of the UI.** The one the brief implies; otherwise the answer set's first choice.
|
|
26
|
+
- **Hosting and production secrets.** Not asked: they belong after UAT.
|
|
27
|
+
|
|
28
|
+
## The database
|
|
29
|
+
|
|
30
|
+
When the Architecture names a database server and none is reachable, create it locally and continue: a container named `{app}-db` (lower case) on a free port, with a development password kept in the app's development secrets, never in a committed file. Write the connection details into the UsageGuide's setup section. Create the schema only through the migration path the Stack Decisions name, during `*build-phase` (the database guard allows it there). This overrides the answer set's "never creates its own database container" for this command only.
|
|
31
|
+
|
|
32
|
+
## What does not change
|
|
33
|
+
|
|
34
|
+
The status gate, the smoke policy, the verifier's checks and the guard hooks. A row is `Verified` only from an executed verify. A thing only the owner can supply (a paid account, a device, a credential for a third-party service the brief requires) is still a blocker: finish everything else first, list it under PROJECT-STATUS "Known blockers", then `done blocked`.
|
|
@@ -12,23 +12,25 @@ A screen passes only if all three hold, at a desktop width and a mobile width:
|
|
|
12
12
|
|
|
13
13
|
A failure on any of the three is a defect: write it into the row's Remarks (prefix `⚠ visual:` for 2 and 3) and do not report the row done. A smoke earns a row at most `Implemented`; only an executed verify run writes `Verified`.
|
|
14
14
|
|
|
15
|
-
The evidence of a smoke is the file `bash .tfcore/utils/tf-verify-screens.sh --screen <name>=<route> … --base <url>` writes (`tests/.artifacts/verify/screens.json`, with a screenshot per screen and width); a row is written `Implemented` only after that run, and its Remark names the file. The application is booted with `bash .tfcore/utils/tf-verify-boot.sh start`, which also drives
|
|
15
|
+
The evidence of a smoke is the file `bash .tfcore/utils/tf-verify-screens.sh --screen <name>=<route> … --base <url>` writes (`tests/.artifacts/verify/screens.json`, with a screenshot per screen and width); a row is written `Implemented` only after that run, and its Remark names the file. The application is booted with `bash .tfcore/utils/tf-verify-boot.sh start`, which also drives a Windows head; a head the script cannot boot leaves the row below `Implemented` with the reason.
|
|
16
16
|
|
|
17
17
|
## Run it yourself
|
|
18
18
|
|
|
19
|
-
The build ladder (`.tfcore/templates/v4custom/build-invocation-ladder.md`) says how to build, run and reach the running UI on every supported host, including native and mobile heads. Follow it.
|
|
19
|
+
The build ladder (`.tfcore/templates/v4custom/build-invocation-ladder.md`) says how to build, run and reach the running UI on every supported host, including native and mobile heads. Follow it. Start a dependent service that is down, from its own configuration, in dependency order. Ask the owner to run something only after the ladder's last rung has failed, and then still run the smoke yourself once they answer.
|
|
20
20
|
|
|
21
21
|
## Test users
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Take credentials from the first that works:
|
|
24
24
|
|
|
25
25
|
1. The Test users table in `docs/<App>-UsageGuide.md`.
|
|
26
|
-
2. An existing account in the database, read with the connection string
|
|
26
|
+
2. An existing account in the database, read with the configured connection string.
|
|
27
27
|
3. Ask the owner, showing what you would create.
|
|
28
|
-
4. Only after a yes, create it and add it to the
|
|
28
|
+
4. Only after a yes, create it and add it to the table.
|
|
29
29
|
|
|
30
30
|
Never invent a throwaway account.
|
|
31
31
|
|
|
32
|
+
An AppManager app skips steps 2 to 4 (stack answer Q4a): register through its register call, passwords in git-ignored secrets, never the owner's account.
|
|
33
|
+
|
|
32
34
|
## Say what ran
|
|
33
35
|
|
|
34
36
|
Name the exact command and where it ran: which host, which rung, focused tests or the full build, your own smoke or an executed verify. A green intermediate step is not a pass of the whole.
|
|
@@ -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,7 +18,7 @@ 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.
|
|
@@ -13,7 +13,7 @@ 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.
|
|
@@ -22,7 +22,7 @@ First, before anything else: `bash .tfcore/utils/tf-phase.sh start day1-brownfie
|
|
|
22
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,7 +16,7 @@ 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".
|
|
@@ -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.
|
|
@@ -11,5 +11,6 @@ First: `bash .tfcore/utils/tf-phase.sh start fix-issues {App}` prints the start
|
|
|
11
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
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.
|
|
@@ -11,7 +11,7 @@ First: `bash .tfcore/utils/tf-phase.sh start mockups {App}` prints the start tim
|
|
|
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
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.
|
|
@@ -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.
|
|
@@ -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.
|
|
@@ -96,6 +96,15 @@ const TechieFlowPlugin = async ({ directory, client }) => {
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
// A flag that expired or went away without `tf-yolo.sh off` leaves the never-ask permissions
|
|
100
|
+
// behind (the rewritten OpenCode config): put it back
|
|
101
|
+
// when the project opens and YOLO is off (tf-yolo.sh sync; owner, 2026-10-14).
|
|
102
|
+
try {
|
|
103
|
+
if (!yoloOn() && fs.existsSync(path.join(root, ".tfcore", ".session", "yolo-perms.json"))) {
|
|
104
|
+
spawnSync("bash", [path.join(root, ".tfcore", "utils", "tf-yolo.sh"), "sync"], { cwd: root, env: { ...process.env, TF_PROJECT_DIR: root }, timeout: 15000 })
|
|
105
|
+
}
|
|
106
|
+
} catch {}
|
|
107
|
+
|
|
99
108
|
// Returns the guard's stderr when the guard BLOCKS (exit 2), else null.
|
|
100
109
|
function guardBlocks(script, payload) {
|
|
101
110
|
try {
|
|
@@ -334,17 +343,16 @@ const TechieFlowPlugin = async ({ directory, client }) => {
|
|
|
334
343
|
}
|
|
335
344
|
},
|
|
336
345
|
|
|
337
|
-
// YOLO / goal mode (.tfcore/tasks/_yolo-mode.md): when the flag is on,
|
|
338
|
-
//
|
|
339
|
-
//
|
|
340
|
-
// hook — they are `deny` in the map and exit-2 in
|
|
341
|
-
// if the harness never calls permission.ask
|
|
346
|
+
// YOLO / goal mode (.tfcore/tasks/_yolo-mode.md): when the flag is on, every
|
|
347
|
+
// ask is approved — a delete, an edit, a web fetch, a folder outside the project
|
|
348
|
+
// — so nothing asks (owner, 2026-10-14; it approved shell asks only until then).
|
|
349
|
+
// Git WRITES never reach this hook — they are `deny` in the map and exit-2 in
|
|
350
|
+
// block-git.sh. Fail-open: if the harness never calls permission.ask (OpenCode 2),
|
|
351
|
+
// the config tf-yolo.sh rewrites (every ask made allow) does the same job.
|
|
342
352
|
"permission.ask": async (input, output) => {
|
|
343
353
|
try {
|
|
344
354
|
if (!active || !output) return
|
|
345
355
|
if (!yoloOn()) return
|
|
346
|
-
const type = String((input && input.type) || "")
|
|
347
|
-
if (type && type !== "bash") return
|
|
348
356
|
output.status = "allow"
|
|
349
357
|
} catch {}
|
|
350
358
|
},
|
|
@@ -17,6 +17,7 @@ Each rule lives in one place; these lines only point at it.
|
|
|
17
17
|
- Run to completion in YOLO or goal mode: `.tfcore/tasks/_yolo-mode.md`. `*build-phase` is in it by default.
|
|
18
18
|
- Run the application yourself and never ask the owner to boot or test anything: `.tfcore/tasks/_smoke-test-policy.md`, with `bash .tfcore/utils/tf-build.sh` for building on any host.
|
|
19
19
|
- A smoke is not a verify. `Verified` is written only by an executed `*verify`; the hook refuses it otherwise. Your ceiling as a builder is `Implemented`.
|
|
20
|
+
- A next command you name is the one `tf-status-facts.sh` printed, phase included. Rows waiting in another phase's checklist get `*verify {scope} {App} --phase N`, or `--phase all` when several phases wait; a bare `*verify` grades `appPhase` only.
|
|
20
21
|
- Analyse is not fix. A bug reported without a request to fix it is `*triage-issues`, documents only. Code changes come only from `*build-phase` and `*fix-issues`.
|
|
21
22
|
- A miss is a record. When the owner says something was missed, `*log-miss` writes it to the miss stream in seconds. Never argue, never guess who caused it; the emitter resolves that.
|
|
22
23
|
- Git is manual and the hook refuses it. Evidence is the checklist and the files on disk.
|
|
@@ -25,6 +26,7 @@ Each rule lives in one place; these lines only point at it.
|
|
|
25
26
|
|
|
26
27
|
| Command | What it does | Task file |
|
|
27
28
|
|---|---|---|
|
|
29
|
+
| `*develop-end-to-end {App} {brief}` | a new app from a brief to UAT, unattended: Day 1, build and verify, handoff; commits and pushes each phase; reports time and tokens per phase (greenfield only) | `develop-end-to-end.md` |
|
|
28
30
|
| `*build-phase {App}` | builds every open row of the phase's checklist, smokes, chains the verifier, fixes what fails | `build-phase.md` |
|
|
29
31
|
| `*fix-issues {App} {folder}` | reproduces reported bugs from screenshots and notes, fixes, re-verifies | `fix-issues.md` |
|
|
30
32
|
| `*triage-issues {App} {evidence} [verify]` | reproduces and logs reported bugs; no code | `triage-issues.md` |
|
|
@@ -7,7 +7,7 @@ Vidur, the TechieFlow verifier (icon 🔍): the one persona that proves whether
|
|
|
7
7
|
- A command starts with `*`. `*verify` maps to `.tfcore/tasks/verify-phase.md`; read that file when the command is typed, not before. Read `.tfcore/core-config.yaml` first for the app name, size, kind and phase.
|
|
8
8
|
- On activation, say who you are and print the command table below once. `*help` prints it again.
|
|
9
9
|
- The task begins with `bash .tfcore/utils/tf-phase.sh start verify-phase <App>` and ends with the status gate (`.tfcore/tasks/_status-update-gate.md`) and one run record.
|
|
10
|
-
- "verify the UI" is `*verify ui`, "check everything" is `*verify all`, "re-check these rows" is `*verify REQ-UI-004,REQ-FN-011`. When the scope is unclear, ask once.
|
|
10
|
+
- "verify the UI" is `*verify ui`, "check everything" is `*verify all`, "re-check these rows" is `*verify REQ-UI-004,REQ-FN-011`, "verify phase 1" is `*verify all {App} --phase 1`, "every phase" is `--phase all`. When the scope is unclear, ask once.
|
|
11
11
|
|
|
12
12
|
## Standing rules
|
|
13
13
|
|
|
@@ -26,7 +26,7 @@ Each rule lives in one place; these lines only point at it.
|
|
|
26
26
|
|
|
27
27
|
| Command | What it does | Task file |
|
|
28
28
|
|---|---|---|
|
|
29
|
-
| `*verify {scope} {App}` | boots the app, runs the seven checks on every row in scope, writes the verdicts and the telemetry | `verify-phase.md` |
|
|
29
|
+
| `*verify {scope} {App} [--phase N\|all]` | boots the app, runs the seven checks on every row in scope of that phase's checklist (default `appPhase`; `all` is each phase in turn, phase 1 first), writes the verdicts and the telemetry | `verify-phase.md` |
|
|
30
30
|
| `*report {scope} {App}` | prints the current Status and Remarks of the rows in scope from the checklist, without running anything | |
|
|
31
31
|
| `*help` | prints this table | |
|
|
32
32
|
| `*exit` | leaves the persona | |
|
package/.tfcore/core-config.yaml
CHANGED
|
@@ -54,4 +54,5 @@ slashPrefix: TechieFlow
|
|
|
54
54
|
# url: http://192.168.1.50:4723 # the LAN Mac (stable IP via DHCP reservation); Appium bound to 0.0.0.0
|
|
55
55
|
# simulator: "iPhone 15"
|
|
56
56
|
# maccatalyst:
|
|
57
|
-
# url: http://
|
|
57
|
+
# url: http://localhost:4723 # this Mac (the default when unset); mac2 driver. tf-verify-boot.sh
|
|
58
|
+
# # starts a local Appium when none answers. A Blazor Hybrid Mac head is checked without control names.
|
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
# the only place that decides. Outside YOLO it returns permissionDecision=ask
|
|
22
22
|
# for them (same prompt the owner always had). In YOLO it stays silent and the
|
|
23
23
|
# bare "Bash" allow rule lets them run — an unattended goal run never stalls on
|
|
24
|
-
# a delete.
|
|
24
|
+
# a delete. A delete of the whole disk or home folder (rm -rf / , /* , ~ , ~/*)
|
|
25
|
+
# is refused here in every mode; settings.json deny keeps only the exact
|
|
26
|
+
# `rm -rf /` and `rm -rf ~` (a deny `*` matched every absolute path).
|
|
25
27
|
#
|
|
26
28
|
# YOLO is ON when any of: env TF_YOLO=1 · .tfcore/.session/yolo.json exists
|
|
27
29
|
# (tf-yolo.sh on) · the hook payload's permission_mode is bypassPermissions/auto.
|
|
@@ -198,6 +200,20 @@ def classify_gh(args):
|
|
|
198
200
|
found = {"read": 0, "write": 0}
|
|
199
201
|
found_rm = [False]
|
|
200
202
|
found_sudo = [False]
|
|
203
|
+
found_wipe = [False]
|
|
204
|
+
|
|
205
|
+
# A delete whose target is the whole disk or the home folder is refused in every mode. These
|
|
206
|
+
# lived in settings.json deny as "rm -rf /*" and "rm -rf ~/*", but a deny rule's * matches any
|
|
207
|
+
# text, so they also refused every delete of an absolute path (rm -rf /mnt/c/...), even in
|
|
208
|
+
# bypass mode (Lekhak scratch folder, 2026-10-18).
|
|
209
|
+
HOME_DIR = os.path.expanduser("~").rstrip("/")
|
|
210
|
+
WIPE = {"/", "/*", "/.", "/..", "~", "~/", "~/*", "~/.", "$HOME", "$HOME/", "$HOME/*",
|
|
211
|
+
"${HOME}", "${HOME}/", "${HOME}/*"}
|
|
212
|
+
def is_wipe(t):
|
|
213
|
+
t = t.strip()
|
|
214
|
+
if t in WIPE or re.fullmatch(r"/+\*?", t):
|
|
215
|
+
return True
|
|
216
|
+
return bool(HOME_DIR) and t.rstrip("/*") == HOME_DIR
|
|
201
217
|
|
|
202
218
|
def scan(cmdline, depth=0):
|
|
203
219
|
if depth > 4:
|
|
@@ -263,6 +279,8 @@ def scan(cmdline, depth=0):
|
|
|
263
279
|
found[classify_gh(args)] += 1
|
|
264
280
|
elif head in ("rm", "rmdir", "unlink", "shred"):
|
|
265
281
|
found_rm[0] = True
|
|
282
|
+
if any(is_wipe(a) for a in args if not a.startswith("-") or a == "-"):
|
|
283
|
+
found_wipe[0] = True
|
|
266
284
|
elif head in ("find",) and ("-delete" in args or "-exec" in args and any(basename(x) == "rm" for x in args)):
|
|
267
285
|
found_rm[0] = True
|
|
268
286
|
|
|
@@ -276,7 +294,9 @@ except Exception:
|
|
|
276
294
|
print("ALLOW")
|
|
277
295
|
sys.exit(0)
|
|
278
296
|
|
|
279
|
-
if
|
|
297
|
+
if found_wipe[0]:
|
|
298
|
+
print("BLOCK_WIPE")
|
|
299
|
+
elif found["write"]:
|
|
280
300
|
print("BLOCK_WRITE")
|
|
281
301
|
elif found["read"] and (strict_git or not yolo):
|
|
282
302
|
print("BLOCK_READ")
|
|
@@ -290,6 +310,9 @@ VERDICT="$(TF_HOOK_INPUT="$INPUT" TF_YOLO_ON="$YOLO" python3 -c "$GIT_GUARD_PY"
|
|
|
290
310
|
case "$VERDICT" in
|
|
291
311
|
BLOCK_WRITE) block_git_msg; exit 2 ;;
|
|
292
312
|
BLOCK_READ) block_read_msg; exit 2 ;;
|
|
313
|
+
BLOCK_WIPE)
|
|
314
|
+
echo "BLOCKED by TechieFlow policy: this deletes the whole disk or the home folder. Never run it, in any mode. Delete the folder you mean by its own path." >&2
|
|
315
|
+
exit 2 ;;
|
|
293
316
|
ASK_RM)
|
|
294
317
|
# Claude Code: surface the owner's usual delete/sudo prompt (hook "ask"
|
|
295
318
|
# beats the bare "Bash" allow). OpenCode: its own `rm *: ask` map prompts.
|