@manhquy/flow-skill 0.1.0-rc.3 → 0.1.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/CHANGELOG.md +12 -0
- package/README_VN.md +4 -2
- package/package.json +1 -1
- package/skills/flow/SKILL.md +2 -2
- package/skills/flow/harness/GAP-MATRIX-0.1.17.md +41 -0
- package/skills/flow/harness/README.md +37 -3
- package/skills/flow/harness/flow_harness.py +70 -1
- package/skills/flow/harness/pins/harness-cli-v0.1.17.sha256sums +9 -0
- package/skills/flow/references/agent-stage-mapping.md +1 -1
- package/skills/flow/references/auto-run.md +1 -1
- package/skills/flow/runner/flow.sh +77 -8
- package/skills-manifest.json +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@manhquy/flow-skill`. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning: [SemVer](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [0.1.0] — 2026-07-19 — GA (first stable, `latest`)
|
|
6
|
+
|
|
7
|
+
First stable release of the installer. Graduates the rc.1→rc.3 line after two live OIDC
|
|
8
|
+
publishes + independent verification; publishes to dist-tag **`latest`** so bare
|
|
9
|
+
`npx @manhquy/flow-skill` / `npm i` resolves it (no manual dist-tag promotion needed).
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Ships skill product **v0.24.0** (harness trust-align — honest `proof_source`, STRICT durable
|
|
13
|
+
modes, canonical harness skill; see root `CHANGELOG.md` `## 0.24.0`). rc.1–rc.3 shipped v0.22.0.
|
|
14
|
+
- No installer code change vs rc.3 — same CLI, detection, lock, and five install targets
|
|
15
|
+
(Claude, Codex, Antigravity, Cursor, universal `~/.agents/skills`).
|
|
16
|
+
|
|
5
17
|
## [0.1.0-rc.3] — 2026-07-18
|
|
6
18
|
|
|
7
19
|
Ships the same skill product **v0.22.0** as rc.2, plus pipeline/UX fixes found after the first
|
package/README_VN.md
CHANGED
|
@@ -10,13 +10,15 @@ Trình cài đặt một-lệnh sao chép skill [flow](https://github.com/manhqu
|
|
|
10
10
|
## Cài đặt
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
# Kênh pre-release (hiện tại — v0.1.0-rc.
|
|
13
|
+
# Kênh pre-release (hiện tại — v0.1.0-rc.3, ships skill v0.22.0)
|
|
14
14
|
npx @manhquy/flow-skill@rc
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
Prompt tương tác hỏi cài vào agent nào. Chọn một hoặc nhiều, xác nhận, xong.
|
|
18
18
|
|
|
19
|
-
> **Giai đoạn RC**: pin `@rc` (dist-tag) hoặc phiên bản cụ thể `@0.1.0-rc.
|
|
19
|
+
> **Giai đoạn RC**: pin `@rc` (dist-tag) hoặc phiên bản cụ thể `@0.1.0-rc.3`. `npx @manhquy/flow-skill@0.1.x` chỉ dùng được sau khi stable `0.1.0` publish — semver range **không** match pre-release theo mặc định. Xem [SECURITY.md](./SECURITY.md).
|
|
20
|
+
>
|
|
21
|
+
> **`npm i` alone chưa đủ** — phải **chạy** CLI (`npx @manhquy/flow-skill@rc`). Hai trục version: package npm vs skill product (`ships skill v…` / `skillVersion` trong JSONL).
|
|
20
22
|
|
|
21
23
|
## Non-interactive
|
|
22
24
|
|
package/package.json
CHANGED
package/skills/flow/SKILL.md
CHANGED
|
@@ -8,7 +8,7 @@ keywords: [flow, buildflow, gate, build, ship, scope, prd, contract, card, deplo
|
|
|
8
8
|
license: MIT
|
|
9
9
|
metadata:
|
|
10
10
|
author: flow-skill
|
|
11
|
-
version: "0.
|
|
11
|
+
version: "0.24.0"
|
|
12
12
|
attribution: "Methodology from ai20k-build-phase/buildflow (Tony, arealisticdreamer.com); harness/agent layers from repository-harness, claudekit-engineer, BMAD-METHOD. v0.22 concierge routing pattern adapted from BMAD-METHOD's bmad-help; forge-idea ritual adapted from BMAD-METHOD's bmad-forge-idea (both MIT, BMad Code LLC)."
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -235,7 +235,7 @@ Hard stops (iteration/token/time caps) and ground-truth gates (`flow.sh` exit, r
|
|
|
235
235
|
- `references/gate-eval.md` — `/flow eval` behavioral proof for the semantic layer: what it
|
|
236
236
|
measures (a fresh-judge lower bound, NOT the work-mode self-challenge), cost, thresholds,
|
|
237
237
|
and the honest authorship-bias limitation. Read before running or relaying a scorecard.
|
|
238
|
-
- `harness/` — durable layer (`flow.sh harness ...`): intake/story
|
|
238
|
+
- `harness/` — durable layer (`flow.sh harness ...`): intake/story/**complete**/trace/decision/backlog. Pins: protocol floor `harness-cli-v0.1.14`, trust CLI `0.1.17` (never `0.1.16`). See `harness/README.md` + `harness/GAP-MATRIX-0.1.17.md`. Never `story update --status implemented` — use `story complete --proof-source …`.
|
|
239
239
|
- `playbooks/` — paid-for stack knowledge: read before building a card on that stack, harvest the lesson after.
|
|
240
240
|
- `_templates/` — the 7 artifacts the runner copies into `flow/` and `cards/`. Never edit during a run.
|
|
241
241
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Gap matrix: flow durable layer vs repository-harness CLI 0.1.17
|
|
2
|
+
|
|
3
|
+
**Authority:** `repository-harness` (local `D:\project\flow\repository-harness`).
|
|
4
|
+
**Pins:** protocol floor **`harness-cli-v0.1.14`** · trust/consumer CLI **`harness-cli-v0.1.17`** · **never** install/use **`0.1.16`** release assets (tag without published proof).
|
|
5
|
+
**Scope:** inventory only — does **not** claim US-101 bit-identical or protocol-v1 parity for flow Python.
|
|
6
|
+
|
|
7
|
+
Supersedes: brainstorm 260703 Thread1 (“nothing to upgrade”).
|
|
8
|
+
|
|
9
|
+
## Schema
|
|
10
|
+
|
|
11
|
+
| Ver | Flow | Harness 0.1.17 | Notes |
|
|
12
|
+
|-----|------|----------------|-------|
|
|
13
|
+
| 001–004 | present (shared) | present | Hash-identical at last measure (2026-07-18) |
|
|
14
|
+
| 005 | present | present | File hash may differ on comments only — do not overclaim DDL fork |
|
|
15
|
+
| 006–008 | **absent** (reserved gap) | changesets / deps / hierarchy | Not adopted this plan |
|
|
16
|
+
| 009–012 | **usage/accessed** (flow-only) | improvement identity / links / closure | **Semantic collision** — same numbers, different DDL |
|
|
17
|
+
| 013 | absent | changeset content sha | Not adopted |
|
|
18
|
+
|
|
19
|
+
## Commands / invariants
|
|
20
|
+
|
|
21
|
+
| Surface | Flow status | Harness 0.1.17 | Trust note |
|
|
22
|
+
|---------|-------------|----------------|------------|
|
|
23
|
+
| `story update --status implemented` | rejected (trust-align) | rejected (US-101) | Use `story complete` |
|
|
24
|
+
| `story complete` | flow-native flags + honest `proof_source` | `story complete` + live verify | Flow may complete via `card_markdown_gate` **without** setting `last_verified_result=pass` |
|
|
25
|
+
| `story verify` | optional shell verify_command | required for shell-proven complete | shell=True = operator-authored only |
|
|
26
|
+
| `query sql` | **not exposed** | read-only connection | Do not add mutating SQL |
|
|
27
|
+
| Rust forward | refused on flow-lineage DB | n/a | `FLOW_HARNESS_BACKEND=rust` → exit 2 when usage mirror / schema≥9 |
|
|
28
|
+
| Changesets / work-graph | not ported | 006–013 | Out of scope (FOMO red line) |
|
|
29
|
+
| `query contract --json` | not on Python CLI | protocol v1 discovery | Optional external binary smoke only |
|
|
30
|
+
|
|
31
|
+
## Pins (consumer)
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
HARNESS_PROTOCOL_V1_TAG = harness-cli-v0.1.14 # floor
|
|
35
|
+
HARNESS_CLI_TRUST_TAG = harness-cli-v0.1.17 # trust features + release proof
|
|
36
|
+
DO_NOT_USE = harness-cli-v0.1.16 # no assets / failed promotion
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Rust refuse-forward
|
|
40
|
+
|
|
41
|
+
Any DB with `usage_event` or `MAX(schema_version) >= 9` is **flow-lineage**. Python entrypoint must refuse forwarding to external `harness-cli` (exit 2). Never unfreeze on `.flow/harness.db` without schema re-home ≥014 (separate epic).
|
|
@@ -2,10 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
The durable memory of `/flow`: intake classification, story packets with proof status,
|
|
4
4
|
auto-scored execution traces, decision records, and the growth-rule backlog. Ported from
|
|
5
|
-
`repository-harness` (
|
|
5
|
+
`repository-harness` (shared base schema + flow-only usage extensions). State lives at
|
|
6
6
|
`<project>/.flow/harness.db` and survives across sessions — this is the "external memory"
|
|
7
7
|
that fights context rot.
|
|
8
8
|
|
|
9
|
+
## Authority pins (repository-harness)
|
|
10
|
+
|
|
11
|
+
| Pin | Tag | Use |
|
|
12
|
+
|-----|-----|-----|
|
|
13
|
+
| Protocol floor | **`harness-cli-v0.1.14`** | protocol v1 discovery floor |
|
|
14
|
+
| Trust / consumer | **`harness-cli-v0.1.17`** | US-101 spirit + release proof |
|
|
15
|
+
| **Do not use** | `harness-cli-v0.1.16` | tag without published assets |
|
|
16
|
+
|
|
17
|
+
Gap inventory: [`GAP-MATRIX-0.1.17.md`](./GAP-MATRIX-0.1.17.md). Flow does **not** claim bit-identical US-101.
|
|
18
|
+
|
|
9
19
|
## Backends
|
|
10
20
|
|
|
11
21
|
| Backend | When | How |
|
|
@@ -23,12 +33,36 @@ power-path for non-flow DBs; flow does not build or ship the binary.
|
|
|
23
33
|
|
|
24
34
|
Disable the durable layer entirely with `FLOW_HARNESS_DISABLE=1` (engine still runs).
|
|
25
35
|
|
|
36
|
+
### STRICT durable writes (`flow.sh`)
|
|
37
|
+
|
|
38
|
+
| Env | Behavior |
|
|
39
|
+
|-----|----------|
|
|
40
|
+
| unset | soft: engine exit 0; one-line `flow-harness: warn` on fail |
|
|
41
|
+
| `FLOW_HARNESS_STRICT=1` | soft exit; louder stderr |
|
|
42
|
+
| `FLOW_HARNESS_STRICT=fail` | propagate nonzero from durable ops on card/check |
|
|
43
|
+
|
|
44
|
+
## Story completion (trust boundary)
|
|
45
|
+
|
|
46
|
+
- **Rejected:** `story update --status implemented`
|
|
47
|
+
- **Use:** `story complete --id <id> --proof-source card_markdown_gate|manual|verify_command [--evidence …]`
|
|
48
|
+
- `card_markdown_gate` / `manual` set status implemented with **honest** `proof_source=…` in notes — **never** forge `last_verified_result=pass`
|
|
49
|
+
- `verify_command` requires prior `story verify` pass
|
|
50
|
+
|
|
51
|
+
## Versioning (harness vs npm)
|
|
52
|
+
|
|
53
|
+
- Telemetry / usage events carry **`flow_version` from the installed skill product**
|
|
54
|
+
(`SKILL.md` metadata), not from the npm installer package version.
|
|
55
|
+
- When you change harness schema or CLI behavior, bump the **skill product** version
|
|
56
|
+
(SKILL.md + plugin.json + portable-manifest) and run `flow.sh coherence`.
|
|
57
|
+
- Publishing a new npm tarball is a separate step (`npm-wrapper` sync + tag `npm@…`) —
|
|
58
|
+
see [`docs/release-process.md`](../../../docs/release-process.md).
|
|
59
|
+
|
|
26
60
|
## Commands ↔ Runtime-Substrate responsibility
|
|
27
61
|
|
|
28
62
|
| Command | Responsibility (of 11) |
|
|
29
63
|
|---|---|
|
|
30
64
|
| `intake --type <t> --summary <s> [--flags ...] [--lane ...] [--narrow-scope]` | Task specification + risk classification |
|
|
31
|
-
| `story add\|update\|verify\|verify-all` | Task state + Verification (mechanical proof) |
|
|
65
|
+
| `story add\|update\|complete\|verify\|verify-all` | Task state + Verification (mechanical proof) |
|
|
32
66
|
| `trace --summary ... [--story\|--card C-NNN] [--agent ...] [--actions ...] [--files-changed ...] --outcome ...` | Observability + Failure attribution (auto-scored tier). Flags accept `-` or `_` (`--actions_taken`, `--files_changed`, `--files_read`) and `--card` is an alias of `--story`. A bad/missing flag prints a guiding "common forms" hint (not a silent exit-2). |
|
|
33
67
|
| `decision add\|verify\|outcome` | Project memory (durable ADR row + companion markdown); `outcome` closes the predicted-vs-actual loop |
|
|
34
68
|
| `backlog add\|close` | Entropy auditing + harness self-improvement (growth rule) |
|
|
@@ -60,7 +94,7 @@ Linking a trace to an unverified story prints a **pre-close gate** warning.
|
|
|
60
94
|
- `/flow next` past **stage 04 (ADR)** → reminds you to record each decision durably (`decision add`) — the ADR markdown is not a durable record.
|
|
61
95
|
- `/flow card` creates a card → seeds a `story` row (tracking handle).
|
|
62
96
|
- `/flow check C-NNN` (todo) → `story update --status in_progress`.
|
|
63
|
-
- `/flow check C-NNN` (done) → `story
|
|
97
|
+
- `/flow check C-NNN` (done) → `story complete --proof-source card_markdown_gate` + a `trace` (tier verdict shown; honest provenance, no shell-verify stamp).
|
|
64
98
|
- `/flow recall` → reads the durable layer back (friction + backlog + audit health) into your working context — the capture→reuse loop.
|
|
65
99
|
- `/flow retro` → surfaces `propose` (deterministic improvement proposals from repeated friction/interventions + audit drift) for you to commit.
|
|
66
100
|
- `/flow harness <args>` exposes the full CLI directly.
|
|
@@ -160,6 +160,21 @@ def cmd_intake(con, a):
|
|
|
160
160
|
return 0
|
|
161
161
|
|
|
162
162
|
|
|
163
|
+
_PROOF_SOURCES = ("card_markdown_gate", "manual", "verify_command")
|
|
164
|
+
_SECRET_RE = re.compile(
|
|
165
|
+
r"(?i)(token|secret|passwd|password|credential|api[_-]?key|bearer|authorization|-----begin)"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _mask_evidence(text):
|
|
170
|
+
"""Redact secret-shaped free text before durable store (trust-align RT)."""
|
|
171
|
+
if text is None:
|
|
172
|
+
return None
|
|
173
|
+
if _SECRET_RE.search(text):
|
|
174
|
+
return "***redacted***"
|
|
175
|
+
return text
|
|
176
|
+
|
|
177
|
+
|
|
163
178
|
def cmd_story(con, a):
|
|
164
179
|
if a.story_cmd == "add":
|
|
165
180
|
if a.lane not in D.LANES:
|
|
@@ -169,11 +184,58 @@ def cmd_story(con, a):
|
|
|
169
184
|
print(f"PASS: story {a.id} added (lane={a.lane})")
|
|
170
185
|
return 0
|
|
171
186
|
if a.story_cmd == "update":
|
|
187
|
+
# Trust boundary (US-101 spirit, flow-native): bare implemented is forbidden.
|
|
188
|
+
if a.status == "implemented":
|
|
189
|
+
print(
|
|
190
|
+
"FAIL: story update --status implemented is rejected.\n"
|
|
191
|
+
" Use: story complete --id <id> --proof-source card_markdown_gate|manual|verify_command\n"
|
|
192
|
+
" (honest proof provenance; never forge last_verified_result without story verify)"
|
|
193
|
+
)
|
|
194
|
+
return 1
|
|
172
195
|
n = _db.update(con, "story", "id", a.id, status=a.status,
|
|
173
196
|
unit_proof=a.unit, integration_proof=a.integration,
|
|
174
|
-
e2e_proof=a.e2e, platform_proof=a.platform,
|
|
197
|
+
e2e_proof=a.e2e, platform_proof=a.platform,
|
|
198
|
+
evidence=_mask_evidence(a.evidence))
|
|
175
199
|
print(f"{'PASS' if n else 'FAIL'}: story {a.id} {'updated' if n else 'not found'}")
|
|
176
200
|
return 0 if n else 1
|
|
201
|
+
if a.story_cmd == "complete":
|
|
202
|
+
s = _db.one(con, "SELECT * FROM story WHERE id=?", (a.id,))
|
|
203
|
+
if not s:
|
|
204
|
+
print(f"FAIL: story {a.id} not found"); return 1
|
|
205
|
+
src = (a.proof_source or "").strip()
|
|
206
|
+
if src not in _PROOF_SOURCES:
|
|
207
|
+
print(
|
|
208
|
+
"FAIL: --proof-source required: card_markdown_gate|manual|verify_command\n"
|
|
209
|
+
" card_markdown_gate = /flow check markdown gate (does NOT set last_verified=pass)\n"
|
|
210
|
+
" verify_command = requires prior story verify pass"
|
|
211
|
+
)
|
|
212
|
+
return 1
|
|
213
|
+
if src == "verify_command":
|
|
214
|
+
if s.get("last_verified_result") != "pass":
|
|
215
|
+
print(
|
|
216
|
+
f"FAIL: proof-source verify_command requires last_verified_result=pass "
|
|
217
|
+
f"(got {s.get('last_verified_result')!r}). Run: story verify --id {a.id}"
|
|
218
|
+
)
|
|
219
|
+
return 1
|
|
220
|
+
# Honest provenance: card/manual never forge last_verified_result=pass
|
|
221
|
+
ev = _mask_evidence(a.evidence) or s.get("evidence") or ""
|
|
222
|
+
note = (s.get("notes") or "").strip()
|
|
223
|
+
prov = f"proof_source={src}"
|
|
224
|
+
if prov not in note:
|
|
225
|
+
note = (note + "\n" + prov).strip() if note else prov
|
|
226
|
+
if src == "card_markdown_gate" and "last_verified_result=pass" not in (note or ""):
|
|
227
|
+
# explicit honesty marker for auditors
|
|
228
|
+
note = note + "\nverify_stamp=not_shell"
|
|
229
|
+
fields = dict(status="implemented", notes=note)
|
|
230
|
+
if ev:
|
|
231
|
+
fields["evidence"] = ev
|
|
232
|
+
# only keep last_verified_* when real verify already passed
|
|
233
|
+
n = _db.update(con, "story", "id", a.id, **fields)
|
|
234
|
+
print(
|
|
235
|
+
f"PASS: story {a.id} complete (status=implemented, proof_source={src})"
|
|
236
|
+
+ ("" if src == "verify_command" else " [no shell-verify stamp]")
|
|
237
|
+
)
|
|
238
|
+
return 0 if n else 1
|
|
177
239
|
if a.story_cmd in ("verify", "verify-all"):
|
|
178
240
|
if a.story_cmd == "verify":
|
|
179
241
|
stories = [_db.one(con, "SELECT * FROM story WHERE id=?", (a.id,))]
|
|
@@ -983,6 +1045,13 @@ def build_parser():
|
|
|
983
1045
|
a2.add_argument("--evidence")
|
|
984
1046
|
a3 = pss.add_parser("verify"); a3.add_argument("--id", required=True)
|
|
985
1047
|
pss.add_parser("verify-all")
|
|
1048
|
+
# flow-native complete (trust-align D7): not protocol-v1 positional parity
|
|
1049
|
+
ac = pss.add_parser("complete", help="mark implemented with honest proof_source (not bare update)")
|
|
1050
|
+
ac.add_argument("--id", required=True)
|
|
1051
|
+
ac.add_argument("--proof-source", dest="proof_source",
|
|
1052
|
+
choices=("card_markdown_gate", "manual", "verify_command"),
|
|
1053
|
+
help="card_markdown_gate never forges last_verified=pass")
|
|
1054
|
+
ac.add_argument("--evidence")
|
|
986
1055
|
|
|
987
1056
|
pt = sub.add_parser("trace", help="record an agent task execution trace (auto-scored)")
|
|
988
1057
|
pt.add_argument("--summary", required=True); pt.add_argument("--intake", type=int); pt.add_argument("--story", "--card")
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Digests from GitHub Release harness-cli-v0.1.17 (fetched for pin policy)
|
|
2
|
+
# TAG harness-cli-v0.1.17
|
|
3
|
+
# PROTOCOL_FLOOR harness-cli-v0.1.14
|
|
4
|
+
# DO_NOT_USE harness-cli-v0.1.16
|
|
5
|
+
5d13f0a024d9d69701534a879581c9433bc0069e04d052e5aacd93b91b3b7a43 harness-cli-linux-x64
|
|
6
|
+
128c42c251fb31b58582342c09c68be6ed3329340fb1d8f179c88590a4539c97 harness-cli-linux-arm64
|
|
7
|
+
902968f1383d45eb60e202eb98f8ce6c143cff73cb6f2ccc159a743ca5a70819 harness-cli-macos-x64
|
|
8
|
+
71217dbe03d111775c5016ab751f8bedbff66e7fd6a4d90f5c8d7e0e4a205b47 harness-cli-macos-arm64
|
|
9
|
+
2d7edff22ae25308c2ba23ab85bb9acb18d87eea28a9ca4efb2014a0f11a51a6 harness-cli-windows-x64.exe
|
|
@@ -54,7 +54,7 @@ gate): **`ck-predict` at ADR** (5-persona pre-decision debate) and **`ck-scenari
|
|
|
54
54
|
| UI card | `ui-ux-designer` | — | inline + `law/DESIGN.md` | review vs DESIGN.md |
|
|
55
55
|
| Repair / diagnostic | `debugger` | — | inline root-cause + fresh same-ladder subagent | `harness intervention add` |
|
|
56
56
|
| Review | `code-reviewer` (+ `typescript-reviewer` or `python-reviewer` layered — see language-specialist lens) | `bmad-code-review` (3-layer adversarial) | inline | `harness intervention add` on red |
|
|
57
|
-
| Deploy / git ship | `git-manager` | — | inline commit + PR guide | `harness story update --status implemented` |
|
|
57
|
+
| Deploy / git ship | `git-manager` | — | inline commit + PR guide | `harness story complete --id … --proof-source manual` (never bare `update --status implemented`) |
|
|
58
58
|
| Docs sync | `docs-manager` | — | inline doc update | — |
|
|
59
59
|
| Verify-live | `tester` / `web-testing` | `bmad-qa-generate-e2e-tests` | curl/Playwright | `harness story update --e2e 1` + `trace` |
|
|
60
60
|
|
|
@@ -34,7 +34,7 @@ for each todo card in card-number order:
|
|
|
34
34
|
4. flow.sh check C-NNN must PASS (mechanical) + gate-rules semantic check
|
|
35
35
|
5. merge to main in card order; deploy; VERIFY ON LIVE URL (merge != shipped)
|
|
36
36
|
6. paste world-state evidence into the card; status: done
|
|
37
|
-
7. flow.sh harness story
|
|
37
|
+
7. flow.sh harness story complete --id … --proof-source manual (or card_markdown_gate) + trace; log AUTO-LOG.md
|
|
38
38
|
8. remove worktree
|
|
39
39
|
```
|
|
40
40
|
|
|
@@ -180,15 +180,71 @@ _python() {
|
|
|
180
180
|
return 1
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
|
|
184
|
-
|
|
183
|
+
# Durable write honesty (plan trust-align D5/D8):
|
|
184
|
+
# unset FLOW_HARNESS_STRICT → soft: engine stays 0; one-line stderr warn on fail
|
|
185
|
+
# FLOW_HARNESS_STRICT=1 → soft exit; louder multi-line stderr
|
|
186
|
+
# FLOW_HARNESS_STRICT=fail → propagate nonzero from harness (card/check paths)
|
|
187
|
+
# harness_call_checked always returns the real harness exit (for callers that care).
|
|
188
|
+
_harness_run() {
|
|
189
|
+
# runs harness; prints stderr (masked lightly); echoes nothing; returns real rc
|
|
190
|
+
# usage: _harness_run <args...> sets _HARNESS_LAST_RC
|
|
191
|
+
_HARNESS_LAST_RC=0
|
|
185
192
|
[ -n "${FLOW_HARNESS_DISABLE:-}" ] && return 0
|
|
186
193
|
[ -f "$HARNESS_PY" ] || return 0
|
|
187
194
|
local py; py="$(_python)"; [ -n "$py" ] || return 0
|
|
188
|
-
|
|
195
|
+
local errf out rc=0
|
|
196
|
+
errf="$(mktemp 2>/dev/null || echo "$ROOT/.flow/.harness-err.$$")"
|
|
197
|
+
mkdir -p "$ROOT/.flow" 2>/dev/null || true
|
|
198
|
+
# capture rc without flipping the caller's set -e state
|
|
199
|
+
out="$(FLOW_PROJECT_ROOT="$ROOT" "$py" "$HARNESS_PY" "$@" 2>"$errf")" || rc=$?
|
|
200
|
+
_HARNESS_LAST_RC=$rc
|
|
201
|
+
if [ "$rc" -ne 0 ]; then
|
|
202
|
+
local errline summary
|
|
203
|
+
errline="$(tr -d '\r' <"$errf" 2>/dev/null | head -n 3 | tr '\n' ' ')"
|
|
204
|
+
# light redact of secret-shaped stderr / never dump free-text evidence args
|
|
205
|
+
case "$errline" in
|
|
206
|
+
*token*|*secret*|*passwd*|*password*|*credential*|*api_key*|*bearer*) errline="***redacted***" ;;
|
|
207
|
+
esac
|
|
208
|
+
summary="$1"
|
|
209
|
+
[ -n "${2:-}" ] && summary="$summary $2"
|
|
210
|
+
[ -n "${3:-}" ] && summary="$summary $3"
|
|
211
|
+
local mode="${FLOW_HARNESS_STRICT:-}"
|
|
212
|
+
if [ "$mode" = "1" ] || [ "$mode" = "fail" ]; then
|
|
213
|
+
printf 'flow-harness: durable command failed (rc=%s) cmd=%s\nflow-harness: %s\n' \
|
|
214
|
+
"$rc" "$summary" "$errline" >&2
|
|
215
|
+
else
|
|
216
|
+
printf 'flow-harness: warn durable write failed (rc=%s)\n' "$rc" >&2
|
|
217
|
+
fi
|
|
218
|
+
fi
|
|
219
|
+
rm -f "$errf" 2>/dev/null || true
|
|
220
|
+
return "$rc"
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
harness_call() {
|
|
224
|
+
# soft durable write: NEVER breaks engine unless STRICT=fail
|
|
225
|
+
_harness_run "$@" || true
|
|
226
|
+
if [ "${FLOW_HARNESS_STRICT:-}" = "fail" ] && [ "${_HARNESS_LAST_RC:-0}" -ne 0 ]; then
|
|
227
|
+
return "${_HARNESS_LAST_RC}"
|
|
228
|
+
fi
|
|
189
229
|
return 0
|
|
190
230
|
}
|
|
191
231
|
|
|
232
|
+
harness_call_checked() {
|
|
233
|
+
# returns real harness exit code (and still prints STRICT-aware warnings)
|
|
234
|
+
_harness_run "$@"
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
# When STRICT=fail, surface durable failure from card/check call sites (D5).
|
|
238
|
+
_harness_or_fail() {
|
|
239
|
+
harness_call "$@" || {
|
|
240
|
+
if [ "${FLOW_HARNESS_STRICT:-}" = "fail" ]; then
|
|
241
|
+
echo "FAIL: durable harness write failed (FLOW_HARNESS_STRICT=fail)."
|
|
242
|
+
return 1
|
|
243
|
+
fi
|
|
244
|
+
return 0
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
192
248
|
harness_available() { # 0 = durable layer usable (python + harness present, not disabled)
|
|
193
249
|
[ -n "${FLOW_HARNESS_DISABLE:-}" ] && return 1
|
|
194
250
|
[ -f "$HARNESS_PY" ] || return 1
|
|
@@ -973,7 +1029,7 @@ cmd_card_start() { # mark a card actively in progress (operator-visible in_progr
|
|
|
973
1029
|
local id; id="$(basename "$file" .md)"; FLOW_LOG_CARD="$id"
|
|
974
1030
|
if [ "$(card_status "$file")" = "done" ]; then echo "FAIL: $id is already done — nothing to start."; return 1; fi
|
|
975
1031
|
_inflight_set "$id"
|
|
976
|
-
|
|
1032
|
+
_harness_or_fail story update --id "$id" --status in_progress # durable mirror (STRICT=fail propagates)
|
|
977
1033
|
echo "PASS: $id marked in flight. Build it, then '/flow card done $id' (or hand-edit status: done + '/flow check $id')."
|
|
978
1034
|
return 0
|
|
979
1035
|
}
|
|
@@ -1033,7 +1089,7 @@ cmd_card() {
|
|
|
1033
1089
|
[ -n "$pc" ] && printf '%s\n' "$pc" | sed 's/^/ /'
|
|
1034
1090
|
[ -n "$dbt" ] && { echo " open debt:"; printf '%s\n' "$dbt" | sed 's/^/ /'; }
|
|
1035
1091
|
fi
|
|
1036
|
-
|
|
1092
|
+
_harness_or_fail story add --id "$id" --title "$id" --lane normal # durable tracking handle
|
|
1037
1093
|
return 0
|
|
1038
1094
|
}
|
|
1039
1095
|
|
|
@@ -1106,9 +1162,22 @@ cmd_check() {
|
|
|
1106
1162
|
if [ "$found" -eq 0 ]; then
|
|
1107
1163
|
echo "PASS: $id is valid (status: $st)."
|
|
1108
1164
|
case "$st" in
|
|
1109
|
-
todo)
|
|
1110
|
-
done)
|
|
1111
|
-
|
|
1165
|
+
todo) _harness_or_fail story update --id "$id" --status in_progress || return 1 ;;
|
|
1166
|
+
done)
|
|
1167
|
+
# trust-align: complete with honest card_markdown_gate provenance (D3/D7/D8)
|
|
1168
|
+
if ! harness_call_checked story complete --id "$id" \
|
|
1169
|
+
--proof-source card_markdown_gate \
|
|
1170
|
+
--evidence "card $id markdown gate PASS"; then
|
|
1171
|
+
if [ "${FLOW_HARNESS_STRICT:-}" = "fail" ]; then
|
|
1172
|
+
echo "FAIL: durable story complete failed (FLOW_HARNESS_STRICT=fail)."
|
|
1173
|
+
return 1
|
|
1174
|
+
fi
|
|
1175
|
+
fi
|
|
1176
|
+
# auto-trace: enrich tier-2 fields from known card context (do not fake --lane tiny)
|
|
1177
|
+
local tr
|
|
1178
|
+
tr="$(harness_emit trace --summary "card $id reached done-evidence" --story "$id" \
|
|
1179
|
+
--outcome completed --agent flow-check \
|
|
1180
|
+
--actions "check $id gate PASS" --files-changed "cards/$id.md" --friction none)"
|
|
1112
1181
|
[ -n "$tr" ] && printf '%s\n' "$tr" | grep -iE 'tier|to reach' | sed 's/^/ harness: /' ;;
|
|
1113
1182
|
esac
|
|
1114
1183
|
return 0
|
package/skills-manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"source": "../skills/flow",
|
|
3
3
|
"destRelative": "skills/flow",
|
|
4
|
-
"fileCount":
|
|
5
|
-
"syncedAt": "2026-07-
|
|
4
|
+
"fileCount": 76,
|
|
5
|
+
"syncedAt": "2026-07-19T14:46:19.032Z",
|
|
6
6
|
"fileList": [
|
|
7
7
|
"SKILL.md",
|
|
8
8
|
"_templates/00-idea.md",
|
|
@@ -31,11 +31,13 @@
|
|
|
31
31
|
"eval/fixtures/routing/states/state-review-pending.txt",
|
|
32
32
|
"eval/fixtures/routing/states/state-scope-stage.txt",
|
|
33
33
|
"eval/manifest.tsv",
|
|
34
|
+
"harness/GAP-MATRIX-0.1.17.md",
|
|
34
35
|
"harness/README.md",
|
|
35
36
|
"harness/_db.py",
|
|
36
37
|
"harness/_domain.py",
|
|
37
38
|
"harness/_presence.py",
|
|
38
39
|
"harness/flow_harness.py",
|
|
40
|
+
"harness/pins/harness-cli-v0.1.17.sha256sums",
|
|
39
41
|
"harness/repo_map.py",
|
|
40
42
|
"harness/schema/001-init.sql",
|
|
41
43
|
"harness/schema/002-story-verify.sql",
|