@andresmassello/uscha 1.51.1 → 1.53.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.
Files changed (98) hide show
  1. package/README.md +24 -5
  2. package/package.json +3 -2
  3. package/uscha-kit/.claude/skills/uscha-adr-refine/SKILL.md +203 -161
  4. package/uscha-kit/.claude/skills/uscha-characterize/SKILL.md +40 -0
  5. package/uscha-kit/.claude/skills/uscha-devloop/SKILL.md +40 -0
  6. package/uscha-kit/.claude/skills/uscha-discovery/SKILL.md +203 -161
  7. package/uscha-kit/.claude/skills/uscha-mirador/SKILL.md +192 -161
  8. package/uscha-kit/.claude/skills/uscha-mirador/mirador-render.py +16 -8
  9. package/uscha-kit/.claude/skills/uscha-reverse-discovery/SKILL.md +42 -0
  10. package/uscha-kit/.claude/skills/uscha-rubric/SKILL.md +119 -79
  11. package/uscha-kit/.claude/skills/uscha-status/SKILL.md +24 -0
  12. package/uscha-kit/.claude/skills/uscha-sysdoc/SKILL.md +128 -88
  13. package/uscha-kit/.claude-plugin/plugin.json +2 -2
  14. package/uscha-kit/.codex-plugin/plugin.json +2 -2
  15. package/uscha-kit/INSTALL.md +3 -0
  16. package/uscha-kit/README.md +1 -1
  17. package/uscha-kit/VERSION +1 -1
  18. package/uscha-kit/install-uscha.py +77 -43
  19. package/uscha-kit/skills/uscha-adr-refine/SKILL.md +203 -161
  20. package/uscha-kit/skills/uscha-characterize/SKILL.md +40 -0
  21. package/uscha-kit/skills/uscha-devloop/SKILL.md +40 -0
  22. package/uscha-kit/skills/uscha-discovery/SKILL.md +203 -161
  23. package/uscha-kit/skills/uscha-mirador/SKILL.md +192 -161
  24. package/uscha-kit/skills/uscha-mirador/mirador-render.py +16 -8
  25. package/uscha-kit/skills/uscha-reverse-discovery/SKILL.md +42 -0
  26. package/uscha-kit/skills/uscha-rubric/SKILL.md +119 -79
  27. package/uscha-kit/skills/uscha-status/SKILL.md +24 -0
  28. package/uscha-kit/skills/uscha-sysdoc/SKILL.md +128 -88
  29. package/uscha-kit/uscha.config.json +1 -1
  30. package/uscha-kit/CHANGELOG-1.10.0.md +0 -84
  31. package/uscha-kit/CHANGELOG-1.11.0.md +0 -67
  32. package/uscha-kit/CHANGELOG-1.12.0.md +0 -46
  33. package/uscha-kit/CHANGELOG-1.13.0.md +0 -33
  34. package/uscha-kit/CHANGELOG-1.14.0.md +0 -42
  35. package/uscha-kit/CHANGELOG-1.15.0.md +0 -58
  36. package/uscha-kit/CHANGELOG-1.16.0.md +0 -55
  37. package/uscha-kit/CHANGELOG-1.17.0.md +0 -44
  38. package/uscha-kit/CHANGELOG-1.18.0.md +0 -42
  39. package/uscha-kit/CHANGELOG-1.19.0.md +0 -41
  40. package/uscha-kit/CHANGELOG-1.2.2.md +0 -16
  41. package/uscha-kit/CHANGELOG-1.2.3.md +0 -20
  42. package/uscha-kit/CHANGELOG-1.2.4.md +0 -10
  43. package/uscha-kit/CHANGELOG-1.2.5.md +0 -23
  44. package/uscha-kit/CHANGELOG-1.2.6.md +0 -11
  45. package/uscha-kit/CHANGELOG-1.2.7.md +0 -15
  46. package/uscha-kit/CHANGELOG-1.2.8.md +0 -24
  47. package/uscha-kit/CHANGELOG-1.2.9.md +0 -4
  48. package/uscha-kit/CHANGELOG-1.20.0.md +0 -29
  49. package/uscha-kit/CHANGELOG-1.21.0.md +0 -33
  50. package/uscha-kit/CHANGELOG-1.22.0.md +0 -60
  51. package/uscha-kit/CHANGELOG-1.23.0.md +0 -75
  52. package/uscha-kit/CHANGELOG-1.24.0.md +0 -50
  53. package/uscha-kit/CHANGELOG-1.25.0.md +0 -55
  54. package/uscha-kit/CHANGELOG-1.26.0.md +0 -70
  55. package/uscha-kit/CHANGELOG-1.27.0.md +0 -45
  56. package/uscha-kit/CHANGELOG-1.28.0.md +0 -35
  57. package/uscha-kit/CHANGELOG-1.29.0.md +0 -20
  58. package/uscha-kit/CHANGELOG-1.3.0.md +0 -74
  59. package/uscha-kit/CHANGELOG-1.30.0.md +0 -46
  60. package/uscha-kit/CHANGELOG-1.31.0.md +0 -59
  61. package/uscha-kit/CHANGELOG-1.32.0.md +0 -50
  62. package/uscha-kit/CHANGELOG-1.33.0.md +0 -46
  63. package/uscha-kit/CHANGELOG-1.34.0.md +0 -55
  64. package/uscha-kit/CHANGELOG-1.35.0.md +0 -30
  65. package/uscha-kit/CHANGELOG-1.36.0.md +0 -33
  66. package/uscha-kit/CHANGELOG-1.37.0.md +0 -41
  67. package/uscha-kit/CHANGELOG-1.38.0.md +0 -11
  68. package/uscha-kit/CHANGELOG-1.39.0.md +0 -14
  69. package/uscha-kit/CHANGELOG-1.4.0.md +0 -68
  70. package/uscha-kit/CHANGELOG-1.40.0.md +0 -16
  71. package/uscha-kit/CHANGELOG-1.40.1.md +0 -11
  72. package/uscha-kit/CHANGELOG-1.40.2.md +0 -13
  73. package/uscha-kit/CHANGELOG-1.41.0.md +0 -18
  74. package/uscha-kit/CHANGELOG-1.41.1.md +0 -53
  75. package/uscha-kit/CHANGELOG-1.41.2.md +0 -34
  76. package/uscha-kit/CHANGELOG-1.41.3.md +0 -30
  77. package/uscha-kit/CHANGELOG-1.42.0.md +0 -41
  78. package/uscha-kit/CHANGELOG-1.43.0.md +0 -37
  79. package/uscha-kit/CHANGELOG-1.44.0.md +0 -90
  80. package/uscha-kit/CHANGELOG-1.44.1.md +0 -26
  81. package/uscha-kit/CHANGELOG-1.45.0.md +0 -58
  82. package/uscha-kit/CHANGELOG-1.46.0.md +0 -50
  83. package/uscha-kit/CHANGELOG-1.46.1.md +0 -35
  84. package/uscha-kit/CHANGELOG-1.47.0.md +0 -45
  85. package/uscha-kit/CHANGELOG-1.48.0.md +0 -35
  86. package/uscha-kit/CHANGELOG-1.48.1.md +0 -55
  87. package/uscha-kit/CHANGELOG-1.48.2.md +0 -47
  88. package/uscha-kit/CHANGELOG-1.49.0.md +0 -45
  89. package/uscha-kit/CHANGELOG-1.5.0.md +0 -64
  90. package/uscha-kit/CHANGELOG-1.50.0.md +0 -52
  91. package/uscha-kit/CHANGELOG-1.50.1.md +0 -52
  92. package/uscha-kit/CHANGELOG-1.50.2.md +0 -62
  93. package/uscha-kit/CHANGELOG-1.51.0.md +0 -44
  94. package/uscha-kit/CHANGELOG-1.51.1.md +0 -33
  95. package/uscha-kit/CHANGELOG-1.6.0.md +0 -57
  96. package/uscha-kit/CHANGELOG-1.7.0.md +0 -74
  97. package/uscha-kit/CHANGELOG-1.8.0.md +0 -46
  98. package/uscha-kit/CHANGELOG-1.9.0.md +0 -112
