@manhquy/flow-skill 0.1.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +152 -0
- package/README_VN.md +134 -0
- package/SECURITY.md +69 -0
- package/bin/cli.mjs +382 -0
- package/package.json +52 -0
- package/skills/flow/SKILL.md +234 -0
- package/skills/flow/_templates/00-idea.md +16 -0
- package/skills/flow/_templates/00-inspect.md +42 -0
- package/skills/flow/_templates/01-research.md +59 -0
- package/skills/flow/_templates/02-scope.md +71 -0
- package/skills/flow/_templates/03-prd.md +57 -0
- package/skills/flow/_templates/04-adr.md +21 -0
- package/skills/flow/_templates/05-contract.md +59 -0
- package/skills/flow/_templates/card.md +26 -0
- package/skills/flow/_templates/constitution.md +22 -0
- package/skills/flow/eval/fixtures/f01a/flow/01-research.md +77 -0
- package/skills/flow/eval/fixtures/f01b/flow/01-research.md +75 -0
- package/skills/flow/eval/fixtures/f02a/flow/02-scope.md +56 -0
- package/skills/flow/eval/fixtures/f02b/flow/02-scope.md +65 -0
- package/skills/flow/eval/fixtures/fcda/.flow/.gitkeep +0 -0
- package/skills/flow/eval/fixtures/fcda/cards/C-001.md +46 -0
- package/skills/flow/eval/fixtures/fcdb/.flow/.gitkeep +0 -0
- package/skills/flow/eval/fixtures/fcdb/cards/C-001.md +35 -0
- package/skills/flow/eval/manifest.tsv +7 -0
- package/skills/flow/harness/README.md +117 -0
- package/skills/flow/harness/_db.py +228 -0
- package/skills/flow/harness/_domain.py +161 -0
- package/skills/flow/harness/_presence.py +109 -0
- package/skills/flow/harness/flow_harness.py +1103 -0
- package/skills/flow/harness/repo_map.py +93 -0
- package/skills/flow/harness/schema/001-init.sql +129 -0
- package/skills/flow/harness/schema/002-story-verify.sql +9 -0
- package/skills/flow/harness/schema/003-tool-registry.sql +15 -0
- package/skills/flow/harness/schema/004-intervention.sql +15 -0
- package/skills/flow/harness/schema/005-tool-extensions.sql +20 -0
- package/skills/flow/harness/schema/009-accessed-count.sql +11 -0
- package/skills/flow/harness/schema/010-usage-event.sql +42 -0
- package/skills/flow/harness/schema/011-usage-gate-reason.sql +8 -0
- package/skills/flow/harness/schema/012-usage-ephemeral.sql +10 -0
- package/skills/flow/law/CLAUDE.md +140 -0
- package/skills/flow/law/DESIGN.md +141 -0
- package/skills/flow/law/RETRO.md +13 -0
- package/skills/flow/playbooks/README.md +28 -0
- package/skills/flow/playbooks/cloudflare-ai-gateway-qwen.md +346 -0
- package/skills/flow/playbooks/docker-deploy-stale-cache.md +32 -0
- package/skills/flow/playbooks/rag-lite-postgres-cloudflare.md +192 -0
- package/skills/flow/playbooks/windows-gitbash-jsonl-telemetry.md +57 -0
- package/skills/flow/references/adversarial-review.md +197 -0
- package/skills/flow/references/agent-detection.md +88 -0
- package/skills/flow/references/agent-stage-mapping.md +114 -0
- package/skills/flow/references/antigravity-integration.md +92 -0
- package/skills/flow/references/auto-run.md +81 -0
- package/skills/flow/references/claudekit-skills.md +128 -0
- package/skills/flow/references/codex-integration.md +104 -0
- package/skills/flow/references/command-dispatch.md +54 -0
- package/skills/flow/references/debt-and-halts.md +41 -0
- package/skills/flow/references/design-review-checklist.md +42 -0
- package/skills/flow/references/gate-eval.md +186 -0
- package/skills/flow/references/gate-rules.md +171 -0
- package/skills/flow/references/ground-truth-gates.md +49 -0
- package/skills/flow/references/loop-harness-2026-principles.md +52 -0
- package/skills/flow/references/mode-work.md +37 -0
- package/skills/flow/references/project-types.md +42 -0
- package/skills/flow/references/stage-state-machine.md +47 -0
- package/skills/flow/references/ui-patterns-tcr.md +49 -0
- package/skills/flow/runner/flow.cmd +18 -0
- package/skills/flow/runner/flow.sh +3297 -0
- package/skills-manifest.json +70 -0
- package/src/constants.mjs +65 -0
- package/src/detect.mjs +36 -0
- package/src/help.mjs +42 -0
- package/src/installer.mjs +231 -0
- package/src/prompt.mjs +60 -0
- package/src/tty.mjs +11 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Reference-count repo-map: rank source files by how widely the symbols they DEFINE are
|
|
3
|
+
referenced across the codebase (Aider's ranking idea, stdlib-only — no tree-sitter dependency,
|
|
4
|
+
so it runs anywhere python 3 does). Best-effort: prints nothing and exits 0 when there is nothing
|
|
5
|
+
rankable, so the caller (flow.sh assess) falls back to its flat scan.
|
|
6
|
+
|
|
7
|
+
Usage: python repo_map.py <project_root> [top_n]
|
|
8
|
+
"""
|
|
9
|
+
import os
|
|
10
|
+
import re
|
|
11
|
+
import sys
|
|
12
|
+
from collections import Counter
|
|
13
|
+
|
|
14
|
+
SKIP_DIRS = {".git", "node_modules", ".flow", "plans", "dist", "build", "__pycache__",
|
|
15
|
+
".venv", "venv", "vendor", ".idea", ".vscode", "target", "coverage", "cards",
|
|
16
|
+
"tests", "test", "spec", "__tests__", "e2e"}
|
|
17
|
+
EXTS = {".py", ".js", ".ts", ".tsx", ".jsx", ".go", ".rs", ".sh", ".rb", ".java", ".kt"}
|
|
18
|
+
MAX_BYTES = 512 * 1024 # skip very large files (binary-adjacent / generated) to bound memory + time
|
|
19
|
+
# generic identifiers that carry no "this file is important" signal even when frequent
|
|
20
|
+
STOPWORDS = {"main", "init", "name", "self", "this", "data", "value", "values", "item", "items",
|
|
21
|
+
"list", "index", "test", "tests", "args", "kwargs", "result", "results", "error",
|
|
22
|
+
"get", "set", "run", "make", "type", "config", "setup", "build", "parse", "func"}
|
|
23
|
+
WORD = re.compile(r"[A-Za-z_]\w+")
|
|
24
|
+
DEF_PATTERNS = [
|
|
25
|
+
re.compile(r"^\s*(?:async\s+)?def\s+([A-Za-z_]\w+)"), # python
|
|
26
|
+
re.compile(r"^\s*class\s+([A-Za-z_]\w+)"), # python/js/ts/java/kt
|
|
27
|
+
re.compile(r"^\s*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_]\w+)"), # js/ts
|
|
28
|
+
re.compile(r"^\s*(?:export\s+)?const\s+([A-Za-z_]\w+)\s*(?::[^=]+)?="), # js/ts (incl. typed arrows: const x: T = )
|
|
29
|
+
re.compile(r"^\s*func\s+([A-Za-z_]\w+)"), # go
|
|
30
|
+
re.compile(r"^\s*(?:pub\s+)?fn\s+([A-Za-z_]\w+)"), # rust
|
|
31
|
+
re.compile(r"^\s*(?:pub\s+)?struct\s+([A-Za-z_]\w+)"), # rust
|
|
32
|
+
re.compile(r"^\s*([A-Za-z_]\w+)\s*\(\)\s*\{"), # shell name() {
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def iter_files(root):
|
|
37
|
+
# os.walk does NOT follow symlinks by default (no symlink-loop risk).
|
|
38
|
+
for dp, dirs, files in os.walk(root):
|
|
39
|
+
dirs[:] = [d for d in dirs if d not in SKIP_DIRS and not d.startswith(".")]
|
|
40
|
+
for fn in files:
|
|
41
|
+
if os.path.splitext(fn)[1] in EXTS:
|
|
42
|
+
yield os.path.join(dp, fn)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _defs_in(lines):
|
|
46
|
+
syms = set()
|
|
47
|
+
for ln in lines:
|
|
48
|
+
for pat in DEF_PATTERNS:
|
|
49
|
+
m = pat.match(ln)
|
|
50
|
+
if m:
|
|
51
|
+
name = m.group(1)
|
|
52
|
+
if len(name) >= 4 and name.lower() not in STOPWORDS:
|
|
53
|
+
syms.add(name)
|
|
54
|
+
return syms
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def main(argv):
|
|
58
|
+
root = argv[1] if len(argv) > 1 else "."
|
|
59
|
+
top_n = int(argv[2]) if len(argv) > 2 else 10
|
|
60
|
+
files = list(iter_files(root))
|
|
61
|
+
if not files:
|
|
62
|
+
return 0
|
|
63
|
+
defs, def_files, freq = {}, Counter(), Counter()
|
|
64
|
+
for f in files:
|
|
65
|
+
try:
|
|
66
|
+
if os.path.getsize(f) > MAX_BYTES:
|
|
67
|
+
continue
|
|
68
|
+
with open(f, "r", encoding="utf-8", errors="ignore") as fh:
|
|
69
|
+
lines = fh.read().splitlines()
|
|
70
|
+
except OSError:
|
|
71
|
+
continue
|
|
72
|
+
syms = _defs_in(lines)
|
|
73
|
+
defs[f] = syms
|
|
74
|
+
for s in syms:
|
|
75
|
+
def_files[s] += 1
|
|
76
|
+
freq.update(WORD.findall("\n".join(lines))) # tokenize ONCE per file (O(corpus) total)
|
|
77
|
+
ranked = []
|
|
78
|
+
for f in files:
|
|
79
|
+
# only symbols UNIQUELY defined in this file score it — a name defined in many files
|
|
80
|
+
# (utils, helper) is ambiguous and would give every definer the same inflated count.
|
|
81
|
+
uniq = [s for s in defs.get(f, ()) if def_files[s] == 1]
|
|
82
|
+
score = sum(max(0, freq.get(s, 0) - 1) for s in uniq) # minus the definition itself
|
|
83
|
+
if score > 0:
|
|
84
|
+
top = sorted(uniq, key=lambda s: -freq.get(s, 0))[:3]
|
|
85
|
+
ranked.append((score, os.path.relpath(f, root).replace("\\", "/"), top))
|
|
86
|
+
ranked.sort(key=lambda x: (-x[0], x[1]))
|
|
87
|
+
for i, (score, rel, top) in enumerate(ranked[:top_n], 1):
|
|
88
|
+
print(f"{i}. {rel} (score {score}; {', '.join(top)})")
|
|
89
|
+
return 0
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
if __name__ == "__main__":
|
|
93
|
+
sys.exit(main(sys.argv))
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
-- Harness v0 schema — migration 001
|
|
2
|
+
-- Durable layer for operational harness data.
|
|
3
|
+
-- Policy docs (HARNESS.md, FEATURE_INTAKE.md, ARCHITECTURE.md) stay as
|
|
4
|
+
-- human-readable references. This database stores the operational records
|
|
5
|
+
-- that agents produce and query during work.
|
|
6
|
+
|
|
7
|
+
PRAGMA journal_mode = WAL;
|
|
8
|
+
PRAGMA foreign_keys = ON;
|
|
9
|
+
|
|
10
|
+
----------------------------------------------------------------------
|
|
11
|
+
-- Schema version
|
|
12
|
+
----------------------------------------------------------------------
|
|
13
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
14
|
+
version INTEGER PRIMARY KEY,
|
|
15
|
+
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
INSERT INTO schema_version (version) VALUES (1);
|
|
19
|
+
|
|
20
|
+
----------------------------------------------------------------------
|
|
21
|
+
-- Intake: classifying incoming work
|
|
22
|
+
----------------------------------------------------------------------
|
|
23
|
+
CREATE TABLE intake (
|
|
24
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
25
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
26
|
+
input_type TEXT NOT NULL
|
|
27
|
+
CHECK(input_type IN (
|
|
28
|
+
'new_spec','spec_slice','change_request',
|
|
29
|
+
'new_initiative','maintenance','harness_improvement'
|
|
30
|
+
)),
|
|
31
|
+
summary TEXT NOT NULL,
|
|
32
|
+
risk_lane TEXT NOT NULL
|
|
33
|
+
CHECK(risk_lane IN ('tiny','normal','high_risk')),
|
|
34
|
+
risk_flags TEXT, -- JSON array, e.g. ["auth","data_model"]
|
|
35
|
+
affected_docs TEXT, -- JSON array of doc paths
|
|
36
|
+
story_id TEXT, -- links to story.id when one is created
|
|
37
|
+
notes TEXT
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
----------------------------------------------------------------------
|
|
41
|
+
-- Story: work packets and their validation status
|
|
42
|
+
-- Replaces hand-edited TEST_MATRIX.md rows.
|
|
43
|
+
----------------------------------------------------------------------
|
|
44
|
+
CREATE TABLE story (
|
|
45
|
+
id TEXT PRIMARY KEY, -- e.g. US-001
|
|
46
|
+
title TEXT NOT NULL,
|
|
47
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
48
|
+
risk_lane TEXT NOT NULL
|
|
49
|
+
CHECK(risk_lane IN ('tiny','normal','high_risk')),
|
|
50
|
+
contract_doc TEXT, -- path to product doc
|
|
51
|
+
status TEXT NOT NULL DEFAULT 'planned'
|
|
52
|
+
CHECK(status IN (
|
|
53
|
+
'planned','in_progress','implemented','changed','retired'
|
|
54
|
+
)),
|
|
55
|
+
unit_proof INTEGER NOT NULL DEFAULT 0,
|
|
56
|
+
integration_proof INTEGER NOT NULL DEFAULT 0,
|
|
57
|
+
e2e_proof INTEGER NOT NULL DEFAULT 0,
|
|
58
|
+
platform_proof INTEGER NOT NULL DEFAULT 0,
|
|
59
|
+
evidence TEXT,
|
|
60
|
+
notes TEXT
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
----------------------------------------------------------------------
|
|
64
|
+
-- Decision: durable records with optional verification
|
|
65
|
+
----------------------------------------------------------------------
|
|
66
|
+
CREATE TABLE decision (
|
|
67
|
+
id TEXT PRIMARY KEY, -- e.g. 0001
|
|
68
|
+
title TEXT NOT NULL,
|
|
69
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
70
|
+
status TEXT NOT NULL DEFAULT 'proposed'
|
|
71
|
+
CHECK(status IN (
|
|
72
|
+
'proposed','accepted','superseded','rejected'
|
|
73
|
+
)),
|
|
74
|
+
doc_path TEXT, -- path to the markdown ADR
|
|
75
|
+
verify_command TEXT, -- optional check command
|
|
76
|
+
last_verified_at TEXT,
|
|
77
|
+
last_verified_result TEXT
|
|
78
|
+
CHECK(last_verified_result IN ('pass','fail') OR
|
|
79
|
+
last_verified_result IS NULL),
|
|
80
|
+
predicted_impact TEXT,
|
|
81
|
+
actual_outcome TEXT,
|
|
82
|
+
notes TEXT
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
----------------------------------------------------------------------
|
|
86
|
+
-- Backlog: harness improvement proposals with evidence loop
|
|
87
|
+
----------------------------------------------------------------------
|
|
88
|
+
CREATE TABLE backlog (
|
|
89
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
90
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
91
|
+
title TEXT NOT NULL,
|
|
92
|
+
discovered_while TEXT,
|
|
93
|
+
current_pain TEXT,
|
|
94
|
+
suggested_improvement TEXT,
|
|
95
|
+
risk TEXT CHECK(risk IN ('tiny','normal','high_risk')),
|
|
96
|
+
status TEXT NOT NULL DEFAULT 'proposed'
|
|
97
|
+
CHECK(status IN (
|
|
98
|
+
'proposed','accepted','implemented','rejected'
|
|
99
|
+
)),
|
|
100
|
+
predicted_impact TEXT,
|
|
101
|
+
actual_outcome TEXT,
|
|
102
|
+
implemented_at TEXT,
|
|
103
|
+
notes TEXT
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
----------------------------------------------------------------------
|
|
107
|
+
-- Trace: agent task execution records (observability foundation)
|
|
108
|
+
----------------------------------------------------------------------
|
|
109
|
+
CREATE TABLE trace (
|
|
110
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
111
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
112
|
+
task_summary TEXT NOT NULL,
|
|
113
|
+
intake_id INTEGER REFERENCES intake(id),
|
|
114
|
+
story_id TEXT REFERENCES story(id),
|
|
115
|
+
agent TEXT,
|
|
116
|
+
actions_taken TEXT, -- JSON array
|
|
117
|
+
files_read TEXT, -- JSON array
|
|
118
|
+
files_changed TEXT, -- JSON array
|
|
119
|
+
decisions_made TEXT, -- JSON array
|
|
120
|
+
errors TEXT, -- JSON array
|
|
121
|
+
outcome TEXT
|
|
122
|
+
CHECK(outcome IN (
|
|
123
|
+
'completed','blocked','partial','failed'
|
|
124
|
+
)),
|
|
125
|
+
duration_seconds INTEGER,
|
|
126
|
+
token_estimate INTEGER,
|
|
127
|
+
harness_friction TEXT,
|
|
128
|
+
notes TEXT
|
|
129
|
+
);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
-- Harness v0 schema - migration 002
|
|
2
|
+
-- Story-level mechanical verification.
|
|
3
|
+
|
|
4
|
+
ALTER TABLE story ADD COLUMN verify_command TEXT;
|
|
5
|
+
ALTER TABLE story ADD COLUMN last_verified_at TEXT;
|
|
6
|
+
ALTER TABLE story ADD COLUMN last_verified_result TEXT
|
|
7
|
+
CHECK(last_verified_result IN ('pass','fail') OR last_verified_result IS NULL);
|
|
8
|
+
|
|
9
|
+
INSERT INTO schema_version (version) VALUES (2);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- Harness v0 schema - migration 003
|
|
2
|
+
-- Machine-readable registry for user-provided project tools.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE tool (
|
|
5
|
+
name TEXT PRIMARY KEY,
|
|
6
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
7
|
+
provider TEXT NOT NULL DEFAULT 'custom',
|
|
8
|
+
command TEXT NOT NULL,
|
|
9
|
+
description TEXT NOT NULL,
|
|
10
|
+
args TEXT,
|
|
11
|
+
responsibility TEXT NOT NULL,
|
|
12
|
+
since TEXT NOT NULL DEFAULT 'registered'
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
INSERT INTO schema_version (version) VALUES (3);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- Harness v0 schema - migration 004
|
|
2
|
+
-- Review, human, CI, or agent interventions separated from normal traces.
|
|
3
|
+
|
|
4
|
+
CREATE TABLE intervention (
|
|
5
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
6
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
7
|
+
trace_id INTEGER REFERENCES trace(id),
|
|
8
|
+
story_id TEXT,
|
|
9
|
+
type TEXT NOT NULL CHECK(type IN ('correction','override','escalation','approval')),
|
|
10
|
+
description TEXT NOT NULL,
|
|
11
|
+
source TEXT NOT NULL CHECK(source IN ('human','reviewer','ci','agent')),
|
|
12
|
+
impact TEXT
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
INSERT INTO schema_version (version) VALUES (4);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- Harness v0 schema - migration 005
|
|
2
|
+
-- Inbound tool registry: kind-aware presence + capability binding.
|
|
3
|
+
-- These columns turn the tool table from "declared intent" into
|
|
4
|
+
-- "intent + last-scanned reality" without breaking existing rows.
|
|
5
|
+
-- Adopted verbatim from repository-harness scripts/schema/005-tool-extensions.sql
|
|
6
|
+
-- to keep migrations 001-005 a faithful port of the upstream harness schema.
|
|
7
|
+
|
|
8
|
+
ALTER TABLE tool ADD COLUMN kind TEXT NOT NULL DEFAULT 'cli';
|
|
9
|
+
ALTER TABLE tool ADD COLUMN capability TEXT;
|
|
10
|
+
ALTER TABLE tool ADD COLUMN scan_target TEXT;
|
|
11
|
+
ALTER TABLE tool ADD COLUMN status TEXT NOT NULL DEFAULT 'unknown';
|
|
12
|
+
ALTER TABLE tool ADD COLUMN checked_at TEXT;
|
|
13
|
+
|
|
14
|
+
-- Backfill kind for tools registered before kinds existed, inferring it from
|
|
15
|
+
-- the agent-neutral command prefix convention so an upgrade does not mis-type
|
|
16
|
+
-- (and then falsely flag as broken) MCP servers or skills that are not on PATH.
|
|
17
|
+
UPDATE tool SET kind = 'mcp' WHERE command LIKE 'mcp:%';
|
|
18
|
+
UPDATE tool SET kind = 'skill' WHERE command LIKE 'skill:%';
|
|
19
|
+
|
|
20
|
+
INSERT INTO schema_version (version) VALUES (5);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Harness v0 schema - migration 009 (re-homed from 005 to free version 5 for the
|
|
2
|
+
-- upstream tool-extensions migration; flow-specific, not in repository-harness).
|
|
3
|
+
-- Usage signal: accessed_count tracks how often a durable row is surfaced by recall/query.
|
|
4
|
+
-- Read-only reuse signal: incremented on read only, NEVER used to delete or prune a row
|
|
5
|
+
-- (a rare-but-critical one-time lesson must survive a low access count). Surfaces what is reused.
|
|
6
|
+
|
|
7
|
+
ALTER TABLE decision ADD COLUMN accessed_count INTEGER NOT NULL DEFAULT 0;
|
|
8
|
+
ALTER TABLE trace ADD COLUMN accessed_count INTEGER NOT NULL DEFAULT 0;
|
|
9
|
+
ALTER TABLE backlog ADD COLUMN accessed_count INTEGER NOT NULL DEFAULT 0;
|
|
10
|
+
|
|
11
|
+
INSERT INTO schema_version (version) VALUES (9);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
-- Harness schema - migration 010 (re-homed from 006; flow-specific, not in repository-harness).
|
|
2
|
+
-- Mechanical usage-log mirror. The append-only JSONL sinks (.flow/events.jsonl full,
|
|
3
|
+
-- ~/.claude/flow/usage.jsonl compact) are the source of truth; this table is a derived,
|
|
4
|
+
-- queryable rollup for `flow usage` stats. Idempotency rests on UNIQUE(src,line_no):
|
|
5
|
+
-- re-rolling the same append-only line is ignored. rollup_cursor stores the last line
|
|
6
|
+
-- number processed per source file (a skip-ahead optimization; correctness is the UNIQUE key).
|
|
7
|
+
|
|
8
|
+
CREATE TABLE usage_event (
|
|
9
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
10
|
+
src TEXT NOT NULL, -- absolute path of the JSONL sink the row came from
|
|
11
|
+
line_no INTEGER NOT NULL, -- 1-based line number within that file
|
|
12
|
+
epoch_s INTEGER,
|
|
13
|
+
session_id TEXT,
|
|
14
|
+
cycle_id TEXT,
|
|
15
|
+
project TEXT,
|
|
16
|
+
command TEXT,
|
|
17
|
+
args TEXT,
|
|
18
|
+
exit_code INTEGER,
|
|
19
|
+
gate_pass INTEGER, -- 1 / 0 / NULL (non-gate command)
|
|
20
|
+
duration_s INTEGER,
|
|
21
|
+
stage_from TEXT,
|
|
22
|
+
stage_to TEXT,
|
|
23
|
+
card TEXT,
|
|
24
|
+
project_type TEXT,
|
|
25
|
+
mode TEXT,
|
|
26
|
+
flow_version TEXT,
|
|
27
|
+
tier TEXT,
|
|
28
|
+
host TEXT,
|
|
29
|
+
read_only INTEGER,
|
|
30
|
+
UNIQUE(src, line_no)
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
CREATE INDEX idx_usage_event_cycle ON usage_event(cycle_id);
|
|
34
|
+
CREATE INDEX idx_usage_event_cmd ON usage_event(command);
|
|
35
|
+
|
|
36
|
+
CREATE TABLE rollup_cursor (
|
|
37
|
+
src TEXT PRIMARY KEY,
|
|
38
|
+
last_line INTEGER NOT NULL DEFAULT 0,
|
|
39
|
+
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
INSERT INTO schema_version (version) VALUES (10);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
-- Harness schema - migration 011 (re-homed from 007; flow-specific, not in repository-harness).
|
|
2
|
+
-- Record WHICH gate check failed (not just the gate_pass bool) so "stage X fails often" is
|
|
3
|
+
-- diagnosable from the usage log. Additive column on the existing mirror; no new table.
|
|
4
|
+
-- Old JSONL lines without the field roll up as NULL (back-compatible).
|
|
5
|
+
|
|
6
|
+
ALTER TABLE usage_event ADD COLUMN gate_fail_reason TEXT;
|
|
7
|
+
|
|
8
|
+
INSERT INTO schema_version (version) VALUES (11);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
-- Harness schema - migration 012 (re-homed from 008; flow-specific, not in repository-harness).
|
|
2
|
+
-- Mark throwaway/test runs so device-wide analytics aren't dominated by them. A run is
|
|
3
|
+
-- ephemeral when its project root is under the system temp dir or named like an mktemp dir.
|
|
4
|
+
-- Additive column; old JSONL lines without the field roll up as NULL and are treated as
|
|
5
|
+
-- non-ephemeral, except the read-time `project LIKE 'tmp.%'` fallback still excludes legacy
|
|
6
|
+
-- temp runs from the default view (back-compatible, no log rewrite).
|
|
7
|
+
|
|
8
|
+
ALTER TABLE usage_event ADD COLUMN ephemeral INTEGER;
|
|
9
|
+
|
|
10
|
+
INSERT INTO schema_version (version) VALUES (12);
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Project rules — buildflow project
|
|
2
|
+
|
|
3
|
+
This repo is a project run with the **buildflow** method. Planning artifacts live in
|
|
4
|
+
`flow/`, build cards in `cards/`. The method: every stage/card has a GATE; no gate pass,
|
|
5
|
+
no advance. Read `README.md` once for the method; THESE rules govern every session here.
|
|
6
|
+
|
|
7
|
+
## /flow commands
|
|
8
|
+
|
|
9
|
+
`/flow` (status) · `/flow next` (gate-check + unlock stage) · `/flow card` (new card) ·
|
|
10
|
+
`/flow check C-NNN` (validate card) · `/flow mode teach|work` (who writes the plan) ·
|
|
11
|
+
`/flow retro` (3 questions → RETRO.md / playbooks/ / FLOW-FEEDBACK.md) ·
|
|
12
|
+
`/flow ready` (what's buildable now, parallel-safe groups) · `/flow auto` (autonomous
|
|
13
|
+
build run — preflight via runner, then drive per SKILL.md AUTO PRINCIPLES: subagent per
|
|
14
|
+
card, planner reviews + verifies, worktree isolation for parallel groups, operator-gated
|
|
15
|
+
cards halt by design, state in card files + AUTO-LOG.md).
|
|
16
|
+
Runner: `bash .claude/skills/flow/runner/flow.sh <cmd>`.
|
|
17
|
+
|
|
18
|
+
Modes (`MODE` file at root; default `teach`): **teach** — the user writes every artifact,
|
|
19
|
+
the AI only gatekeeps. **work** — the AI interviews the operator once, drafts stages 00-05
|
|
20
|
+
itself, pauses only for scope sign-off, delivers the card set as one summary. Gates and
|
|
21
|
+
done-rules are identical in both modes.
|
|
22
|
+
|
|
23
|
+
## Build-session discipline (when implementing a card)
|
|
24
|
+
|
|
25
|
+
1. ONE card per session. The card IS the session brief: build exactly its `## Scope`,
|
|
26
|
+
touch ONLY its `## Allowed files`. Need another file? Stop — amend the card first.
|
|
27
|
+
Default is serial, in card order. Parallel is allowed ONLY per the worktree protocol below.
|
|
28
|
+
2. Two law files: the contract (`flow/05-contract.md`) for shapes, `DESIGN.md` for pixels.
|
|
29
|
+
Every UI card (mock + frontend) is built AND reviewed against DESIGN.md — tokens,
|
|
30
|
+
affordance ladder, object-first pattern, never-do list. Read it before any UI work.
|
|
31
|
+
The contract: never improvise a request/response shape.
|
|
32
|
+
If the contract is wrong, amend `flow/05-contract.md` FIRST, then code to it.
|
|
33
|
+
When the contract requires a field whose FEATURE belongs to a later card: honor the
|
|
34
|
+
SHAPE now (null/stub value, commented as such), deliver the VALUE in that feature's
|
|
35
|
+
card. Never omit the field — the UI card will consume the shape you ship.
|
|
36
|
+
3. Run every `## Verify` step for real before claiming done. Paste actual output/URLs
|
|
37
|
+
into `## Evidence`. Only then set `status: done`, then run `/flow check C-NNN`.
|
|
38
|
+
4. Done-evidence = world-state (deployed URL, curl output, DB row). "Tests pass" /
|
|
39
|
+
"code merged" are mid-pipeline, never done.
|
|
40
|
+
5. Never check a gate box or write a planning artifact on the user's behalf.
|
|
41
|
+
Never set a card `done` without pasted evidence.
|
|
42
|
+
6. Read any file flow.sh just created before first editing it.
|
|
43
|
+
7. **Playbooks** (`playbooks/`): paid-for stack knowledge. Before building a card that
|
|
44
|
+
touches a stack with a playbook (check `playbooks/README.md` index), READ it and run
|
|
45
|
+
its smoke tests before committing to a design on that stack. After a card pays for a
|
|
46
|
+
non-obvious lesson, HARVEST it back into a playbook — the card review isn't done
|
|
47
|
+
until the lesson is filed. More stacks → more playbooks.
|
|
48
|
+
|
|
49
|
+
## Standard card sequence
|
|
50
|
+
|
|
51
|
+
1. **Scaffold + CI/CD** — repo, deploy pipeline, `/healthz` on a public URL. The scaffold
|
|
52
|
+
picks the spec-serving mechanism (FastAPI: free at `/docs` + `/openapi.json`; other
|
|
53
|
+
stacks: choose the generator in the ADR) — API docs are plumbing, not a later feature.
|
|
54
|
+
2. **Vertical slice** — one contract endpoint + one ugly page calling it, deployed.
|
|
55
|
+
From this card on, `/docs` is LIVE on the deployed URL and shows the endpoint.
|
|
56
|
+
3. **Backend cards** — one endpoint-group per card, built TO the contract.
|
|
57
|
+
**Swagger lands WITH the API**: every backend card's verify includes "the card's
|
|
58
|
+
endpoints appear in the live `/docs` with correct request/response schemas" — its
|
|
59
|
+
done-evidence includes the docs URL. Docs are never a catch-up card.
|
|
60
|
+
4. **Contract-test card** — automated suite hitting EVERY contract endpoint with edge +
|
|
61
|
+
failure cases against the deployed API. The objective "feel safe" gate before UI.
|
|
62
|
+
If the framework serves OpenAPI (FastAPI: `/openapi.json`), the suite ALSO asserts
|
|
63
|
+
every `flow/05-contract.md` endpoint exists in the live spec with matching shapes —
|
|
64
|
+
planning contract and runtime swagger must never drift.
|
|
65
|
+
5. **UI mock card** — static HTML, real copy, no logic/framework, rendered per `DESIGN.md`
|
|
66
|
+
(its tokens + patterns; the mock IS the design review). Done-evidence = the operator
|
|
67
|
+
viewed it in a browser and approved. Iterate here: mock retries cost seconds,
|
|
68
|
+
framework retries cost deploys.
|
|
69
|
+
6. **Frontend cards** — implement the approved mock, consuming the contract, reviewed
|
|
70
|
+
against `DESIGN.md`.
|
|
71
|
+
7. **E2E card** — automated browser test over the DEPLOYED app covering the PRD's user
|
|
72
|
+
actions; its run doubles as verify-live.
|
|
73
|
+
|
|
74
|
+
## PR & merge protocol
|
|
75
|
+
|
|
76
|
+
Once the scaffold card lands, **main = deployable** (auto-deploy watches it). From then on:
|
|
77
|
+
|
|
78
|
+
1. **Branch per card**: `card/C-NNN`, serial or parallel alike. No direct commits to main.
|
|
79
|
+
2. **Commits**: plain ASCII messages (smart quotes / arrows can break CI+deploy hooks),
|
|
80
|
+
prefixed with the card id (`C-003: resident reply endpoint`), one logical change each.
|
|
81
|
+
3. **PR per card** when the repo has a remote: title = the card's title; body = the card's
|
|
82
|
+
scope + the verify outputs (paste real runs). The card review — diff vs scope, vs
|
|
83
|
+
allowed-files, vs contract shapes, vs DESIGN.md for UI — happens ON the PR diff,
|
|
84
|
+
BEFORE merge. A card with failing verify steps does not get a PR.
|
|
85
|
+
4. **Merge rules**:
|
|
86
|
+
- Merge in card-number order (deps guarantee order makes sense).
|
|
87
|
+
- After `gh pr create`, pushing more commits is a trap on squash-merge — trailing
|
|
88
|
+
commits can silently drop. If you must push post-create, re-check the PR's commit
|
|
89
|
+
list before merging, and verify the merged SHA on main contains every change.
|
|
90
|
+
- Delete the branch (and worktree) after merge — never with unmerged work.
|
|
91
|
+
5. **Merge ≠ shipped.** After merge: deploy runs → verify the change on the LIVE URL
|
|
92
|
+
(deploy-success is not proof the surface changed). Only then does the card's
|
|
93
|
+
`## Evidence` get its world-state proof and `status: done`.
|
|
94
|
+
6. **Auto runs**: the planner opens the PR, reviews the diff, merges green cards without
|
|
95
|
+
asking (Tier-A), and logs PR URL + merged SHA per card in AUTO-LOG.md. A red review
|
|
96
|
+
goes back to a fresh subagent (two-strikes rule applies).
|
|
97
|
+
7. **No remote?** Local-only projects keep the same shape minus the PR: branch per card,
|
|
98
|
+
review the diff before merging to main, same live-verify rule.
|
|
99
|
+
|
|
100
|
+
## Debt (deliberate gate-skips)
|
|
101
|
+
|
|
102
|
+
Reordering past the standard sequence or skipping a gate is a legitimate OPERATOR call
|
|
103
|
+
(demo-first, riskiest-first). But a skipped gate is a loan, and loans get written down:
|
|
104
|
+
|
|
105
|
+
1. Every deliberate skip opens a line in `DEBT.md` (create it on first use):
|
|
106
|
+
`- [ ] DEBT: <what was skipped> — <the exposure, concretely> — close before: <named
|
|
107
|
+
condition, e.g. "any real user touches this"> — opened <date> (cards: C-NNN…)`
|
|
108
|
+
2. **Security-class skips** (auth, public exposure of admin surfaces, tenancy, payments)
|
|
109
|
+
are NEVER silent and never planner-decided: the operator explicitly accepts the
|
|
110
|
+
exposure, in writing, in the DEBT line. In auto runs this is a Tier-C halt.
|
|
111
|
+
3. A debt's close condition is checked at every retro and before anything is given to a
|
|
112
|
+
real user. Closing a project run with open security debt requires an explicit
|
|
113
|
+
operator acknowledgment — "temporary" is one forgotten step from production.
|
|
114
|
+
4. Cards blocked by a debt (built but can't honestly reach done-evidence) stay
|
|
115
|
+
`todo` with PARTIAL evidence naming the debt — never half-done, never rounded up.
|
|
116
|
+
|
|
117
|
+
## Parallel builds (worktree protocol)
|
|
118
|
+
|
|
119
|
+
Cards declare `deps:` (card ids, or "none"). `bash .claude/skills/flow/runner/flow.sh ready`
|
|
120
|
+
computes which todo cards have deps met AND no allowed-files overlap — only those may run
|
|
121
|
+
in parallel. The runner advises; the OPERATOR dispatches. Rules:
|
|
122
|
+
|
|
123
|
+
1. One card = one worktree = one session:
|
|
124
|
+
`git worktree add ../<project>-C-NNN -b card/C-NNN`
|
|
125
|
+
2. A session in a worktree obeys its card's allowed-files exactly (overlap was checked
|
|
126
|
+
against the card text — drifting outside it breaks the parallel-safety guarantee).
|
|
127
|
+
3. Merge back in card-number order, one at a time: `/flow check C-NNN` passes →
|
|
128
|
+
merge to main → run the merged app once (deps-done means INTERFACE done, not proven
|
|
129
|
+
integration) → only then merge the next. Conflicts on merge = the overlap check was
|
|
130
|
+
gamed; stop and re-plan.
|
|
131
|
+
4. Remove the worktree after merge: `git worktree remove ../<project>-C-NNN`.
|
|
132
|
+
5. Cards whose verify needs the deployed app (contract-tests, e2e) are SERIAL by nature —
|
|
133
|
+
don't parallelize them.
|
|
134
|
+
|
|
135
|
+
## Forbidden
|
|
136
|
+
|
|
137
|
+
- Building two cards in the SAME worktree/session, or in parallel without `flow.sh ready`
|
|
138
|
+
marking them safe (planning all cards up front is fine).
|
|
139
|
+
- Editing `_templates/` or `flow.sh` during a project run.
|
|
140
|
+
- Frontend code before the UI mock card is approved.
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Design law — buildflow projects
|
|
2
|
+
|
|
3
|
+
This file is LAW for every UI card in this project — the UI mock card and every
|
|
4
|
+
frontend card MUST be built and reviewed against it. If a change conflicts with a rule
|
|
5
|
+
here, the rule wins (or the rule is changed deliberately, in this file, with a dated note).
|
|
6
|
+
|
|
7
|
+
Two layers, treat them differently:
|
|
8
|
+
- **Structure is law**: the affordance ladder, object-first pattern, forms rules, and the
|
|
9
|
+
never-do list apply to any product. Don't relitigate these per project.
|
|
10
|
+
- **Tokens are taste**: the colors, fonts, and gradients below are one good default.
|
|
11
|
+
A project MAY replace them — deliberately, in this file, all at once, with a dated
|
|
12
|
+
note — never ad-hoc per component.
|
|
13
|
+
|
|
14
|
+
## North Star
|
|
15
|
+
|
|
16
|
+
**Simple stupid UI for non-technical users; full power kept available — but never in the way.**
|
|
17
|
+
|
|
18
|
+
Users think in *their* objects ("my workshop", "my ticket", "my booking") — never in
|
|
19
|
+
engine concepts. Engine words (workflow, trigger, action, job, queue, webhook, agent,
|
|
20
|
+
prompt…) NEVER appear in user-facing copy. Define this project's vocabulary in the
|
|
21
|
+
table below and use it everywhere.
|
|
22
|
+
|
|
23
|
+
### Project vocabulary (fill per project — strings, never code paths)
|
|
24
|
+
|
|
25
|
+
| Engine concept | This project's user word |
|
|
26
|
+
|---|---|
|
|
27
|
+
| _(e.g. async agent run)_ | _(e.g. "đang phân loại…")_ |
|
|
28
|
+
|
|
29
|
+
## Five rules that override everything
|
|
30
|
+
|
|
31
|
+
1. **Object-first, not feature-first.** The home page of a thing IS the thing. Tabs are
|
|
32
|
+
lenses on the same object — the user never navigates "out" to reach something related.
|
|
33
|
+
2. **WYSIWYG, edited in place.** The daily 80% of edits happen inline on the object's own
|
|
34
|
+
page (see the affordance ladder). A separate Edit page exists only for the structural 20%.
|
|
35
|
+
3. **Defaults beat configuration.** Creatable in ≤6 visible fields; everything else behind
|
|
36
|
+
one "More options" disclosure. If a default serves 80%, ship it and demote the toggle.
|
|
37
|
+
4. **Plain language beats power syntax.** "4 days after it ends" — never cron. A field-picker
|
|
38
|
+
chip — never `{{ raw.templates }}`. No JSON in any simple surface.
|
|
39
|
+
5. **Power behind a door.** If a power surface exists, it's a `Simple | Pro` toggle that
|
|
40
|
+
never loses data, plus a visible "switch to simple" path back. 95% never flip it.
|
|
41
|
+
|
|
42
|
+
## Edit-affordance ladder (inline ↔ popup is a spectrum, not a switch)
|
|
43
|
+
|
|
44
|
+
Choose by the field's SEMANTIC SHAPE — always the lightest rung the shape allows.
|
|
45
|
+
Decision rule: count the inputs the user must touch to finish the edit.
|
|
46
|
+
|
|
47
|
+
| Rung | Field shape | Interaction |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| 1. Inline text | one free-text value | click → input in place → save on blur/Enter (optimistic) |
|
|
50
|
+
| 2. Inline control | one value, known set/format | click → the right native control in place (date picker, stepper, select) |
|
|
51
|
+
| 3. Popover composite | ONE displayed line composed of 2–4 sub-choices | click → popover anchored to the field, type-switch + matching input → "Done" writes one line |
|
|
52
|
+
| 4. Modal | a multi-field object, or a collection | "+ Add" / "Edit" → centered dialog with all fields |
|
|
53
|
+
|
|
54
|
+
- Popover edits **one display value**, dims nothing. Modal edits **an object or list**, dims the page.
|
|
55
|
+
Finishing produces one chip → popover. A new row in a list → modal. Never swap them.
|
|
56
|
+
- Inline-editable fields: text by default; hover reveals dotted underline + a 12px pencil;
|
|
57
|
+
click becomes the right affordance.
|
|
58
|
+
- **Empty state rides the same ladder**: a missing value renders as a dashed `+ Add {label}`
|
|
59
|
+
that opens its own rung. No field is ever a dead-end.
|
|
60
|
+
|
|
61
|
+
## Object page pattern (the Luma pattern)
|
|
62
|
+
|
|
63
|
+
Every object-detail page:
|
|
64
|
+
- **Pulse strip** — at-a-glance metrics inline (calm, no stat-tile cards, no shadows).
|
|
65
|
+
- **Up to 3 hero action cards** — the top things a user does on this object. Big targets,
|
|
66
|
+
gradient-tinted, one click. NOT a kebab menu.
|
|
67
|
+
- **Tabs as lenses** — all on the same object. Active tab: 2px bottom border `var(--fg-base)`.
|
|
68
|
+
- **Modal-first sub-actions** — small focused modals, one CTA. No multi-screen flows.
|
|
69
|
+
- **The overview shows less, not more.** Heavy lifting goes to specialized tabs.
|
|
70
|
+
|
|
71
|
+
## Editorial Minimal tokens (locked)
|
|
72
|
+
|
|
73
|
+
| Token | Value | Use |
|
|
74
|
+
|---|---|---|
|
|
75
|
+
| `--bg-base` | `#FFFFFF` | page bg, cards |
|
|
76
|
+
| `--bg-subtle` | `#FAFAFA` | sidebar, savebar, secondary surfaces |
|
|
77
|
+
| `--bg-muted` | `#F4F4F5` | hover, muted chips |
|
|
78
|
+
| `--fg-base` | `#09090B` | primary text, primary buttons |
|
|
79
|
+
| `--fg-muted` | `#52525B` | body, descriptions |
|
|
80
|
+
| `--fg-subtle` | `#71717A` | helper text, timestamps |
|
|
81
|
+
| `--border` | `#E4E4E7` | all 1px borders |
|
|
82
|
+
| `--accent` | `#4F46E5` | focus rings, accent links, validate-ok |
|
|
83
|
+
|
|
84
|
+
**Typography**: `Inter` body/labels/buttons · `Fraunces` h1, card titles, prominent stat
|
|
85
|
+
values ONLY · `JetBrains Mono` identifiers, dates, counts, machine-shaped content ONLY.
|
|
86
|
+
Don't sprinkle serif on body text or mono on prose.
|
|
87
|
+
|
|
88
|
+
**Borders**: 1px `var(--border)`. No drop shadows except focus rings, active sidebar item,
|
|
89
|
+
and hero-card hover lift. One purposeful elevation, never shadow noise.
|
|
90
|
+
|
|
91
|
+
## Soft gradients (highlight, not decorate)
|
|
92
|
+
|
|
93
|
+
Hero surfaces ONLY (hero action cards, gallery/list covers, pulse backdrop). NEVER on
|
|
94
|
+
tables, form inputs, sidebars, page backgrounds, or body rows.
|
|
95
|
+
|
|
96
|
+
```css
|
|
97
|
+
--grad-peach: linear-gradient(135deg, #FFF4EC 0%, #FEE7D6 100%); /* action / first in a series */
|
|
98
|
+
--grad-mint: linear-gradient(135deg, #ECFDF3 0%, #D1F4DD 100%); /* money / success / all-green */
|
|
99
|
+
--grad-sky: linear-gradient(135deg, #EEF4FF 0%, #DCE7FF 100%); /* info / context banners */
|
|
100
|
+
--grad-lavender: linear-gradient(135deg, #F3EEFF 0%, #E2D6FB 100%); /* primary surface / pulse */
|
|
101
|
+
--grad-rose: linear-gradient(135deg, #FFF1F4 0%, #FDDDE3 100%); /* social / sharing / accent */
|
|
102
|
+
--grad-pulse: linear-gradient(90deg, #FAFAFA 0%, #F3EEFF 50%, #FAFAFA 100%); /* subtle strips */
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Hover on gradient cards: lift `translateY(-1px)` + `box-shadow: 0 8px 24px rgba(9,9,11,.06)`;
|
|
106
|
+
no hard accent border.
|
|
107
|
+
|
|
108
|
+
## Forms
|
|
109
|
+
|
|
110
|
+
- Max 6 visible fields on any create/edit page; more → disclosure.
|
|
111
|
+
- One column, max-width 640px for focused forms. No multi-step wizards for editing.
|
|
112
|
+
- Sticky savebar: white, 1px top border, optional 4px gradient accent strip.
|
|
113
|
+
- Labels 12px / 500 / `var(--fg-muted)`. Inputs 38px tall, 1px border, accent focus ring.
|
|
114
|
+
|
|
115
|
+
## Iconography
|
|
116
|
+
|
|
117
|
+
Stroke line icons (Heroicons/Lucide style), stroke-width 1.6–2, no fill.
|
|
118
|
+
**No emojis. Anywhere. Ever.** Use SVGs.
|
|
119
|
+
|
|
120
|
+
## VN conventions (when the project is Vietnamese-facing)
|
|
121
|
+
|
|
122
|
+
- Vietnamese copy throughout the user surface — written natively, not translated.
|
|
123
|
+
- Prices: `₫750,000` — symbol leading, comma groups. Never "VND 750000.00".
|
|
124
|
+
- VietQR scan-to-pay as the default payment presentation; cards demoted to "Thẻ quốc tế".
|
|
125
|
+
- Zalo as a first-class support-channel option, not only email.
|
|
126
|
+
|
|
127
|
+
## What to never do
|
|
128
|
+
|
|
129
|
+
- Never leak engine words into user-facing copy (see vocabulary table).
|
|
130
|
+
- Never show raw `{{ }}` templates or JSON outside a power-user surface.
|
|
131
|
+
- Never use multi-step wizards for editing.
|
|
132
|
+
- Never gradient form inputs, body backgrounds, or table rows.
|
|
133
|
+
- Never stack shadows. Never add emojis. Never write design comments in HTML.
|
|
134
|
+
|
|
135
|
+
## How this binds the cards
|
|
136
|
+
|
|
137
|
+
- The **UI mock card** renders these tokens/patterns in static HTML — the mock IS the
|
|
138
|
+
design review; the operator approves against this file.
|
|
139
|
+
- Every **frontend card**'s review checks the diff against this file the same way it
|
|
140
|
+
checks shapes against `flow/05-contract.md`. DESIGN.md is to pixels what the contract
|
|
141
|
+
is to shapes.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Retro
|
|
2
|
+
|
|
3
|
+
After all cards are done, append ONE line per project run:
|
|
4
|
+
*Which gate did I skip or rush, and what did it cost?*
|
|
5
|
+
|
|
6
|
+
**Optional aid — the `retro` SKILL (opt-in).** Before writing the line, you may offer the `retro`
|
|
7
|
+
skill (git-history-driven: commit/velocity/code-health numbers) so the retro is backed by real
|
|
8
|
+
figures, not memory. It INFORMS the operator's line — **the operator still writes the line; the
|
|
9
|
+
skill never authors it** (the teach-mode rule holds). Distinct from the `journal-writer` agent
|
|
10
|
+
(narrative) — see `claudekit-skills.md`. After it runs at this gate, record the lazy durable
|
|
11
|
+
metric via `flow.sh harness intervention add`.
|
|
12
|
+
|
|
13
|
+
---
|