create-issflow 1.1.0 → 1.2.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/README.md CHANGED
@@ -25,7 +25,7 @@ Flags:
25
25
  The portable kit (every tool) in `<project>/.claude/`:
26
26
 
27
27
  - `agents/` — planner · researcher · implementer · test-author · debugger · e2e-runner · synthesizer
28
- - `commands/` — `/overview` `/propose` `/phase` `/change-request` `/replan` `/quick` `/synthesize` `/store-wisdom` `/log-issue` `/log-decision` `/unstuck`
28
+ - `commands/` — `/overview` `/propose` `/phase` `/ui-audit` `/qa-audit` `/security-audit` `/change-request` `/replan` `/quick` `/synthesize` `/store-wisdom` `/log-issue` `/log-decision` `/unstuck`
29
29
  - `skills/` — caveman · grill-me · karpathy-guidelines · ux-design
30
30
  - `hooks/` — session-start · pre-compact · subagent-stop
31
31
  - `istartsoft-flow/METHODOLOGY.md` — the full methodology (single source of truth)
package/bin/cli.js CHANGED
@@ -107,8 +107,21 @@ function copyTemplateCommands(destDir) {
107
107
  // ---- adapters (keep the methodology single-source — these POINT at it) ------
108
108
 
109
109
  function adapterClaude() {
110
+ // Claude Code auto-loads CLAUDE.md only — NOT AGENTS.md. Without a CLAUDE.md
111
+ // the methodology never enters context on its own (the SessionStart hook still
112
+ // injects the per-session summary, but the full single-source doc would not
113
+ // load). A one-line `@AGENTS.md` import gives Claude Code the full baseline
114
+ // while keeping ONE source of truth — no rule is restated here (anti-drift).
115
+ const c0 = conflicts;
116
+ writeFile('CLAUDE.md', claudeMd());
117
+ if (conflicts > c0) warnings.push('claude: you already keep a CLAUDE.md — ours was written as CLAUDE.md.issflow-new. Add a line `@AGENTS.md` to your CLAUDE.md so the methodology auto-loads.');
118
+ // Context-budget watchdog config (consumed by .claude/hooks/context-guard.js).
119
+ // Shipped default window:0 = auto-detect; flow-config.json lives at .claude root,
120
+ // outside build.js's copied DIRS, so the installer writes it here.
121
+ writeFile('.claude/flow-config.json', flowConfig());
110
122
  const HOOKS = {
111
123
  SessionStart: [{ matcher: 'startup|clear|compact', hooks: [{ type: 'command', command: 'node .claude/hooks/session-start.js' }] }],
124
+ PreToolUse: [{ matcher: '*', hooks: [{ type: 'command', command: 'node .claude/hooks/context-guard.js' }] }],
112
125
  PreCompact: [{ matcher: 'auto|manual', hooks: [{ type: 'command', command: 'node .claude/hooks/pre-compact.js' }] }],
113
126
  SubagentStop: [{ hooks: [{ type: 'command', command: 'node .claude/hooks/subagent-stop.js' }] }],
114
127
  };
@@ -176,7 +189,7 @@ function adapterAider() {
176
189
  const ADAPTERS = { claude: adapterClaude, codex: adapterCodex, cursor: adapterCursor, gemini: adapterGemini, aider: adapterAider };
177
190
 
178
191
  const NEXT_STEPS = {
179
- claude: 'Open Claude Code — the SessionStart hook fires automatically. Run /overview to bootstrap.',
192
+ claude: 'Open Claude Code — CLAUDE.md (@AGENTS.md) loads the methodology and the SessionStart hook fires automatically. Run /overview to bootstrap.',
180
193
  codex: 'Open Codex CLI — it reads AGENTS.md. Start by running the /overview procedure (.claude/commands/overview.md).',
181
194
  cursor: 'Open Cursor — the rule applies automatically. Run the /overview command to bootstrap.',
182
195
  gemini: 'Open Gemini CLI — it reads GEMINI.md. Run the SESSION-OPEN ritual, then the overview procedure.',
@@ -198,8 +211,9 @@ function agentsMd() {
198
211
  '## Roles — `.claude/agents/`', '',
199
212
  'planner · researcher · implementer · test-author · debugger · e2e-runner · synthesizer', '',
200
213
  '## Procedures — `.claude/commands/` (run as `/name`)', '',
201
- '/overview · /propose · /phase · /change-request · /replan · /quick · /synthesize ·',
202
- '/store-wisdom · /log-issue · /log-decision · /unstuck', '',
214
+ '/overview · /propose · /phase · /ui-audit · /qa-audit · /security-audit ·',
215
+ '/change-request · /replan · /quick · /synthesize · /runbook · /store-wisdom · /log-issue ·',
216
+ '/log-decision · /unstuck', '',
203
217
  '## Skills — `.claude/skills/` (loaded on demand)', '',
204
218
  'caveman · grill-me · karpathy-guidelines · ux-design · security (Secure SDLC) · code-standards', '',
205
219
  '## Autonomy', '',
@@ -224,6 +238,40 @@ function agentsMd() {
224
238
  ].join('\n');
225
239
  }
226
240
 
241
+ function claudeMd() {
242
+ return [
243
+ '# CLAUDE.md — iStartSoftFlow (Claude Code entry)', '',
244
+ '@AGENTS.md', '',
245
+ 'The import above is the single source of truth — it points to',
246
+ '`.claude/istartsoft-flow/METHODOLOGY.md` (read on demand). Do NOT restate any',
247
+ 'rule here; this file only wires Claude-native mechanisms (anti-drift invariant).', '',
248
+ '## Claude-native wiring (automatic — see `.claude/settings.json`)', '',
249
+ '- **SessionStart** hook injects git state + `docs/STATE.md` + open `docs/ISSUES.md`',
250
+ ' + the rule summary each session — read those first.',
251
+ '- **PreCompact** + **SubagentStop** hooks run their rituals automatically.',
252
+ '- Commands in `.claude/commands/` run as `/name`; agents in `.claude/agents/` are',
253
+ ' native subagents.', '',
254
+ ].join('\n');
255
+ }
256
+
257
+ function flowConfig() {
258
+ return JSON.stringify({
259
+ context: {
260
+ window: 0,
261
+ warnPct: 60,
262
+ gatePct: 78,
263
+ _note: 'Context-budget watchdog (.claude/hooks/context-guard.js, PreToolUse hook). '
264
+ + 'window 0 = auto-detect from the model id (200000 for standard models). '
265
+ + 'Some 1M-context models report their id WITHOUT a [1m] tag, so auto-detect '
266
+ + 'assumes 200000 and may false-gate around 156k — if you run a 1M model, set '
267
+ + 'window:1000000 here by hand. warnPct = soft non-blocking nudge; gatePct = hard '
268
+ + 'block on NEW build work (Edit/Write-to-source/feature Task). Checkpoint paths '
269
+ + '(docs/**, STATE/ISSUES/snapshots), the synthesizer subagent, and all Bash are '
270
+ + 'never blocked.',
271
+ },
272
+ }, null, 2) + '\n';
273
+ }
274
+
227
275
  // ---- main -------------------------------------------------------------------
228
276
 
229
277
  function main() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-issflow",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "Scaffold the iStartSoftFlow AI-coding workflow into a project. Stack-agnostic, tool-agnostic (Claude Code, Codex, Cursor, Gemini, Aider), non-destructive.",
5
5
  "bin": {
6
6
  "create-issflow": "bin/cli.js"
@@ -0,0 +1,53 @@
1
+ ---
2
+ description: Holistic QA audit — sweep the WHOLE product's functional quality (test-coverage gaps, regression health, flaky tests, critical-flow e2e, error/edge handling), score it, and produce a prioritized findings report. On-demand or before a release. NOT the per-phase gate — the phase gate runs one phase's real suite; this audits the entire test estate + behaviour.
3
+ argument-hint: [optional scope]
4
+ ---
5
+
6
+ Caveman ULTRA mode. You are the ORCHESTRATOR.
7
+
8
+ Purpose: a whole-product FUNCTIONAL QA audit — the QA counterpart of `/ui-audit`.
9
+ The per-phase gate (rule 5) proves ONE phase's real suite is green; this audit checks
10
+ the health + coverage of the ENTIRE test estate and the product's behaviour, end to
11
+ end. Run before a release, after big changes, or on request.
12
+
13
+ QA = "does it WORK right?" — a DIFFERENT axis from UI audit ("does it LOOK / meet
14
+ standards right?"). Passing one never implies the other.
15
+
16
+ ## PRE-FLIGHT
17
+ Read `docs/ENDPOINTS.md` (the surface), `docs/PLAN.md` (acceptance specs), and the
18
+ `tests/` + `e2e/` suites. The acceptance criteria + ENDPOINTS are the rubric.
19
+
20
+ ## STEP 1 — INVENTORY
21
+ List the public surface (endpoints, exported functions, CLI, message contracts) and
22
+ the critical user flows (from OVERVIEW). These are what MUST be covered.
23
+
24
+ ## STEP 2 — SWEEP (dispatch a worker to keep context lean)
25
+ - **Coverage** — every ENDPOINTS entry + acceptance criterion has a real-API
26
+ regression test? List gaps. Untested branches / error paths?
27
+ - **Critical flows** — does e2e cover the must-work journeys (auth, the core slice,
28
+ payments / data)?
29
+ - **Regression health** — run the full REAL corpus (`scripts/regression.sh --real`).
30
+ Any reds?
31
+ - **Flakiness** — tests that pass only on rerun (timing) — flag; don't hide.
32
+ - **Negative / edge** — are abuse cases + edge inputs asserted, not just the happy path?
33
+ - **Contract drift** — do the mock suites still match the real API?
34
+ - **Test integrity** — tests written BLIND from the spec (no overfit)? None edited to pass?
35
+
36
+ ## STEP 3 — SCORE + FINDINGS
37
+ Rate each dimension PASS / WARN / FAIL. Per finding:
38
+ - **severity**: BLOCKER (red real test · uncovered critical flow) · MAJOR (coverage
39
+ gap · flaky) · MINOR (polish)
40
+ - **location**: suite + case (or the uncovered surface)
41
+ - **issue** + **fix**: the concrete change
42
+
43
+ ## STEP 4 — REPORT
44
+ Write `docs/qa-audit-<YYYY-MM-DD>.md`: coverage map · per-dimension scoreboard ·
45
+ findings sorted by severity · prioritized fix list. Log BLOCKER / MAJOR to
46
+ `docs/ISSUES.md`.
47
+ **VERDICT: SHIP | FIX-FIRST** — never ship with a red real test or an uncovered
48
+ critical flow.
49
+
50
+ ## STEP 5 — REMEDIATE
51
+ AUTO: dispatch `test-author` (BLIND) to fill coverage gaps, `debugger` for reds
52
+ (budget 3), then re-run. Park what's blocked + report. Tests are written by
53
+ `test-author` for impartiality — never weaken a test to make it pass.
@@ -0,0 +1,38 @@
1
+ ---
2
+ description: Capture an operational/incident scenario in docs/RUNBOOK.md — one grep-able markdown so prod-debug knowledge isn't re-derived under pressure.
3
+ argument-hint: [scenario, or "from the incident we just solved"]
4
+ ---
5
+
6
+ Caveman ULTRA mode.
7
+
8
+ Distill an operational scenario into docs/RUNBOOK.md. Scenario: $ARGUMENTS
9
+
10
+ This is the runbook pattern Anthropic's Security + Data-Infra teams converged on
11
+ independently: consolidate stack traces, dashboard signals, and the exact
12
+ remediation commands into ONE searchable file so the next incident is a lookup,
13
+ not a re-investigation.
14
+
15
+ If $ARGUMENTS says "from the incident we just solved" (or similar), distill the
16
+ debugging session in context — symptom, the REAL root cause, the commands that
17
+ fixed it — instead of asking the user to re-type it.
18
+
19
+ Append an entry to docs/RUNBOOK.md (create the file if missing). Canonical format:
20
+ ```
21
+
22
+ ### <scenario title — searchable, literal symptom keywords>
23
+
24
+ - trigger: <what you observe first — alert, error string, dashboard signal>
25
+ - diagnose: <steps/commands to confirm the real root cause>
26
+ - remediate: <the exact commands/actions that fix it>
27
+ - verify: <how to confirm recovery — what "healthy" looks like>
28
+ - refs: <dashboard URLs, docs, related docs/ISSUES.md titles>
29
+
30
+ ```
31
+ Rules:
32
+ - title carries literal symptom keywords -> grep finds it mid-incident.
33
+ - remediate must be runnable as-is; no "investigate further".
34
+ - mark any step that is irreversible / PROD-writing with ⚠ so it's never run blind.
35
+ - cross-link the matching docs/ISSUES.md entry instead of duplicating root-cause prose.
36
+ - newest scenario at the TOP.
37
+
38
+ Confirm the entry back in 2 lines.
@@ -0,0 +1,56 @@
1
+ ---
2
+ description: Holistic security audit — sweep the WHOLE product against the security cookbook (OWASP Top 10 / ASVS / WSTG / secrets / SCA / SAST / supply chain), score it, and produce a prioritized findings report. On-demand or before a release. NOT the per-phase gate — rule 11 checks one phase while coding; this audits the whole attack surface.
3
+ argument-hint: [optional scope]
4
+ ---
5
+
6
+ Caveman ULTRA mode. You are the ORCHESTRATOR.
7
+
8
+ Purpose: a whole-product SECURITY audit — the security counterpart of `/ui-audit`
9
+ and `/qa-audit`. The per-phase gate (rule 11) checks secrets/SCA/SAST + secure coding
10
+ on ONE phase; this audit sweeps the ENTIRE attack surface and the product's security
11
+ posture. Run before a release, after auth/data changes, or on request — and before
12
+ the pre-deploy pentest, not instead of it.
13
+
14
+ Security = "is it SAFE?" — a different axis from QA ("does it work?") and UI
15
+ ("does it look right?"). Passing those never implies this.
16
+
17
+ ## PRE-FLIGHT
18
+ Read the rubric: `.claude/skills/security/SKILL.md` (the Secure SDLC cookbook) and
19
+ its `references/` (OWASP Top 10 / ASVS / WSTG / ISO 27001 / SLSA). The cookbook IS the
20
+ checklist — audit against it; don't invent criteria.
21
+
22
+ ## STEP 1 — INVENTORY (attack surface)
23
+ Map it from `docs/ENDPOINTS.md` + the code: entry points (routes, inputs, file
24
+ uploads, webhooks), trust boundaries, auth/session, data stores + PII, secrets,
25
+ third-party deps, and outbound calls.
26
+
27
+ ## STEP 2 — SWEEP (dispatch a worker to keep context lean)
28
+ - **OWASP Top 10** — broken access control, crypto failures, injection (SQLi/XSS/
29
+ cmd), insecure design, misconfiguration, vulnerable components, auth failures,
30
+ integrity failures, logging/monitoring gaps, SSRF.
31
+ - **AuthN / AuthZ** — every protected route enforces it; no IDOR; least privilege.
32
+ - **Secrets** — none in code/history/config/prompts (run gitleaks/trufflehog if present).
33
+ - **Dependencies (SCA)** — known CVEs (run `npm audit` / `pip-audit` / `osv-scanner`).
34
+ - **SAST** — run semgrep / CodeQL if present; review hotspots otherwise.
35
+ - **Input validation + output encoding** at every boundary; safe file handling.
36
+ - **Crypto** — strong algorithms, no hardcoded keys, secrets at rest/in transit.
37
+ - **Supply chain (SLSA)** — pinned deps, build integrity, no untrusted scripts.
38
+ - **Logging / monitoring** — security events logged; no sensitive data in logs.
39
+ - **Threat-model coverage** — were the design-stage abuse cases actually tested?
40
+
41
+ ## STEP 3 — SCORE + FINDINGS
42
+ Rate each area PASS / WARN / FAIL. Per finding:
43
+ - **severity**: CRITICAL · HIGH · MEDIUM · LOW (map to CVSS where it helps)
44
+ - **location**: endpoint / file / dependency
45
+ - **issue** + the OWASP/ASVS reference it breaks + **fix**
46
+
47
+ ## STEP 4 — REPORT
48
+ Write `docs/security-audit-<YYYY-MM-DD>.md`: attack-surface map · per-area scoreboard ·
49
+ findings sorted by severity · prioritized remediation. Log HIGH/CRITICAL to
50
+ `docs/ISSUES.md`.
51
+ **VERDICT: SHIP | FIX-FIRST** — never ship with an open HIGH or CRITICAL.
52
+
53
+ ## STEP 5 — REMEDIATE
54
+ A security fix is security-sensitive (autonomy hard-stop): in AUTO, fix and re-audit
55
+ but SURFACE the change for human sign-off before it lands. Park what's blocked +
56
+ report. A clean `/security-audit` is a precondition for the pre-deploy pentest gate.
@@ -0,0 +1,54 @@
1
+ ---
2
+ description: Holistic UI audit — sweep the WHOLE product's UI against the ux-design cookbook (+ a11y / responsive / consistency), score it, and produce a prioritized findings report. On-demand or before a release. This is NOT the per-phase gate — the `ux-design` gate checks one screen at phase close (pass/block); this audit sweeps every screen and reports accumulated drift.
3
+ argument-hint: [optional scope — a route, or "all"]
4
+ ---
5
+
6
+ Caveman ULTRA mode. You are the ORCHESTRATOR.
7
+
8
+ Purpose: a periodic, WHOLE-PRODUCT UI audit — distinct from the inline `ux-design`
9
+ gate. The gate validates ONE screen at phase close; this AUDIT sweeps EVERY screen,
10
+ scores the product, and surfaces drift that accumulated across changes. Run before a
11
+ release, after big UI work, or on request.
12
+
13
+ ## PRE-FLIGHT
14
+ Read the rubric: `.claude/skills/ux-design/SKILL.md` (the cookbook) and
15
+ `references/wireframe-template.md` (the frame). The cookbook IS the checklist —
16
+ do not invent new criteria; audit against it.
17
+
18
+ ## STEP 1 — INVENTORY
19
+ List every screen / route / major component to audit (from the router, the
20
+ wireframe baseline, or `$ARGUMENTS`). Audit shared components once.
21
+
22
+ ## STEP 2 — SWEEP (dispatch a worker per area to keep context lean)
23
+ Score each screen against the cookbook dimensions:
24
+ - design tokens · 8-pt spacing · type scale (no raw hex/px)
25
+ - iconography — a real SVG set, **NEVER emoji**
26
+ - accessibility (WCAG 2.1 AA): contrast ≥ 4.5:1, visible focus, keyboard reach,
27
+ semantic HTML, labels / alt / aria, 44×44 targets, `prefers-reduced-motion`
28
+ - state matrix: default · hover · focus · active · disabled · loading · empty · error
29
+ - responsive breakpoints (no overflow / break)
30
+ - content & i18n (no hardcoded strings; growth-safe)
31
+ - consistency / wireframe conformance (no drift BETWEEN screens)
32
+ Run automated tools if the project has them (axe-core / Lighthouse / pa11y) and fold
33
+ their output in; otherwise do the manual cookbook sweep.
34
+
35
+ ## STEP 3 — SCORE + FINDINGS
36
+ Rate each dimension PASS / WARN / FAIL. For every finding record:
37
+ - **severity**: BLOCKER (a11y / contrast / unusable) · MAJOR (drift / missing state)
38
+ · MINOR (polish)
39
+ - **location**: screen + element
40
+ - **issue** + the cookbook rule it breaks
41
+ - **fix**: the concrete change
42
+
43
+ ## STEP 4 — REPORT
44
+ Write `docs/ui-audit-<YYYY-MM-DD>.md`:
45
+ - coverage (screens audited) · a per-dimension scoreboard · the findings table sorted
46
+ by severity · a prioritized fix list.
47
+ - Log BLOCKER / MAJOR findings to `docs/ISSUES.md`.
48
+ - **VERDICT: SHIP | FIX-FIRST** — a release must not ship with open BLOCKERs.
49
+
50
+ ## STEP 5 — REMEDIATE
51
+ AUTO: fix MINOR / MAJOR that don't change the visual direction, re-audit them, log.
52
+ A new visual direction or a design-token change → confirm with the user first
53
+ (hard rule 9 — UI conforms to the frame; new direction is a human call).
54
+ Hand back the report + what was fixed vs parked.
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+ // PreToolUse context watchdog (iStartSoftFlow). Two tiers, one hook:
4
+ // warnPct -> non-blocking nudge (additionalContext) once per climb into the band
5
+ // gatePct -> HARD block of NEW build work (Edit/Write-to-source/feature Task)
6
+ // Reads REAL token usage from the transcript. Fail-OPEN: any error -> allow,
7
+ // never wedge the tool loop on a hook bug.
8
+ const path = require('path');
9
+ const fs = require('fs');
10
+
11
+ const silent = () => process.exit(0);
12
+ const out = (obj) => { process.stdout.write(JSON.stringify(obj)); process.exit(0); };
13
+
14
+ let input = '';
15
+ process.stdin.setEncoding('utf8');
16
+ process.stdin.on('data', (d) => (input += d));
17
+ process.stdin.on('end', () => {
18
+ let evt;
19
+ try { evt = JSON.parse(input); } catch (_) { return silent(); }
20
+ try { run(evt); } catch (_) { silent(); }
21
+ });
22
+
23
+ function run(evt) {
24
+ const projectDir = process.env.CLAUDE_PROJECT_DIR || evt.cwd || '.';
25
+ let ctx;
26
+ try { ctx = require(path.join(projectDir, '.claude/hooks/lib/ctx.js')); } catch (_) { return silent(); }
27
+ const cfg = ctx.loadConfig(projectDir);
28
+ const warn = cfg.warnPct || 60;
29
+ const gate = cfg.gatePct || 78;
30
+
31
+ const u = ctx.contextUsage(evt.transcript_path, cfg);
32
+ if (!u) return silent();
33
+
34
+ const tool = evt.tool_name || '';
35
+ const ti = evt.tool_input || {};
36
+ const band = u.pct >= gate ? 'gate' : u.pct >= warn ? 'warn' : 'ok';
37
+ const BLOCKABLE = new Set(['Edit', 'Write', 'MultiEdit', 'NotebookEdit', 'Task']);
38
+
39
+ // HARD GATE — block new build mutations; reason is fed to the model.
40
+ if (band === 'gate' && BLOCKABLE.has(tool) && !isEscape(tool, ti)) {
41
+ return out({
42
+ hookSpecificOutput: {
43
+ hookEventName: 'PreToolUse',
44
+ permissionDecision: 'deny',
45
+ permissionDecisionReason: gateReason(u, gate),
46
+ },
47
+ });
48
+ }
49
+
50
+ // NON-BLOCKING WARN — emit once each time we climb into a higher band.
51
+ const bandFile = path.join(projectDir, 'docs/.snapshots/.ctx-band');
52
+ const rank = (b) => (b === 'gate' ? 2 : b === 'warn' ? 1 : 0);
53
+ let prev = 'ok';
54
+ try { prev = (fs.readFileSync(bandFile, 'utf8').trim() || 'ok'); } catch (_) {}
55
+
56
+ if (rank(band) !== rank(prev)) {
57
+ try { fs.mkdirSync(path.dirname(bandFile), { recursive: true }); fs.writeFileSync(bandFile, band); } catch (_) {}
58
+ }
59
+ if (rank(band) > rank(prev) && band !== 'ok') {
60
+ return out({
61
+ hookSpecificOutput: {
62
+ hookEventName: 'PreToolUse',
63
+ additionalContext: band === 'gate' ? gateReason(u, gate) : warnReason(u, warn, gate),
64
+ },
65
+ });
66
+ }
67
+ return silent();
68
+ }
69
+
70
+ // Checkpoint/logging writes + the synthesizer ritual are never blocked, so the
71
+ // model always has an escape path out of the gate.
72
+ function isEscape(tool, ti) {
73
+ if (tool === 'Edit' || tool === 'Write' || tool === 'MultiEdit' || tool === 'NotebookEdit') {
74
+ const fp = ti.file_path || ti.path || ti.notebook_path || '';
75
+ return /(^|\/)docs\//.test(fp) || /STATE\.md|ISSUES\.md|\.snapshots\//.test(fp);
76
+ }
77
+ if (tool === 'Task') return (ti.subagent_type || '').toLowerCase() === 'synthesizer';
78
+ return false;
79
+ }
80
+
81
+ const fmt = (n) => (n >= 1000 ? Math.round(n / 1000) + 'k' : String(n));
82
+
83
+ function gateReason(u, gate) {
84
+ return [
85
+ `⛔ CONTEXT GATE — ${u.pct}% (${fmt(u.tokens)}/${fmt(u.window)} tok), เกิน ${gate}% = หยุดเปิดงาน build ใหม่.`,
86
+ 'ทำก่อนไปต่อ:',
87
+ ' 1) ปิด/commit งานค้างให้จบ (Bash/git ไม่ถูก block)',
88
+ ' 2) /synthesize (อัด handoff docs — subagent นี้ไม่ถูก block)',
89
+ ' 3) /clear (session ใหม่ บางลง)',
90
+ 'build ต่อหลัง clear. กลาง irreversible op? ใช้ Bash ปิดให้จบก่อน clear.',
91
+ 'ปลดล็อกชั่วคราว: เพิ่ม gatePct ใน .claude/flow-config.json.',
92
+ ].join('\n');
93
+ }
94
+
95
+ function warnReason(u, warn, gate) {
96
+ return [
97
+ `⚠️ CONTEXT ${u.pct}% (${fmt(u.tokens)}/${fmt(u.window)} tok) — แตะ warn band ${warn}%.`,
98
+ `วางแผนปิด phase: ทยอย /synthesize → /clear ก่อนถึง gate ${gate}% (เลยจุดนั้น hook block งาน build ใหม่).`,
99
+ 'Delegate งาน noisy ให้ subagent เพื่อกัน context โต.',
100
+ ].join('\n');
101
+ }
@@ -0,0 +1,82 @@
1
+ 'use strict';
2
+ // Shared context-budget math for iStartSoftFlow watchdog hooks.
3
+ // Reads the live Claude Code transcript (JSONL) and reports how full the
4
+ // model's context window currently is — from the REAL token usage the API
5
+ // reported, not a heuristic. Pure Node, cross-platform.
6
+ const fs = require('fs');
7
+
8
+ // Known context windows by model-id substring. First match wins. The 1M
9
+ // Opus/Sonnet variants advertise "[1m]" in the model id.
10
+ const WINDOWS = [
11
+ [/\[1m\]|-1m\b|:1m\b|1m-/i, 1000000],
12
+ [/opus|sonnet|haiku|claude/i, 200000],
13
+ ];
14
+
15
+ function inferWindow(model) {
16
+ if (!model) return 200000;
17
+ for (const [re, w] of WINDOWS) if (re.test(model)) return w;
18
+ return 200000;
19
+ }
20
+
21
+ // Read project flow config; returns the `context` block or {}.
22
+ function loadConfig(projectDir) {
23
+ try {
24
+ const cfg = JSON.parse(fs.readFileSync(projectDir + '/.claude/flow-config.json', 'utf8'));
25
+ return (cfg && cfg.context) || {};
26
+ } catch (_) { return {}; }
27
+ }
28
+
29
+ // Read only the last `bytes` of a file (the recent assistant turns live at the
30
+ // tail of the JSONL — no need to load a multi-MB transcript on every tool).
31
+ function readTail(p, bytes) {
32
+ const fd = fs.openSync(p, 'r');
33
+ try {
34
+ const size = fs.fstatSync(fd).size;
35
+ const start = Math.max(0, size - bytes);
36
+ const len = size - start;
37
+ const buf = Buffer.alloc(len);
38
+ fs.readSync(fd, buf, 0, len, start);
39
+ return { text: buf.toString('utf8'), partial: start > 0 };
40
+ } finally { fs.closeSync(fd); }
41
+ }
42
+
43
+ // Scan lines (newest first) for the most recent assistant usage block.
44
+ // input_tokens + cache_read + cache_creation == the full prompt size actually
45
+ // sent == current context occupancy.
46
+ function scanUsage(text, dropFirst) {
47
+ const lines = text.split('\n');
48
+ const lo = dropFirst ? 1 : 0; // first line may be a truncated tail fragment
49
+ for (let i = lines.length - 1; i >= lo; i--) {
50
+ const ln = lines[i].trim();
51
+ if (!ln) continue;
52
+ let obj;
53
+ try { obj = JSON.parse(ln); } catch (_) { continue; }
54
+ const m = obj && obj.message;
55
+ if (m && m.role === 'assistant' && m.usage && typeof m.usage.input_tokens === 'number') {
56
+ return { usage: m.usage, model: m.model || obj.model || null };
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ function contextUsage(transcriptPath, cfg) {
63
+ if (!transcriptPath) return null;
64
+ let hit;
65
+ try {
66
+ const tail = readTail(transcriptPath, 512 * 1024);
67
+ hit = scanUsage(tail.text, tail.partial);
68
+ if (!hit && tail.partial) {
69
+ // usage not in the tail window — fall back to a full read (rare).
70
+ hit = scanUsage(fs.readFileSync(transcriptPath, 'utf8'), false);
71
+ }
72
+ } catch (_) { return null; }
73
+ if (!hit) return null;
74
+ const u = hit.usage;
75
+ const tokens = (u.input_tokens || 0)
76
+ + (u.cache_read_input_tokens || 0)
77
+ + (u.cache_creation_input_tokens || 0);
78
+ const window = (cfg && cfg.window) ? cfg.window : inferWindow(hit.model);
79
+ return { tokens, window, model: hit.model, pct: Math.round((tokens / window) * 100) };
80
+ }
81
+
82
+ module.exports = { contextUsage, inferWindow, loadConfig, readTail, scanUsage };
@@ -174,6 +174,15 @@ Named procedures, each with a canonical body in `.claude/commands/<name>.md`.
174
174
  coverage gate.
175
175
  - **quick [change]** — small, obvious, non-phase change; no agent chain. Stays
176
176
  non-TDD. Runs the mock regression corpus after the change.
177
+ - **ui-audit** — whole-product UI audit against the `ux-design` cookbook (a11y /
178
+ responsive / consistency); scored findings report. Periodic / pre-release. Distinct
179
+ from the per-phase ux-design gate (one screen) — this sweeps every screen.
180
+ - **qa-audit** — whole-product FUNCTIONAL QA audit (coverage gaps, regression health,
181
+ flaky tests, critical-flow e2e, edge/error handling); scored report. The QA
182
+ counterpart of `ui-audit`. Distinct from the per-phase real-suite gate.
183
+ - **security-audit** — whole-product SECURITY audit against the `security` cookbook
184
+ (OWASP/ASVS/WSTG/secrets/SCA/SAST/supply-chain); scored report. On-demand; a
185
+ precondition for the pre-deploy pentest. Distinct from the per-phase rule-11 gate.
177
186
  - **unstuck** — deep re-research after a circuit breaker (auto-run once in AUTO on
178
187
  first stuck; human-triggered in GUIDED).
179
188
  - **synthesize** — compress STATE.md, dedup ISSUES.md, prune snapshots. Run
@@ -332,6 +341,26 @@ development run that follows the spec and logs every problem so it never recurs.
332
341
 
333
342
  -----
334
343
 
344
+ ## Quality model (orthogonal axes — each audited)
345
+
346
+ Quality is checked on independent axes. Passing one NEVER implies another. Each has a
347
+ STANDARD, an inline GATE (per phase), and — for the user-facing ones — a holistic
348
+ AUDIT (whole product, pre-release):
349
+
350
+ | Axis | Question | Standard | Inline gate (per phase) | Whole-product audit |
351
+ |------|----------|----------|-------------------------|---------------------|
352
+ | **Functional / QA** | does it WORK? | blind TDD, RED-first (rules 5–6) | real suite green + regression corpus | full REAL corpus (final phase) · `/qa-audit` |
353
+ | **UI / UX** | is it usable + on-brand? | `ux-design` cookbook | the ux-design check (rule 9) | `/ui-audit` |
354
+ | **Security** | is it safe? | `security` cookbook (OWASP/ASVS/ISO) | secrets/SCA/SAST + secure coding (rule 11) | `/security-audit` · pentest + review before deploy |
355
+ | **Code** | is it consistent? | `code-standards` (naming/architecture) | lint/format + idiom (rule 12) | — |
356
+
357
+ **QA is the test discipline**, not a single agent: `test-author` (blind tests) +
358
+ `e2e-runner` (functional E2E) + the phase gate + the regression corpus + `debugger`.
359
+ UI audit checks *presentation*; QA checks *behaviour* — a button can pass one and
360
+ fail the other.
361
+
362
+ -----
363
+
335
364
  ## Shared KB (optional)
336
365
 
337
366
  If `.claude/kb-config.json` exists, the SESSION-OPEN ritual pulls the KB and loads
@@ -392,7 +421,7 @@ the same everywhere — only the *wiring* differs.
392
421
 
393
422
  | Host | Entry file | Commands | Subagents | Lifecycle hooks | Shared KB |
394
423
  |------|-----------|----------|-----------|-----------------|-----------|
395
- | **Claude Code** (reference) | `AGENTS.md` + `.claude/` | `.claude/commands/` | native | SessionStart · PreCompact · SubagentStop (with context injection) | yes |
424
+ | **Claude Code** (reference) | `CLAUDE.md` (`@AGENTS.md`) + `.claude/` | `.claude/commands/` | native | SessionStart · PreToolUse (context-budget watchdog) · PreCompact · SubagentStop | yes |
396
425
  | **Codex CLI** | `AGENTS.md` (native) | `.claude/commands/` (read as prompts) | read as reference | model-run | yes |
397
426
  | **Cursor** | `.cursor/rules/` + `AGENTS.md` | `.cursor/commands/` | reads `.claude/agents/` | `.cursor/hooks.json` (sessionStart · subagentStop) | yes |
398
427
  | **Gemini CLI** | `GEMINI.md` + `AGENTS.md` | `.claude/commands/` (read as prompts) | read as reference | model-run | yes |
@@ -31,6 +31,10 @@ confirmed with the user before building — design is where human taste matters.
31
31
  - Reviewing a UI diff (the "ตรวจ" pass).
32
32
  - CLOSE gate of any frontend phase — the cookbook check MUST pass.
33
33
 
34
+ This skill is the STANDARD + the inline GATE (one screen, at phase close). For a
35
+ WHOLE-PRODUCT sweep against this same cookbook — periodic or before a release — run
36
+ `/ui-audit` (same rubric, broader scope, a scored report).
37
+
34
38
  Order: **wireframe first** (does the layout match the baseline frame?) ->
35
39
  **cookbook** (do the details obey the system?). Never invent layout the
36
40
  wireframe does not have. If the design truly needs a frame the wireframe lacks,