@@ -1,79 +1,119 @@
1
- ---
2
- name: uscha-rubric
3
- description: >
4
- Grade the change against the versioned RUBRIC.md (the ACCEPTANCE of the
5
- non-testable: conventions, error-handling sanity, API ergonomics, doc quality)
6
- and ingest the verdict into the ledger. This skill is a THIN ADAPTER for
7
- Claude Code: the portable core is templates/rubric-grader-prompt.md (works on
8
- Codex, Gemini CLI, Cursor, raw API, or a human) + the vendor-neutral JSON
9
- contract that `qa_ledger.py rubric-ingest` validates. Advisory by default;
10
- gates only when the human declares it. Invoke for "grade the rubric",
11
- "evaluá la rúbrica", "rubric pass".
12
- allowed-tools: Read, Write, Glob, Grep, Bash
13
- disable-model-invocation: false
14
- ---
15
-
16
- # uscha-rubric — grade the non-testable against versioned criteria (adapter)
17
-
18
- **Architecture note (read this first).** You are the Claude Code ADAPTER of a
19
- vendor-neutral layer. The core is: `RUBRIC.md` (versioned criteria) + the JSON
20
- contract + `qa_ledger.py rubric-ingest` (stdlib, runs anywhere). ANY runner can be
21
- the grader — this skill just wraps the neutral prompt so Claude Code users get it
22
- in one command. Never add Claude-specific behavior to the contract.
23
-
24
- ## Protocol
25
-
26
- 1. **Locate the rubric**: `defaults.rubric.file` in `uscha.config.json`, else
27
- `./RUBRIC.md`. If absent, offer to create one from `templates/RUBRIC.md` and STOP
28
- (the criteria are the human's to approve — propose, don't impose).
29
- 2. **Validate structure first** (facts block):
30
-
31
- ```bash
32
- QL="./.claude/skills/uscha-devloop/qa_ledger.py"
33
- [ -f "$QL" ] || QL="$HOME/.codex/skills/uscha-devloop/qa_ledger.py"
34
- [ -f "$QL" ] || QL="$HOME/plugins/uscha/skills/uscha-devloop/qa_ledger.py"
35
- [ -f "$QL" ] || QL="$HOME/.claude/skills/uscha-devloop/qa_ledger.py"
36
- python3 $QL spec-check --rubric RUBRIC.md # exit 1 = fix the rubric before grading
37
- ```
38
-
39
- 3. **Grade with ISOLATED context** — follow `templates/rubric-grader-prompt.md` to
40
- the letter: read ONLY the diff + RUBRIC.md (not the maker's reasoning, not the PR
41
- body). For every criterion emit `pass|fail`; **evidence `file:line` is mandatory
42
- for any verdict that affects the score** (a positive's pass, a negative's fail) —
43
- without it the engine discards the verdict. Anchors calibrate you; when in doubt,
44
- fail (the optimist bias is the failure mode this layer exists to counter).
45
- 4. **Write the contract JSON** to `reports/rubric-grade.json`:
46
-
47
- ```json
48
- {"criteria": [{"id": "RB-01", "verdict": "pass",
49
- "evidence": "src/x.py:42 — ...", "note": "..."}]}
50
- ```
51
-
52
- 5. **Ingest** (the ledger validates IDs, applies evidence-or-nothing, computes the
53
- weighted score vs threshold, and persists — advisory by default):
54
-
55
- ```bash
56
- python3 $QL rubric-ingest --repo <REPO> --report reports/rubric-grade.json \
57
- --iteration <N> # add --gate ONLY if the human declared it
58
- ```
59
-
60
- A below-threshold score with the gate declared (config `defaults.rubric.gate: true`
61
- or `--gate`) blocks convergence and caps readiness ≤65 through the existing ledger
62
- plumbing. Without the declaration it advises — never silently escalate it yourself.
63
-
64
- ## Non-negotiables
65
-
66
- - **Maker ≠ grader**: never grade a change you authored in this same context. Run
67
- the grade in a fresh/isolated pass (that separation is the entire value).
68
- - **Evidence-or-nothing**: a verdict without a `file:line` citation does not count —
69
- the engine enforces it, you comply with it.
70
- - The rubric file is the HUMAN's criterion: propose edits, never rewrite it silently
71
- (tracked-markdown protocol applies).
72
- - This layer never replaces the hard gates (tests, golden, gate-check, simplicity):
73
- it is the structured-guess layer — facts block, guesses advise.
74
-
75
- ## Relationship to the other skills
76
-
77
- - `uscha-devloop` runs this in Phase 3b alongside gate-check when a rubric exists.
78
- - `uscha-discovery` / `uscha-adr-refine` are where the human's quality criteria
79
- crystallize — a RUBRIC.md can be drafted there (step: quality bar).
1
+ ---
2
+ name: uscha-rubric
3
+ description: >
4
+ Grade the change against the versioned RUBRIC.md (the ACCEPTANCE of the
5
+ non-testable: conventions, error-handling sanity, API ergonomics, doc quality)
6
+ and ingest the verdict into the ledger. This skill is a THIN ADAPTER for
7
+ Claude Code: the portable core is templates/rubric-grader-prompt.md (works on
8
+ Codex, Gemini CLI, Cursor, raw API, or a human) + the vendor-neutral JSON
9
+ contract that `qa_ledger.py rubric-ingest` validates. Advisory by default;
10
+ gates only when the human declares it. Invoke for "grade the rubric",
11
+ "evaluá la rúbrica", "rubric pass".
12
+ allowed-tools: Read, Write, Glob, Grep, Bash
13
+ disable-model-invocation: false
14
+ ---
15
+
16
+ # uscha-rubric — grade the non-testable against versioned criteria (adapter)
17
+
18
+ **Architecture note (read this first).** You are the Claude Code ADAPTER of a
19
+ vendor-neutral layer. The core is: `RUBRIC.md` (versioned criteria) + the JSON
20
+ contract + `qa_ledger.py rubric-ingest` (stdlib, runs anywhere). ANY runner can be
21
+ the grader — this skill just wraps the neutral prompt so Claude Code users get it
22
+ in one command. Never add Claude-specific behavior to the contract.
23
+
24
+ ## Orientation markers (non-negotiable)
25
+
26
+ The operator must never have to ask "where am I?" or "what happens now?". Two markers, always.
27
+ They are navigation, not ceremony: one line per turn, one block at the end.
28
+
29
+ **Open every turn with a breadcrumb**, then the content:
30
+
31
+ `[uscha · rubric · <step> → <target>]`
32
+
33
+ - `<step>` — `Q<n>` for a question, `pass <n>` for a loop iteration, `step <n>` otherwise.
34
+ Count what has actually happened. **Never write a denominator** (`Q4/12`): this phase
35
+ converges, its length is not known in advance, and an invented total is exactly the kind of
36
+ narrated number the method forbids. **When the ledger already measures the count** (the QA
37
+ loop's `loop_count`), use the measured number — never keep a parallel tally of your own.
38
+ - `<target>` — the artifact this turn feeds (`SPEC`, `ADR-003`, `ACCEPTANCE`, `LEDGER`,
39
+ `RECEIVED`, ...). Drop `→ <target>` only when the turn genuinely feeds none.
40
+
41
+ **Close with the close block ONCE, when the skill finishes** — not on every turn. Ending
42
+ without it is a defect, even when the phase converged cleanly:
43
+
44
+ ```
45
+ [uscha · rubric · CLOSED]
46
+ Produced: <files actually written, or "nothing">
47
+ Blocks: <what stands between here and the next phase, or "nothing">
48
+ Next: <the next action, and why it is that one>
49
+ Run: <the exact command or skill to invoke>
50
+ ```
51
+
52
+ This is **not** the implementation handoff some skills also emit: that one is a prompt for
53
+ whoever implements next, this one is navigation for the human operator, and both can appear.
54
+
55
+ `Blocks` and `Next` are **derived from the state you just produced** — never copied from a
56
+ fixed route, **including any `Flow:` line in this file**. Those lines are the nominal path;
57
+ open ADR experiments, an unclosed spike, an unapproved golden or a red gate all change what
58
+ genuinely comes next, and the derived answer wins. If the next phase cannot start yet, name it
59
+ and say exactly what unblocks it.
60
+
61
+ Keep the CONTENT in the conversation's language, but keep the labels (`CLOSED`, `Produced`,
62
+ `Blocks`, `Next`, `Run`) verbatim — they are the method's vocabulary and the smoke checks them.
63
+
64
+ ## Protocol
65
+
66
+ 1. **Locate the rubric**: `defaults.rubric.file` in `uscha.config.json`, else
67
+ `./RUBRIC.md`. If absent, offer to create one from `templates/RUBRIC.md` and STOP
68
+ (the criteria are the human's to approve — propose, don't impose).
69
+ 2. **Validate structure first** (facts block):
70
+
71
+ ```bash
72
+ QL="./.claude/skills/uscha-devloop/qa_ledger.py"
73
+ [ -f "$QL" ] || QL="$HOME/.codex/skills/uscha-devloop/qa_ledger.py"
74
+ [ -f "$QL" ] || QL="$HOME/plugins/uscha/skills/uscha-devloop/qa_ledger.py"
75
+ [ -f "$QL" ] || QL="$HOME/.claude/skills/uscha-devloop/qa_ledger.py"
76
+ python3 $QL spec-check --rubric RUBRIC.md # exit 1 = fix the rubric before grading
77
+ ```
78
+
79
+ 3. **Grade with ISOLATED context** — follow `templates/rubric-grader-prompt.md` to
80
+ the letter: read ONLY the diff + RUBRIC.md (not the maker's reasoning, not the PR
81
+ body). For every criterion emit `pass|fail`; **evidence `file:line` is mandatory
82
+ for any verdict that affects the score** (a positive's pass, a negative's fail) —
83
+ without it the engine discards the verdict. Anchors calibrate you; when in doubt,
84
+ fail (the optimist bias is the failure mode this layer exists to counter).
85
+ 4. **Write the contract JSON** to `reports/rubric-grade.json`:
86
+
87
+ ```json
88
+ {"criteria": [{"id": "RB-01", "verdict": "pass",
89
+ "evidence": "src/x.py:42 — ...", "note": "..."}]}
90
+ ```
91
+
92
+ 5. **Ingest** (the ledger validates IDs, applies evidence-or-nothing, computes the
93
+ weighted score vs threshold, and persists — advisory by default):
94
+
95
+ ```bash
96
+ python3 $QL rubric-ingest --repo <REPO> --report reports/rubric-grade.json \
97
+ --iteration <N> # add --gate ONLY if the human declared it
98
+ ```
99
+
100
+ A below-threshold score with the gate declared (config `defaults.rubric.gate: true`
101
+ or `--gate`) blocks convergence and caps readiness ≤65 through the existing ledger
102
+ plumbing. Without the declaration it advises — never silently escalate it yourself.
103
+
104
+ ## Non-negotiables
105
+
106
+ - **Maker ≠ grader**: never grade a change you authored in this same context. Run
107
+ the grade in a fresh/isolated pass (that separation is the entire value).
108
+ - **Evidence-or-nothing**: a verdict without a `file:line` citation does not count —
109
+ the engine enforces it, you comply with it.
110
+ - The rubric file is the HUMAN's criterion: propose edits, never rewrite it silently
111
+ (tracked-markdown protocol applies).
112
+ - This layer never replaces the hard gates (tests, golden, gate-check, simplicity):
113
+ it is the structured-guess layer — facts block, guesses advise.
114
+
115
+ ## Relationship to the other skills
116
+
117
+ - `uscha-devloop` runs this in Phase 3b alongside gate-check when a rubric exists.
118
+ - `uscha-discovery` / `uscha-adr-refine` are where the human's quality criteria
119
+ crystallize — a RUBRIC.md can be drafted there (step: quality bar).
@@ -19,6 +19,30 @@ skill (**pull** — one screen when the human asks), and the **mirador** (bird's
19
19
  HTML). This skill exists because some surfaces never show a statusline; the answer
20
20
  is the same data, printed in chat when requested.
21
21
 
22
+ ## Orientation markers (non-negotiable)
23
+
24
+ The operator must never have to ask "where am I?" or "what happens now?".
25
+
26
+ This skill is a **one-shot read-only readout**: its block IS the answer. It therefore does NOT
27
+ take the conversational close block — that would be exactly the padding this skill forbids.
28
+ It carries the two minimal markers instead.
29
+
30
+ **Open with a breadcrumb:**
31
+
32
+ `[uscha · status · step <n> → <target>]`
33
+
34
+ **End with the two routing lines, and nothing else:**
35
+
36
+ ```
37
+ Next: <the next action, derived from what this readout just showed>
38
+ Run: <the exact command or skill to invoke>
39
+ ```
40
+
41
+ `Next` is **derived** from the state you just read — never copied from a fixed route,
42
+ including any `Flow:` line in this file. If nothing is actionable, say that plainly rather
43
+ than inventing a step. Keep the CONTENT in the conversation's language and the labels
44
+ (`Next`, `Run`) verbatim — the smoke suite checks for them.
45
+
22
46
  ## Contract
23
47
 
24
48
  - **Read-only over persisted facts.** Never run `readiness`, tests, or gates. The
@@ -1,88 +1,128 @@
1
- ---
2
- name: uscha-sysdoc
3
- description: >
4
- Generate a single self-contained, navigable HTML deck (PowerPoint-style, keyboard +
5
- click navigation) documenting a system in two parallel tracks: a commercial/CEO view
6
- and a technical view. Pulls real metrics from QA-LEDGER.json, includes inline SVG
7
- diagrams, dark control-room aesthetic. Invoke for "document this system",
8
- "make the system deck", "commercial + tech doc". Pairs with the dev-loop skill.
9
- allowed-tools: Read, Write, Glob, Grep, Bash
10
- disable-model-invocation: false
11
- ---
12
-
13
- # sys-doc — two-view system deck generator
14
-
15
- Produce ONE self-contained `.html` file (no external assets, no CDN, no localStorage)
16
- that reads like a slide deck and documents the system on two tracks the reader can
17
- switch between at any time:
18
-
19
- - **Commercial / CEO track** — what the system does, the value, the risk posture, the
20
- status. No code. Plain business language. Money/time/reliability framing.
21
- - **Technical track** — architecture, modules, data flow, contracts, QA results,
22
- coverage, known deferred issues.
23
-
24
- ## Inputs
25
-
26
- 1. **Metrics (authoritative):** run the ledger summary and use its numbers verbatim —
27
- never invent figures.
28
-
29
- ```bash
30
- QL="./.claude/skills/uscha-devloop/qa_ledger.py" # instalacion por proyecto
31
- [ -f "$QL" ] || QL="$HOME/.codex/skills/uscha-devloop/qa_ledger.py" # Codex raw-skills install
32
- [ -f "$QL" ] || QL="$HOME/plugins/uscha/skills/uscha-devloop/qa_ledger.py" # Codex plugin install
33
- [ -f "$QL" ] || QL="$HOME/.claude/skills/uscha-devloop/qa_ledger.py" # Claude global install
34
- python3 $QL summary --json > /tmp/qa-summary.json
35
- python3 $QL readiness --json > /tmp/qa-readiness.json
36
- ```
37
-
38
- From the summary use: `total_steps`, `by_tool`, `by_repo`, `aggregate`, `escalations`.
39
- From readiness use: `score`, `status`, `cap_reason`, `dimensions`, `acceptance`,
40
- `by_repo`. Render readiness as a **semaphore widget** at the top of slide 5 and as a
41
- per-repo readiness column on the technical QA slide: green ≥80, amber 50–79, red <50,
42
- and always print the `cap_reason` when a hard cap is active.
43
-
44
- 2. **System understanding:** read the ADR/PLAN, CLAUDE.md, module layout, and key
45
- contracts to describe architecture and value. If no ledger exists, ask whether to
46
- proceed without QA metrics (the deck still works, just without the QA section).
47
-
48
- 3. **Tracked-markdown protocol:** the HTML output itself is not tracked markdown, so
49
- generate freely. But if asked to also update a tracked `.md`, ask for its current
50
- version first.
51
-
52
- ## Structure (each is one navigable slide)
53
-
54
- 1. **Title** — system name, one-line purpose, date, run id.
55
- 2. **Track switcher** — persistent toggle: Commercial ⇄ Technical (affects which
56
- slides/sections show; default Commercial).
57
- 3. Commercial: **What it does** (plain language, the job it removes).
58
- 4. Commercial: **Value & status** (what's done, what's in flight, risk posture).
59
- 5. Commercial: **Quality at a glance** — coverage %, tests count, a simple
60
- "issues found and resolved" readout from `by_tool`. No jargon.
61
- 6. Technical: **Architecture** — inline SVG: modules/repos as boxes, data flow as
62
- arrows, external systems (DB, external APIs, devices) distinct.
63
- 7. Technical: **Key contracts / interfaces** — the seams between repos/modules.
64
- 8. Technical: **QA results** — per-tool table (reported / fixed / %fixed / deferred /
65
- suppressed), coverage per repo, tests/kLOC, escalations list.
66
- 9. Technical: **Deferred issues** — summarize `ISSUES-DEFERRED.md` honestly.
67
- 10. **Smoke checklist** — the manual verification steps.
68
-
69
- ## Build constraints
70
-
71
- - Single `.html`, all CSS/JS inline. Works opened directly from disk and deployable to
72
- Cloudflare Pages / S3 as-is.
73
- - **No localStorage / sessionStorage** (won't run in some sandboxes). Hold nav state in
74
- JS variables only.
75
- - Navigation: arrow keys (← →), on-screen prev/next, a slide index/dots, and Esc for an
76
- overview grid. Slide counter visible.
77
- - Diagrams are hand-authored inline `<svg>` using `currentColor`/CSS variables so they
78
- theme with the deck. No raster images, no external diagram libs.
79
- - Aesthetic: dark control-room (deep neutral background, one accent, high-contrast
80
- mono for technical figures), but keep the Commercial track clean and uncluttered.
81
- - Accessible: semantic headings, `aria-label`s on nav controls, visible focus, contrast
82
- AA. Readable when printed (print stylesheet flattens slides to a linear document).
83
-
84
- ## Output
85
-
86
- Write to `docs/system-deck.html` (or the path the human gives). Then state the file
87
- path and the two or three things the reader should look at first. Do not paste the HTML
88
- into chat — present the file.
1
+ ---
2
+ name: uscha-sysdoc
3
+ description: >
4
+ Generate a single self-contained, navigable HTML deck (PowerPoint-style, keyboard +
5
+ click navigation) documenting a system in two parallel tracks: a commercial/CEO view
6
+ and a technical view. Pulls real metrics from QA-LEDGER.json, includes inline SVG
7
+ diagrams, dark control-room aesthetic. Invoke for "document this system",
8
+ "make the system deck", "commercial + tech doc". Pairs with the dev-loop skill.
9
+ allowed-tools: Read, Write, Glob, Grep, Bash
10
+ disable-model-invocation: false
11
+ ---
12
+
13
+ # sys-doc — two-view system deck generator
14
+
15
+ Produce ONE self-contained `.html` file (no external assets, no CDN, no localStorage)
16
+ that reads like a slide deck and documents the system on two tracks the reader can
17
+ switch between at any time:
18
+
19
+ - **Commercial / CEO track** — what the system does, the value, the risk posture, the
20
+ status. No code. Plain business language. Money/time/reliability framing.
21
+ - **Technical track** — architecture, modules, data flow, contracts, QA results,
22
+ coverage, known deferred issues.
23
+
24
+ ## Orientation markers (non-negotiable)
25
+
26
+ The operator must never have to ask "where am I?" or "what happens now?". Two markers, always.
27
+ They are navigation, not ceremony: one line per turn, one block at the end.
28
+
29
+ **Open every turn with a breadcrumb**, then the content:
30
+
31
+ `[uscha · sysdoc · <step> → <target>]`
32
+
33
+ - `<step>` — `Q<n>` for a question, `pass <n>` for a loop iteration, `step <n>` otherwise.
34
+ Count what has actually happened. **Never write a denominator** (`Q4/12`): this phase
35
+ converges, its length is not known in advance, and an invented total is exactly the kind of
36
+ narrated number the method forbids. **When the ledger already measures the count** (the QA
37
+ loop's `loop_count`), use the measured number — never keep a parallel tally of your own.
38
+ - `<target>` — the artifact this turn feeds (`SPEC`, `ADR-003`, `ACCEPTANCE`, `LEDGER`,
39
+ `RECEIVED`, ...). Drop `→ <target>` only when the turn genuinely feeds none.
40
+
41
+ **Close with the close block ONCE, when the skill finishes** — not on every turn. Ending
42
+ without it is a defect, even when the phase converged cleanly:
43
+
44
+ ```
45
+ [uscha · sysdoc · CLOSED]
46
+ Produced: <files actually written, or "nothing">
47
+ Blocks: <what stands between here and the next phase, or "nothing">
48
+ Next: <the next action, and why it is that one>
49
+ Run: <the exact command or skill to invoke>
50
+ ```
51
+
52
+ This is **not** the implementation handoff some skills also emit: that one is a prompt for
53
+ whoever implements next, this one is navigation for the human operator, and both can appear.
54
+
55
+ `Blocks` and `Next` are **derived from the state you just produced** — never copied from a
56
+ fixed route, **including any `Flow:` line in this file**. Those lines are the nominal path;
57
+ open ADR experiments, an unclosed spike, an unapproved golden or a red gate all change what
58
+ genuinely comes next, and the derived answer wins. If the next phase cannot start yet, name it
59
+ and say exactly what unblocks it.
60
+
61
+ Keep the CONTENT in the conversation's language, but keep the labels (`CLOSED`, `Produced`,
62
+ `Blocks`, `Next`, `Run`) verbatim — they are the method's vocabulary and the smoke checks them.
63
+
64
+ ## Inputs
65
+
66
+ 1. **Metrics (authoritative):** run the ledger summary and use its numbers verbatim —
67
+ never invent figures.
68
+
69
+ ```bash
70
+ QL="./.claude/skills/uscha-devloop/qa_ledger.py" # instalacion por proyecto
71
+ [ -f "$QL" ] || QL="$HOME/.codex/skills/uscha-devloop/qa_ledger.py" # Codex raw-skills install
72
+ [ -f "$QL" ] || QL="$HOME/plugins/uscha/skills/uscha-devloop/qa_ledger.py" # Codex plugin install
73
+ [ -f "$QL" ] || QL="$HOME/.claude/skills/uscha-devloop/qa_ledger.py" # Claude global install
74
+ python3 $QL summary --json > /tmp/qa-summary.json
75
+ python3 $QL readiness --json > /tmp/qa-readiness.json
76
+ ```
77
+
78
+ From the summary use: `total_steps`, `by_tool`, `by_repo`, `aggregate`, `escalations`.
79
+ From readiness use: `score`, `status`, `cap_reason`, `dimensions`, `acceptance`,
80
+ `by_repo`. Render readiness as a **semaphore widget** at the top of slide 5 and as a
81
+ per-repo readiness column on the technical QA slide: green ≥80, amber 50–79, red <50,
82
+ and always print the `cap_reason` when a hard cap is active.
83
+
84
+ 2. **System understanding:** read the ADR/PLAN, CLAUDE.md, module layout, and key
85
+ contracts to describe architecture and value. If no ledger exists, ask whether to
86
+ proceed without QA metrics (the deck still works, just without the QA section).
87
+
88
+ 3. **Tracked-markdown protocol:** the HTML output itself is not tracked markdown, so
89
+ generate freely. But if asked to also update a tracked `.md`, ask for its current
90
+ version first.
91
+
92
+ ## Structure (each is one navigable slide)
93
+
94
+ 1. **Title** — system name, one-line purpose, date, run id.
95
+ 2. **Track switcher** — persistent toggle: Commercial ⇄ Technical (affects which
96
+ slides/sections show; default Commercial).
97
+ 3. Commercial: **What it does** (plain language, the job it removes).
98
+ 4. Commercial: **Value & status** (what's done, what's in flight, risk posture).
99
+ 5. Commercial: **Quality at a glance** — coverage %, tests count, a simple
100
+ "issues found and resolved" readout from `by_tool`. No jargon.
101
+ 6. Technical: **Architecture** — inline SVG: modules/repos as boxes, data flow as
102
+ arrows, external systems (DB, external APIs, devices) distinct.
103
+ 7. Technical: **Key contracts / interfaces** — the seams between repos/modules.
104
+ 8. Technical: **QA results** — per-tool table (reported / fixed / %fixed / deferred /
105
+ suppressed), coverage per repo, tests/kLOC, escalations list.
106
+ 9. Technical: **Deferred issues** — summarize `ISSUES-DEFERRED.md` honestly.
107
+ 10. **Smoke checklist** — the manual verification steps.
108
+
109
+ ## Build constraints
110
+
111
+ - Single `.html`, all CSS/JS inline. Works opened directly from disk and deployable to
112
+ Cloudflare Pages / S3 as-is.
113
+ - **No localStorage / sessionStorage** (won't run in some sandboxes). Hold nav state in
114
+ JS variables only.
115
+ - Navigation: arrow keys (← →), on-screen prev/next, a slide index/dots, and Esc for an
116
+ overview grid. Slide counter visible.
117
+ - Diagrams are hand-authored inline `<svg>` using `currentColor`/CSS variables so they
118
+ theme with the deck. No raster images, no external diagram libs.
119
+ - Aesthetic: dark control-room (deep neutral background, one accent, high-contrast
120
+ mono for technical figures), but keep the Commercial track clean and uncluttered.
121
+ - Accessible: semantic headings, `aria-label`s on nav controls, visible focus, contrast
122
+ AA. Readable when printed (print stylesheet flattens slides to a linear document).
123
+
124
+ ## Output
125
+
126
+ Write to `docs/system-deck.html` (or the path the human gives). Then state the file
127
+ path and the two or three things the reader should look at first. Do not paste the HTML
128
+ into chat — present the file.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.51.1",
2
+ "version": "1.53.0",
3
3
  "project": null,
4
4
  "defaults": {
5
5
  "coverage_threshold": 60,
@@ -1,84 +0,0 @@
1
- # dev-loop-kit 1.10.0 — acceptance trazable: AC-n cierra por testcase MEDIDO (2026-07-02)
2
-
3
- Primera mejora del backlog PragProg (M2 de `docs/analisis-pragmatic-programmer.md`;
4
- Topic 50 "Do What Works" + la anécdota Jeffries/Sudoku + Tip 94 "Find Bugs Once").
5
- Ataca el modo de falla típico del agente: **pulir la métrica sin acercarse a la
6
- solución**. El readiness deja de estar dominado por coverage/tests-verdes y pasa a
7
- estar dominado por **criterios de aceptación cerrados con evidencia medida**.
8
- Smoke suite: 68/68.
9
-
10
- ## La idea (measured beats narrated, ahora a nivel CRITERIO)
11
-
12
- - Cada criterio de `ACCEPTANCE.md` lleva un ID estable: `- [ ] AC-01 — cuando X
13
- entonces Y`.
14
- - Un criterio cierra **MEDIDO** solo cuando existe ≥1 testcase VERDE cuyo nombre
15
- lleva el tag (`test_ac1_x`, `testAC01X`, `"AC-01: ..."`) en los reportes JUnit
16
- que el engine ya ingiere — y **ningún** testcase taggeado en rojo (evidencia
17
- roja veta: fail-closed).
18
- - El checkbox es RELATO; el testcase es HECHO. Un `[x]` sin test verde se
19
- reporta como `narrated_only` y NO cierra.
20
-
21
- ## Engine (qa_ledger.py)
22
-
23
- - `_parse_acceptance_items()`: parser de checkboxes con ID opcional; IDs
24
- normalizados por número (`AC-01 == AC_1 == ac1` — los nombres de test de
25
- python/go no admiten `-`).
26
- - `_ac_tags()`: scan de NOMBRES de testcase en los reportes JUnit por type
27
- (reusa el selector de ubicaciones vía `_junit_report_files()`, extraído para
28
- no duplicar la lista — surefire/gradle per-clase, junit-family, dual-file
29
- swift; flutter no emite JUnit → sus criterios no cierran medido, documentado).
30
- Boundaries explícitos en el regex del tag: `\b` NO sirve (`_` es word char y
31
- `test_ac1` quedaría invisible); soporta separador no-alfanumérico y camelCase.
32
- - `readiness`: nueva dimensión **acceptance** (dominante, peso 30) = criterios
33
- cerrados medidos / criterios totales (un criterio sin ID no puede cerrar →
34
- cuenta como abierto). Pesos default rebalanceados:
35
- acceptance 30 · adr 15 · coverage 15 · static 20 · convergencia 10 ·
36
- integración 10 — el techo a coverage/verde es el anti-Goodhart. JSON expone
37
- `traceable/ids/measured_closed/narrated_only/measured_unchecked/untagged`;
38
- warnings en texto para narrated-only y sin-IDs.
39
- - **Fallback legacy**: ACCEPTANCE sin ningún AC-ID → la dimensión cae al ratio
40
- de checkboxes con warning (adopción incremental, no rotura retroactiva).
41
- - `spec-check --acceptance ACCEPTANCE.md`: la trazabilidad es estructura =
42
- FACT → bloquea: archivo ausente, cero criterios, CERO criterios trazables,
43
- IDs duplicados (normalizados). Criterios sueltos sin ID = advisory. Puede
44
- correr solo (sin `--spec`).
45
-
46
- ## Skills / docs
47
-
48
- - `discovery`: ACCEPTANCE se genera con AC-NN secuenciales, nunca reusados;
49
- cada criterio pensado para ser cubrible por un test con nombre.
50
- - `dev-loop`: al escribir los tests de un criterio, el tag AC-n va en el nombre
51
- del test; `spec-check --acceptance` al arrancar.
52
-
53
- ## Hardening (review fresco pre-commit, 10 hallazgos aplicados)
54
-
55
- - `_ac_tags`: el tag ahora lee SOLO el nombre del testcase (nunca classname) —
56
- un módulo/clase que matchea "ACn" por coincidencia (`test_ac3_flow.py`) ya no
57
- contamina los OTROS tests del mismo archivo.
58
- - `_AC_ID`: tolera IDs markdown-formateados (`**AC-01**`, `` `AC-01` ``) — antes
59
- degradaban en silencio a `id=None` y toda la trazabilidad caía a legacy.
60
- - `readiness`: IDs duplicados en ACCEPTANCE cuentan **una sola vez** (antes un
61
- test verde podía cerrar "medido" tantos criterios como copias del ID).
62
- - `readiness`: config pre-1.10.0 con `readiness_weights` explícitos que no
63
- conocían `acceptance` ya no la reciben inyectada por default — se excluye
64
- (peso 0) con warning hasta que el usuario la agregue o taggee AC-IDs (si no,
65
- duplicaba el peso de `adr` en silencio).
66
- - `readiness`: `--section` sin match ahora avisa (`0 criterios en scope`) en
67
- vez de zonear en silencio adr+acceptance.
68
- - `readiness`: ledger sin `config.repos` ya no crashea (KeyError) — usa
69
- `.get("repos", [])` como el resto del comando.
70
- - `spec-check --acceptance`: pipear un SPEC por stdin junto con `--acceptance`
71
- ya no se descarta en silencio — se lee stdin salvo modo interactivo puro
72
- acceptance-only.
73
- - `spec-check --acceptance --strict`: los criterios sin AC-ID ahora gatean
74
- `--strict` (antes el verdict imprimía "OK" con advisories pendientes).
75
- - Documentado (no resuelto): reportes JUnit stale de maven/gradle pueden
76
- vetear/cerrar un AC sin evidencia vigente — mismo límite que
77
- `junit_test_count`, ahora con blast radius mayor. Mitigación real (mtime +
78
- correlación con el árbol de fuentes) diferida.
79
-
80
- ## Diferido consciente
81
-
82
- - El resto del backlog PragProg (M1 regression-capture, M3 ledger atómico,
83
- M8 secret-scan, M9 tests fuera del presupuesto de simplicity, etc.) sigue en
84
- `docs/analisis-pragmatic-programmer.md` — una mejora por release.
@@ -1,67 +0,0 @@
1
- # dev-loop-kit 1.11.0 — tests fuera del presupuesto de simplicity (2026-07-03)
2
-
3
- Segunda mejora del backlog PragProg (M9 de `docs/analisis-pragmatic-programmer.md`;
4
- Topic 51: *"un buen proyecto puede tener MÁS código de test que de producción, y
5
- vale la pena"*). Elimina un **incentivo perverso activo**: el simplicity-check
6
- contaba las líneas de test junto a las de producción contra un único presupuesto —
7
- el gate castigaba escribir tests y empujaba al agente a testear menos para pasar.
8
- Smoke suite: 73/73.
9
-
10
- ## La idea
11
-
12
- - Escribir tests **nunca** acerca un diff a OVERBUILT. Los archivos de test se
13
- detectan, se cuentan y se **reportan aparte** (`test_lines_added`,
14
- `test_files_changed`) — pero no gatean ninguna dimensión del score.
15
- - La otra dirección ya estaba protegida: **borrar** tests lo bloquea gate-check.
16
- Con esto el incentivo queda alineado en ambas direcciones.
17
-
18
- ## Engine (qa_ledger.py)
19
-
20
- - `_is_simplicity_test_file()`: clasificador type-agnóstico (el diff no trae
21
- `repo_type`) — unión de las convenciones de los 9 stacks: dirs
22
- `test/tests/__tests__/Tests/*.Tests`, source sets Gradle (`src/*Test/`),
23
- `test_*.py`, `*_test.go`, `*.test.ts`/`*.spec.js` (multi-dot incluido),
24
- `*Test.java`/`*Tests.cs` CamelCase **case-sensitive** — `backtest.cpp` /
25
- `protest.cc` siguen contando como producción (misma trampa que ya evitan
26
- dotnet/cpp en `_is_test_path`).
27
- - Dirección de fallo benigna y documentada: un falso positivo solo EXIME del
28
- presupuesto — nunca bloquea ni borra nada.
29
- - `_simplicity_metrics()`: tercer estado de conteo (`prod`/`test`/fuera);
30
- las líneas de test no alimentan `lines_added`, `net_lines`, `files_changed`,
31
- `max_nesting`, `max_hunk_added` ni abstracciones. Output humano: línea
32
- informativa "tests FUERA del presupuesto: +N líneas en M archivo(s)".
33
-
34
- ## Smoke
35
-
36
- - **T32**: diff sintético 6 líneas prod + 302 de test → el presupuesto ve 6/1;
37
- batería del clasificador (9 convenciones positivas + backtest/protest/Engine
38
- negativas).
39
- - **T31** (edges 1.10.0, deuda del release anterior): batería de falsos
40
- positivos del tag regex (`HVAC2`, `mac1`, `track12` no taggean), classname
41
- jamás taggea, y semántica flaky de surefire (`<flakyFailure>` que pasó tras
42
- retry = verde; `<failure>`+`<rerunFailure>` = rojo, veta).
43
-
44
- ## Hardening (review fresco pre-commit)
45
-
46
- - El review detectó que gate-check tenía SU PROPIO clasificador de tests
47
- (`_gc_is_test_file`) más débil: no reconocía `foo_test.go` (Go),
48
- `*.Tests/*.cs` (dotnet), `*.spec.tsx` ni `__tests__/` — así que "borrar
49
- tests lo bloquea gate-check" era overclaim para 4+ stacks. Fix: unión
50
- fail-closed — gate-check reusa el clasificador compartido de los 9 stacks
51
- MÁS sus sufijos legacy; solo se AMPLÍA qué cuenta como test, ningún path
52
- antes protegido se desprotege.
53
- - `_GC_TESTDEF` ampliado con las definiciones de test que faltaban:
54
- `func TestX` (Go), `[Fact]`/`[Theory]` (xunit), `#[test]` (rust),
55
- `it(`/`test(`/`describe(` (js) — seguro porque TESTDEF solo se evalúa
56
- dentro de archivos ya clasificados como test.
57
- - Smoke **T33**: borrado de tests Go/dotnet/JS → BLOCKER (antes invisible).
58
- - Corrección truth-pass en `dev-loop-kit/README.md`: los pesos documentados
59
- de simplicity (`diff_size 30, nesting 25, abstraction 20...`) no coincidían
60
- con el engine (`35/30/20/8/7`, abstraction advisory sin peso) — drift
61
- pre-existente, alineado acá.
62
-
63
- ## Diferido consciente
64
-
65
- - El resto del backlog PragProg (M1 regression-capture, M3 ledger atómico,
66
- M8 secret-scan, etc.) sigue en `docs/analisis-pragmatic-programmer.md` —
67
- una mejora por release.