@andresmassello/uscha 1.40.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/LICENSE +21 -0
- package/README.md +104 -0
- package/bin/README.md +6 -0
- package/bin/uscha.js +28 -0
- package/package.json +38 -0
- package/uscha-kit/.claude/skills/uscha-adr-refine/SKILL.md +161 -0
- package/uscha-kit/.claude/skills/uscha-characterize/SKILL.md +124 -0
- package/uscha-kit/.claude/skills/uscha-devloop/SKILL.md +490 -0
- package/uscha-kit/.claude/skills/uscha-devloop/qa_ledger.py +5602 -0
- package/uscha-kit/.claude/skills/uscha-discovery/SKILL.md +161 -0
- package/uscha-kit/.claude/skills/uscha-mirador/SKILL.md +145 -0
- package/uscha-kit/.claude/skills/uscha-mirador/mirador-render.py +112 -0
- package/uscha-kit/.claude/skills/uscha-mirador/mirador-watch.ps1 +22 -0
- package/uscha-kit/.claude/skills/uscha-mirador/mirador-watch.sh +26 -0
- package/uscha-kit/.claude/skills/uscha-mirador/mirador.template.html +586 -0
- package/uscha-kit/.claude/skills/uscha-mirador/telemetry-extract.py +130 -0
- package/uscha-kit/.claude/skills/uscha-reverse-discovery/SKILL.md +116 -0
- package/uscha-kit/.claude/skills/uscha-rubric/SKILL.md +79 -0
- package/uscha-kit/.claude/skills/uscha-sysdoc/SKILL.md +88 -0
- package/uscha-kit/.claude-plugin/plugin.json +24 -0
- package/uscha-kit/.codex-plugin/plugin.json +37 -0
- package/uscha-kit/CHANGELOG-1.10.0.md +84 -0
- package/uscha-kit/CHANGELOG-1.11.0.md +67 -0
- package/uscha-kit/CHANGELOG-1.12.0.md +46 -0
- package/uscha-kit/CHANGELOG-1.13.0.md +33 -0
- package/uscha-kit/CHANGELOG-1.14.0.md +42 -0
- package/uscha-kit/CHANGELOG-1.15.0.md +58 -0
- package/uscha-kit/CHANGELOG-1.16.0.md +55 -0
- package/uscha-kit/CHANGELOG-1.17.0.md +44 -0
- package/uscha-kit/CHANGELOG-1.18.0.md +42 -0
- package/uscha-kit/CHANGELOG-1.19.0.md +41 -0
- package/uscha-kit/CHANGELOG-1.2.2.md +16 -0
- package/uscha-kit/CHANGELOG-1.2.3.md +20 -0
- package/uscha-kit/CHANGELOG-1.2.4.md +10 -0
- package/uscha-kit/CHANGELOG-1.2.5.md +23 -0
- package/uscha-kit/CHANGELOG-1.2.6.md +11 -0
- package/uscha-kit/CHANGELOG-1.2.7.md +15 -0
- package/uscha-kit/CHANGELOG-1.2.8.md +24 -0
- package/uscha-kit/CHANGELOG-1.2.9.md +4 -0
- package/uscha-kit/CHANGELOG-1.20.0.md +29 -0
- package/uscha-kit/CHANGELOG-1.21.0.md +33 -0
- package/uscha-kit/CHANGELOG-1.22.0.md +60 -0
- package/uscha-kit/CHANGELOG-1.23.0.md +75 -0
- package/uscha-kit/CHANGELOG-1.24.0.md +50 -0
- package/uscha-kit/CHANGELOG-1.25.0.md +55 -0
- package/uscha-kit/CHANGELOG-1.26.0.md +70 -0
- package/uscha-kit/CHANGELOG-1.27.0.md +45 -0
- package/uscha-kit/CHANGELOG-1.28.0.md +35 -0
- package/uscha-kit/CHANGELOG-1.29.0.md +20 -0
- package/uscha-kit/CHANGELOG-1.3.0.md +74 -0
- package/uscha-kit/CHANGELOG-1.30.0.md +46 -0
- package/uscha-kit/CHANGELOG-1.31.0.md +59 -0
- package/uscha-kit/CHANGELOG-1.32.0.md +50 -0
- package/uscha-kit/CHANGELOG-1.33.0.md +46 -0
- package/uscha-kit/CHANGELOG-1.34.0.md +55 -0
- package/uscha-kit/CHANGELOG-1.35.0.md +30 -0
- package/uscha-kit/CHANGELOG-1.36.0.md +33 -0
- package/uscha-kit/CHANGELOG-1.37.0.md +41 -0
- package/uscha-kit/CHANGELOG-1.38.0.md +11 -0
- package/uscha-kit/CHANGELOG-1.39.0.md +14 -0
- package/uscha-kit/CHANGELOG-1.4.0.md +68 -0
- package/uscha-kit/CHANGELOG-1.40.0.md +16 -0
- package/uscha-kit/CHANGELOG-1.40.1.md +11 -0
- package/uscha-kit/CHANGELOG-1.5.0.md +64 -0
- package/uscha-kit/CHANGELOG-1.6.0.md +57 -0
- package/uscha-kit/CHANGELOG-1.7.0.md +74 -0
- package/uscha-kit/CHANGELOG-1.8.0.md +46 -0
- package/uscha-kit/CHANGELOG-1.9.0.md +112 -0
- package/uscha-kit/LICENSE +21 -0
- package/uscha-kit/README.md +497 -0
- package/uscha-kit/VERSION +1 -0
- package/uscha-kit/WORKBENCH.md +178 -0
- package/uscha-kit/hooks/block-approved-writes.ps1 +46 -0
- package/uscha-kit/hooks/hooks.json +15 -0
- package/uscha-kit/install-uscha.py +344 -0
- package/uscha-kit/skills/uscha-adr-refine/SKILL.md +161 -0
- package/uscha-kit/skills/uscha-characterize/SKILL.md +124 -0
- package/uscha-kit/skills/uscha-devloop/SKILL.md +490 -0
- package/uscha-kit/skills/uscha-devloop/qa_ledger.py +5602 -0
- package/uscha-kit/skills/uscha-discovery/SKILL.md +161 -0
- package/uscha-kit/skills/uscha-mirador/SKILL.md +145 -0
- package/uscha-kit/skills/uscha-mirador/mirador-render.py +112 -0
- package/uscha-kit/skills/uscha-mirador/mirador-watch.ps1 +22 -0
- package/uscha-kit/skills/uscha-mirador/mirador-watch.sh +26 -0
- package/uscha-kit/skills/uscha-mirador/mirador.template.html +586 -0
- package/uscha-kit/skills/uscha-mirador/telemetry-extract.py +130 -0
- package/uscha-kit/skills/uscha-reverse-discovery/SKILL.md +116 -0
- package/uscha-kit/skills/uscha-rubric/SKILL.md +79 -0
- package/uscha-kit/skills/uscha-sysdoc/SKILL.md +88 -0
- package/uscha-kit/templates/.gitattributes +6 -0
- package/uscha-kit/templates/CLAUDE.md +56 -0
- package/uscha-kit/templates/CONSTITUTION.md +149 -0
- package/uscha-kit/templates/RUBRIC.md +38 -0
- package/uscha-kit/templates/docs/adr/README.md +19 -0
- package/uscha-kit/templates/rubric-grader-prompt.md +63 -0
- package/uscha-kit/tests/smoke-engine.sh +1739 -0
- package/uscha-kit/uscha.config.json +181 -0
- package/uscha-kit/workbench-doctor.sh +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Andres Massello
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Uscha
|
|
2
|
+
|
|
3
|
+
**Uscha** is a spec-driven, tool-agnostic methodology for development with
|
|
4
|
+
LLM coding agents — *you bring the idea, the method builds the rest* — with its
|
|
5
|
+
instantiation in Claude Code, the **uscha-kit**.
|
|
6
|
+
|
|
7
|
+
> **On the name.** *Uscha* is the methodology's name; the pattern it operationalizes is a *spec-loop* — the concept, not the branding. The name was chosen partly to avoid collision with [spec-loop](https://github.com/dpolivaev/spec-loop) by D. Polivaev — an independently developed, actively maintained project that shares the term and the spec-driven, review-per-increment philosophy while taking a different implementation path (shell-based agent skills via npx). It was found late in this project's development; the two are convergent, not derivative. (The local checkout keeps the path `SpecLoop`.)
|
|
8
|
+
|
|
9
|
+
> The tool executes · the method governs · evidence decides · the human approves.
|
|
10
|
+
|
|
11
|
+
## Repo map
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
SpecLoop/
|
|
15
|
+
├── uscha-kit/ # ★ canonical SOURCE of the kit (v1.40.1)
|
|
16
|
+
│ ├── .claude/skills/ # 8 skills: uscha-discovery · uscha-adr-refine · uscha-devloop · uscha-sysdoc
|
|
17
|
+
│ │ # uscha-reverse-discovery · uscha-characterize · uscha-rubric · uscha-mirador
|
|
18
|
+
│ ├── .claude/skills/uscha-devloop/qa_ledger.py # evidence engine (29 subcommands, stdlib)
|
|
19
|
+
│ ├── hooks/ # PreToolUse: the agent never writes .approved (INV-GOLDEN-01)
|
|
20
|
+
│ ├── templates/ # CLAUDE.md · CONSTITUTION.md · .gitattributes · docs/adr
|
|
21
|
+
│ └── CHANGELOG-*.md # 1.2.x → 1.3.0 ("facts block, wired") → 1.4.0 (python) → 1.5.0 (node) → 1.6.0 (go) → 1.7.0 (rust+dotnet) → 1.8.0 (cpp) → 1.9.0 (gradle+swift) → 1.10.0 (traceable acceptance) → 1.11.0 (tests outside the budget) → 1.12.0 (secret-scan) → 1.13.0 (atomic ledger) → 1.14.0 (plateau/stop-signal) → 1.15.0 (golden scrub) → 1.16.0 (regression-capture) → 1.17.0 (threshold provenance) → 1.18.0 (derived FSM) → 1.19.0 (spikes — PragProg backlog CLOSED) → 1.20.0 (global install) → 1.21.0 (namespace uscha-*) → 1.22.0 (doctor) → 1.23.0 (rubric layer) → 1.24.0 (Claude Code plugin) → 1.25.0 (anti-ceremony) → 1.26.0 (waste-check REUSE-FIRST) → 1.27.0 (FTY) → 1.28.0 (measured acceptance %) → 1.29.0 (rebrand → Uscha) → 1.30.0 (dependency gate) → 1.31.0 (evidence freshness + doc-version gate) → 1.32.0 (mirador — bird's-eye view + dashboard --json) → 1.33.0 (mirador telemetry — per-model tokens/time/model + transcript extractor) → 1.34.0 (mirador: project name from config + live watch/auto-refresh) -> 1.35.0 (execution-policy routing) -> 1.36.0 (discovery-intake: production findings + spec-doubt) -> 1.37.0 (ADR experiments: visible hypotheses) -> 1.38.0 (contract closure: SCR bridge + golden labels + calibration) -> 1.39.0 (universal Codex/Claude installer) -> 1.40.1 (npm/npx router)
|
|
22
|
+
├── docs/ # published artifacts (canonical here; Downloads = snapshots)
|
|
23
|
+
│ ├── uscha-claude-code-doc-FINAL.html # long deck ES (36 slides)
|
|
24
|
+
│ ├── uscha-claude-code-doc-EN.html # long deck EN
|
|
25
|
+
│ ├── uscha-playbook{,-EN}.html # Operator's Manual (trigger/move/gate)
|
|
26
|
+
│ ├── uscha-onepager{,-EN}.html # one-page sheet
|
|
27
|
+
│ ├── uscha-team-pitch.html # team adoption pitch (Vale/Martín story, 14 slides)
|
|
28
|
+
│ ├── uscha-team-pitch-extended.html # extended pitch: + typical day, readiness KPI, 2-story ledger, pilot (22 slides)
|
|
29
|
+
│ ├── skills-referencia.html # exhaustive reference of the 8 skills (what each does, phase by phase)
|
|
30
|
+
│ ├── casos-reales.md # logbook: real moments where the method intervenes (anonymized)
|
|
31
|
+
│ ├── *.png # system map · 10 steps · reverse-discovery
|
|
32
|
+
│ └── diagram-sources/ # source HTML of the PNGs (re-renderable)
|
|
33
|
+
├── formats/ # 6 format explorations (A-F); playbook + atlas-map were adopted
|
|
34
|
+
└── audits/ # outputs of the adversarial audits (2026-07)
|
|
35
|
+
├── audit-metodologia-7-lentes.json # 33 weaknesses confirmed / 13 refuted
|
|
36
|
+
├── audit-fidelidad-doc-codigo-idea.json # 171 claims verified doc↔code↔idea
|
|
37
|
+
├── truth-pass-6-docs.json # 130 truthfulness edits post-wiring
|
|
38
|
+
└── verificacion-team-pitch.json # 3 lenses over the pitch
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Status (2026-07-05)
|
|
42
|
+
|
|
43
|
+
- **Kit v1.40.1** <!-- uscha:version --> — the fact-gates are WIRED into the engine (1.3.0: `log-gate`,
|
|
44
|
+
`flag-blocker`, `resolve-escalation`; UNMEASURED; per-tool convergence with a veto from
|
|
45
|
+
the measured snapshot) and the engine measures **Python** repos (1.4.0: pytest/Cobertura + ruff +
|
|
46
|
+
mypy) **TypeScript/JS** (1.5.0: lcov + jest-junit + eslint + tsc) **Go** (1.6.0: native cover
|
|
47
|
+
profile + gotestsum + golangci via checkstyle), **Rust** (1.7.0: Cobertura +
|
|
48
|
+
nextest + clippy) **C#/.NET** (1.7.0: coverlet + junit
|
|
49
|
+
logger + SARIF/Roslyn), **C++** (1.8.0: gcovr/Cobertura + ctest junit +
|
|
50
|
+
clang-tidy), **Kotlin/JVM Gradle** and **Swift** (1.9.0: zero new parsers —
|
|
51
|
+
JaCoCo/lcov/JUnit/checkstyle reused; detekt + SwiftLint). **Traceable acceptance** (1.10.0: AC-n closes on a
|
|
52
|
+
MEASURED testcase, the dominant dimension of readiness — M2 of the PragProg backlog). **Tests outside
|
|
53
|
+
the simplicity budget** (1.11.0: writing tests does not penalize the gate — M9).
|
|
54
|
+
**Secret-scan in gate-check** (1.12.0: added private keys/tokens/containers
|
|
55
|
+
block as a fact — M8). **Atomic ledger** (1.13.0: integrity checksum + hardened
|
|
56
|
+
load — M3). **Plateau/stop-signal** (1.14.0: stall and PR-candidate as
|
|
57
|
+
advisories — M6). **Golden scrub** (1.15.0: declared volatiles are masked with
|
|
58
|
+
visible masking — M7). **Regression-capture** (1.16.0: closing findings without a test =
|
|
59
|
+
narrated; escape-analysis mandatory when resolving blockers — M1). **Threshold
|
|
60
|
+
provenance** (1.17.0: each threshold is tagged by provenance — a requirement
|
|
61
|
+
declared in config vs the kit's default opinion; the biting cap says so in the
|
|
62
|
+
headline — M5). **Derived FSM** (1.18.0: `phase` computes the workflow state
|
|
63
|
+
from the ledger's facts, never declared; the PR is gated with `--require
|
|
64
|
+
pr-ready` — M4). **Formal spikes** (1.19.0: a `spike/*` branch never passes the PR
|
|
65
|
+
gate; the legitimate output is an ADR with lessons — M10). **Execution policy routing** (1.35.0: phase-level methodology/model/effort metadata for the operator and Mirador, not readiness scoring). **Discovery intake** (1.36.0: production findings + spec-doubt/SPEC-WRONG enter the ledger and reopen discovery instead of disappearing into narration). **ADR experiments** (1.37.0: `Status: Experiment` is visible/advisory in dashboard/Mirador with feedback/review metadata, not a readiness score). **Contract closure** (1.38.0: structured `spec-change-request`, golden intended vs observed-accidental labels, and post-merge calibration metrics). **Universal installer** (1.39.0: one machine installer for Codex plugin adoption and Claude global install, with dry-run/doctor/version checks). **npm/npx router** (1.40.1: `@andresmassello/uscha` exposes `uscha`/`uscha-kit` and delegates to the canonical Python installer). Smoke suite 224/224 green.
|
|
66
|
+
**The PragProg backlog is CLOSED: 10 of 10** (see
|
|
67
|
+
`docs/analisis-pragmatic-programmer.md`).
|
|
68
|
+
License: MIT. The principle "facts block, guesses advise" is an enforced property,
|
|
69
|
+
not a slogan.
|
|
70
|
+
- **Docs** — passed through truth-pass against the real engine: every claim describes what
|
|
71
|
+
v1.40.1 does; the references appendix has **fetch-verified links** to the 10
|
|
72
|
+
sources. Status convention in the docs: `in the kit` / `new` / `proposal`.
|
|
73
|
+
- **In progress** — dogfooding on a real case (pilot project, Python): the 1.4.0 adapter unblocked it;
|
|
74
|
+
what remains is the read-only dry-run (criterion 2 of the python-adapter HANDOFF) and the on-ramp.
|
|
75
|
+
Conscious deferrals in CHANGELOG-1.4.0 (assert density in rebuild, mechanized A-E
|
|
76
|
+
profiles).
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Install from npm/npx
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npx @andresmassello/uscha@latest install --target codex
|
|
83
|
+
npx @andresmassello/uscha@latest doctor --target codex
|
|
84
|
+
# or both Codex + Claude:
|
|
85
|
+
npx @andresmassello/uscha@latest install --target both
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The npm package is only a router. The canonical installer remains
|
|
89
|
+
`uscha-kit/install-uscha.py`, and Python 3.8+ is still required on the target machine.
|
|
90
|
+
|
|
91
|
+
## How the kit is re-packaged
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
powershell -NoProfile -Command "Compress-Archive -Path 'uscha-kit' -DestinationPath 'uscha-kit-X.Y.Z.zip' -Force"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The zips are build artifacts: they are not committed. The kit source in this repo is the truth.
|
|
98
|
+
|
|
99
|
+
## History
|
|
100
|
+
|
|
101
|
+
It was born as a methodology for working with Claude Code, was distilled with the
|
|
102
|
+
Böckeler principle (computational blocks / inferential advises), survived two
|
|
103
|
+
adversarial audits (231 agents) that found the central principle inverted in the code
|
|
104
|
+
— and 1.3.0 flipped it right. The details are in `audits/` and in the CHANGELOGs.
|
package/bin/README.md
ADDED
package/bin/uscha.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawnSync } = require('node:child_process');
|
|
3
|
+
const path = require('node:path');
|
|
4
|
+
|
|
5
|
+
const script = path.join(__dirname, '..', 'uscha-kit', 'install-uscha.py');
|
|
6
|
+
const args = process.argv.slice(2);
|
|
7
|
+
const candidates = process.platform === 'win32'
|
|
8
|
+
? [ ['python', []], ['py', ['-3']] ]
|
|
9
|
+
: [ ['python3', []], ['python', []] ];
|
|
10
|
+
|
|
11
|
+
let lastError = null;
|
|
12
|
+
for (const [cmd, prefix] of candidates) {
|
|
13
|
+
const result = spawnSync(cmd, [...prefix, script, ...args], { stdio: 'inherit' });
|
|
14
|
+
if (!result.error) {
|
|
15
|
+
process.exit(result.status === null ? 1 : result.status);
|
|
16
|
+
}
|
|
17
|
+
if (result.error.code !== 'ENOENT') {
|
|
18
|
+
lastError = result.error;
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
lastError = result.error;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.error('[uscha] Python 3.8+ is required but was not found in PATH.');
|
|
25
|
+
if (lastError && lastError.message) {
|
|
26
|
+
console.error(`[uscha] ${lastError.message}`);
|
|
27
|
+
}
|
|
28
|
+
process.exit(1);
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@andresmassello/uscha",
|
|
3
|
+
"version": "1.40.1",
|
|
4
|
+
"description": "Uscha installer for Codex and Claude coding-agent workflows.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"uscha": "bin/uscha.js",
|
|
7
|
+
"uscha-kit": "bin/uscha.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"uscha-kit/",
|
|
12
|
+
"!uscha-kit/**/__pycache__/",
|
|
13
|
+
"!uscha-kit/**/*.pyc",
|
|
14
|
+
"!uscha-kit/**/*.pyo",
|
|
15
|
+
"README.md",
|
|
16
|
+
"LICENSE"
|
|
17
|
+
],
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/andresmassello/uscha.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://github.com/andresmassello/uscha#readme",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/andresmassello/uscha/issues"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"codex",
|
|
28
|
+
"claude",
|
|
29
|
+
"spec-driven",
|
|
30
|
+
"qa",
|
|
31
|
+
"coding-agents",
|
|
32
|
+
"sdd"
|
|
33
|
+
],
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": ">=18"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uscha-adr-refine
|
|
3
|
+
description: >
|
|
4
|
+
Turn a rough idea into a development-ready ADR set + ACCEPTANCE.md by INTERROGATING
|
|
5
|
+
before generating. Runs a structured Socratic interview (problem, implicit decisions,
|
|
6
|
+
behavior incl. failure modes, inviolable constraints, out-of-scope, Definition of
|
|
7
|
+
Done, dependencies), refuses to emit artifacts until the gaps are closed, then
|
|
8
|
+
distills the conversation into docs/adr/ADR-NNN.md files and an ACCEPTANCE.md. The
|
|
9
|
+
front-half counterpart to dev-loop. Invoke for "refine the ADR", "let's spec this
|
|
10
|
+
before coding", "ayudame a definir esto antes de desarrollar".
|
|
11
|
+
allowed-tools: Read, Write, Glob, Grep
|
|
12
|
+
disable-model-invocation: false
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# adr-refine — interview, then distill
|
|
16
|
+
|
|
17
|
+
You convert a rough idea into a development-ready specification. You do this in two
|
|
18
|
+
phases. **You are NOT a generator. You are an interrogator that distills.** The value
|
|
19
|
+
is in the questions, not in agreeing.
|
|
20
|
+
|
|
21
|
+
## Non-negotiable principles
|
|
22
|
+
|
|
23
|
+
1. **Interrogate, don't agree.** Your job in Phase A is to surface what the human left
|
|
24
|
+
implicit and to find the holes — not to validate. A refinement where you agreed with
|
|
25
|
+
everything failed.
|
|
26
|
+
2. **Converge, don't run out of questions.** The interview ends on an objective
|
|
27
|
+
criterion (below), not when the human seems tired or you run out of ideas. This
|
|
28
|
+
mirrors dev-loop's "converge, don't chase zero" — the same discipline at the front.
|
|
29
|
+
3. **Do not emit artifacts until convergence.** No ADR, no ACCEPTANCE.md until every
|
|
30
|
+
exit condition is met. If asked to "just write it" early, name the open gaps first.
|
|
31
|
+
4. **One topic at a time.** Never dump 20 questions. Walk the agenda below, a focused
|
|
32
|
+
batch at a time, and reflect back what you heard before moving on.
|
|
33
|
+
5. **Record deferrals as explicit assumptions.** If the human says "you decide" on a
|
|
34
|
+
consequential decision, push back once with the trade-off; if they still defer,
|
|
35
|
+
record it as an explicit assumption in the ADR, never as a silent default.
|
|
36
|
+
|
|
37
|
+
## Phase A — The interview (agenda)
|
|
38
|
+
|
|
39
|
+
Start from the human's initial context. Work the agenda in order; skip a topic only if
|
|
40
|
+
it's already fully answered. Keep a running list of OPEN GAPS and resolved decisions.
|
|
41
|
+
|
|
42
|
+
1. **Problem and why now.** What job does this remove? What does it cost to NOT do
|
|
43
|
+
it (money, time, risk)? If "why now" has no answer, the priority is suspect.
|
|
44
|
+
2. **Implicit decisions.** Surface the choices the request assumed: sync vs async,
|
|
45
|
+
storage, protocol, idempotency, transactional boundaries, who owns state. For each,
|
|
46
|
+
force an explicit decision and at least one considered alternative.
|
|
47
|
+
3. **Behavior.** Happy path first, then the DIRTY cases: provider/timeout failures,
|
|
48
|
+
retries and backoff, 4xx vs 5xx, concurrency, partial/terminal states, what must NOT
|
|
49
|
+
happen. A feature without its failure behavior is half-specified.
|
|
50
|
+
4. **Inviolable constraints (→ `CONSTITUTION.md`).** Domain + security + operation
|
|
51
|
+
rules that cannot be broken (money to the cent, numbering without gaps, never cross
|
|
52
|
+
environments/credentials, secrets never logged, auth/authz, data retention). Write/extend
|
|
53
|
+
`CONSTITUTION.md` (one invariant per line, CWE ref where it maps); these feed the
|
|
54
|
+
dev-loop severity gate and a breach is a BLOCKER. **An ADR may never contradict the
|
|
55
|
+
CONSTITUTION** — if a decision would, it's escalated, not recorded.
|
|
56
|
+
5. **Out of scope.** Explicit boundaries, with forward references ("X goes to a later
|
|
57
|
+
spec"). What you exclude is as important as what you include.
|
|
58
|
+
6. **Definition of Done + how we measure success.** Concrete, checkable acceptance criteria
|
|
59
|
+
(tests green, documented, metrics published, runbook) AND success metrics (p95,
|
|
60
|
+
cost ceiling, zero orphaned records). Each item must be verifiable, not a feeling.
|
|
61
|
+
7. **Dependencies.** Which other specs/systems/credentials this needs to exist first.
|
|
62
|
+
|
|
63
|
+
After each batch, reflect: "Decided: … / Still open: …". Move on only when the
|
|
64
|
+
current topic is closed.
|
|
65
|
+
|
|
66
|
+
## Convergence — exit conditions (ALL must hold)
|
|
67
|
+
|
|
68
|
+
- Every decision has a rationale and at least one considered alternative.
|
|
69
|
+
- Every failure mode named has a defined behavior.
|
|
70
|
+
- Out-of-scope is explicit.
|
|
71
|
+
- The Definition of Done exists and every item is checkable.
|
|
72
|
+
- No OPEN GAP you raised remains unresolved (resolved = decided OR recorded as an
|
|
73
|
+
explicit assumption).
|
|
74
|
+
|
|
75
|
+
State plainly when you've converged ("Closed: every decision has a rationale, the failures
|
|
76
|
+
have behavior, the scope has a boundary and the DoD is verifiable.") before Phase B.
|
|
77
|
+
|
|
78
|
+
## Phase B — Distill the artifacts
|
|
79
|
+
|
|
80
|
+
Only after convergence. Produce (and, if any new project-wide invariant surfaced in
|
|
81
|
+
step 4, append it to **`CONSTITUTION.md`** — never let an inviolable rule slip into an
|
|
82
|
+
ADR where it could later be "traded away"):
|
|
83
|
+
|
|
84
|
+
1. **One ADR per decision worth recording** at `docs/adr/ADR-NNN-<slug>.md`, format:
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
# ADR-NNN: <title of the decision>
|
|
88
|
+
## Status: Accepted
|
|
89
|
+
<!-- Use Status: Experiment only for a bounded hypothesis with feedback/review criteria. -->
|
|
90
|
+
## Context
|
|
91
|
+
<the problem + the considered options: A) … B) … C) …>
|
|
92
|
+
## Decision
|
|
93
|
+
<the chosen option>
|
|
94
|
+
## Reasons
|
|
95
|
+
- <why, point by point>
|
|
96
|
+
## Consequences
|
|
97
|
+
+ <the good>
|
|
98
|
+
- <the cost / what it forces on us>
|
|
99
|
+
<!-- If Status: Experiment, also include:
|
|
100
|
+
## Hypothesis
|
|
101
|
+
## Feedback Signal
|
|
102
|
+
## Review By: YYYY-MM-DD (or ## Review Trigger)
|
|
103
|
+
## Promote Criteria
|
|
104
|
+
## Rollback / Supersede Criteria
|
|
105
|
+
-->
|
|
106
|
+
## Implementation Plan
|
|
107
|
+
- Affected paths: <files/dirs>
|
|
108
|
+
- Patterns: <pattern to follow>
|
|
109
|
+
- Tests: <which tests prove the decision>
|
|
110
|
+
## Verification
|
|
111
|
+
- [ ] <criterion checkable by an agent>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Number ADRs continuing from the highest existing one in `docs/adr/` (glob first).
|
|
115
|
+
Negative decisions count: "what we are NOT going to use and why" is a valid ADR.
|
|
116
|
+
Experimental decisions count only when they are explicit hypotheses with feedback signal,
|
|
117
|
+
review date/trigger, promote criteria and rollback/supersede criteria. Do not use
|
|
118
|
+
`Status: Experiment` as a polite way to avoid deciding.
|
|
119
|
+
|
|
120
|
+
2. **`ACCEPTANCE.md`** at the repo root (or the path in `uscha.config.json` →
|
|
121
|
+
`defaults.acceptance_file`). This is the file dev-loop's readiness measures — it MUST
|
|
122
|
+
exist and be checkable:
|
|
123
|
+
|
|
124
|
+
```markdown
|
|
125
|
+
# Acceptance — <feature>
|
|
126
|
+
## Definition of Done
|
|
127
|
+
- [ ] <verifiable criterion>
|
|
128
|
+
- [ ] …
|
|
129
|
+
## How we measure success
|
|
130
|
+
- <objective metric: p95, cost, zero orphans, …>
|
|
131
|
+
## Out of scope
|
|
132
|
+
- <boundary> → <future spec>
|
|
133
|
+
## Recorded decisions
|
|
134
|
+
- ADR-NNN — <title>
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Where to write:** with file tools available (Claude Code), write the files to disk.
|
|
138
|
+
In a chat-only context, print each file in a fenced block, clearly labeled with its
|
|
139
|
+
target path, ready to paste — and remind the human these go to `docs/adr/` and the repo
|
|
140
|
+
root before running dev-loop.
|
|
141
|
+
|
|
142
|
+
**Tracked-markdown protocol:** if any target `.md` already exists and is tracked, ask
|
|
143
|
+
for its current version before overwriting — never silently replace.
|
|
144
|
+
|
|
145
|
+
## Handoff to dev-loop
|
|
146
|
+
|
|
147
|
+
Close with the handoff prompt so the build phase starts by planning, not improvising:
|
|
148
|
+
|
|
149
|
+
> "Read the ADR set and ACCEPTANCE.md. Before touching code: 1) summarize the plan of
|
|
150
|
+
> files to create/modify, 2) confirm which decisions were left implicit, 3)
|
|
151
|
+
> show me the first test you would write."
|
|
152
|
+
|
|
153
|
+
Two-command flow end to end: `/uscha-adr-refine` → (ADR set + ACCEPTANCE.md) → `/uscha-devloop`.
|
|
154
|
+
|
|
155
|
+
## Anti-patterns (do not do)
|
|
156
|
+
|
|
157
|
+
- Generate an ADR from a one-line request without interviewing.
|
|
158
|
+
- Accept "do it however you want" on a consequential decision without recording the
|
|
159
|
+
assumption.
|
|
160
|
+
- Write an ACCEPTANCE item that isn't objectively checkable ("that it works well").
|
|
161
|
+
- Emit artifacts before the convergence conditions are met.
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uscha-characterize
|
|
3
|
+
description: >
|
|
4
|
+
Capture a golden / approval suite of a module's CURRENT behavior — the one artifact the
|
|
5
|
+
agent must NOT author. Run the ORIGINAL code with real inputs through a deterministic
|
|
6
|
+
harness, emit .received, and STOP for human approval; never create or edit a .approved
|
|
7
|
+
file. Used before any migration/modernization to freeze pre-change behavior as field
|
|
8
|
+
truth. Invoke for "characterize", "golden-capture", "capturá el comportamiento viejo".
|
|
9
|
+
allowed-tools: Read, Write, Glob, Grep, Bash
|
|
10
|
+
disable-model-invocation: false
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# characterize — freeze the current behavior as field truth (the agent does not author it)
|
|
14
|
+
|
|
15
|
+
The golden suite is the ONE piece of the loop the agent cannot author, and that is exactly
|
|
16
|
+
its reason to exist. If you write the golden by reasoning about what the code "should"
|
|
17
|
+
return, you encode the same partial understanding that loses logic silently. **You capture
|
|
18
|
+
what the code DOES, mechanically, by running it — never what it should do.** You may write
|
|
19
|
+
the capture harness; you may NOT create, rename, or edit any `.approved` file.
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
- **Target module** + a **corpus source**: a path to input fixtures, or a reference to
|
|
24
|
+
(anonymized) production data. The golden is only worth as much as the corpus (see below).
|
|
25
|
+
|
|
26
|
+
## Phase 1 — Capture harness (you write this)
|
|
27
|
+
|
|
28
|
+
Generate a deterministic harness that runs the ORIGINAL module over the corpus and
|
|
29
|
+
serializes ALL observable output. Same input → same `.received`, byte for byte.
|
|
30
|
+
|
|
31
|
+
## Phase 2 — Non-determinism checklist (emit + normalize BEFORE serializing)
|
|
32
|
+
|
|
33
|
+
Control every one of these, or the diff lies. Output the checklist applied:
|
|
34
|
+
- [ ] **Timestamps / dates** — frozen clock or stable placeholder.
|
|
35
|
+
- [ ] **Random / seeds** — fixed seed or mocked generator.
|
|
36
|
+
- [ ] **Map/set iteration order** — sort keys before serializing.
|
|
37
|
+
- [ ] **GUIDs / DB auto-increment** — normalized or excluded from the snapshot.
|
|
38
|
+
- [ ] **Concurrency** — thread order must not leak into the output.
|
|
39
|
+
- [ ] **Target locale** — decimal separator, date format, culture. **Mandatory and
|
|
40
|
+
explicit.** A golden built on one machine and run on another with a different locale
|
|
41
|
+
breaks entirely (Windows/SQL Server: high risk).
|
|
42
|
+
- [ ] **Deterministic serialization** — JSON with sorted keys, fixed float precision,
|
|
43
|
+
explicit encoding. Identical byte-for-byte when behavior is identical.
|
|
44
|
+
|
|
45
|
+
## Phase 3 — Run the capture
|
|
46
|
+
|
|
47
|
+
Execute the harness → generate `.received` files.
|
|
48
|
+
|
|
49
|
+
**Declare volatile fields BEFORE approval (kit 1.15.0).** If the ORIGINAL code emits
|
|
50
|
+
values that vary between correct runs and cannot be made deterministic at the source
|
|
51
|
+
(timestamps, request ids, GUIDs from a layer you cannot touch), declare scrub rules in
|
|
52
|
+
`golden.scrub.json` at the fixtures root:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{ "rules": [
|
|
56
|
+
{"pattern": "\\d{4}-\\d{2}-\\d{2}T[0-9:.+Z-]+", "replace": "<TIMESTAMP>"},
|
|
57
|
+
{"pattern": "requestId=[0-9a-f-]{36}", "replace": "requestId=<UUID>"} ] }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`golden-diff` masks BOTH sides with these rules before comparing (text only; binary
|
|
61
|
+
stays byte-for-byte) and reports every scrub-match separately (`N via scrub`) — masking
|
|
62
|
+
is never invisible. Prefer fixing determinism at the source (Phase 2 checklist); scrub
|
|
63
|
+
is for what you genuinely cannot control. The rules file is part of what the human
|
|
64
|
+
approves in Phase 4 — gate-check flags any later edit to it (a broadened rule can mask
|
|
65
|
+
real divergence).
|
|
66
|
+
|
|
67
|
+
## Phase 4 — STOP for human approval
|
|
68
|
+
|
|
69
|
+
Return control to the human to review and approve the `.approved` — and, if present,
|
|
70
|
+
`golden.scrub.json` (the scrub rules are contract, same as the goldens). **The skill
|
|
71
|
+
ends here.** It does NOT auto-complete approval, and it does NOT create any `.approved`
|
|
72
|
+
file.
|
|
73
|
+
|
|
74
|
+
## Corpus — where the inputs come from (critical)
|
|
75
|
+
|
|
76
|
+
The golden only protects the paths you exercise; what gets lost is usually a rare path.
|
|
77
|
+
Sources, in order of value:
|
|
78
|
+
1. **Real production samples** (anonymized if needed) — the true distribution, including
|
|
79
|
+
cases nobody knew existed.
|
|
80
|
+
2. **Hand-built edge cases** — known limits (zeros, boundaries, error states, rare
|
|
81
|
+
combinations of inputs).
|
|
82
|
+
3. **Inputs of past bugs** — every historical bug is a golden input.
|
|
83
|
+
A module whose corpus does not exercise its known branches is marked **PARTIAL**, never
|
|
84
|
+
covered.
|
|
85
|
+
|
|
86
|
+
## Guardrails (non-negotiable)
|
|
87
|
+
|
|
88
|
+
- The skill STOPS at the approval point (Phase 4); it never creates/renames/edits `.approved`.
|
|
89
|
+
- A `PreToolUse` hook on `**/*.approved.*` should make agent writes mechanically impossible
|
|
90
|
+
(see `hooks/block-approved-writes.ps1` + the settings snippet in the kit).
|
|
91
|
+
- `.gitattributes`: `*.approved.* binary` — line endings must not create false diffs
|
|
92
|
+
(Windows/SQL Server).
|
|
93
|
+
|
|
94
|
+
## Acceptance criteria
|
|
95
|
+
|
|
96
|
+
- The skill ends at Phase 4 with no `.approved` created or renamed.
|
|
97
|
+
- The harness is deterministic (same input → same `.received` byte for byte).
|
|
98
|
+
- The output includes the non-determinism checklist that was applied.
|
|
99
|
+
|
|
100
|
+
## Harness stack
|
|
101
|
+
|
|
102
|
+
- **Java** → ApprovalTests.Java (`com.approvaltests:approvaltests`, JUnit 5 / JDK 21);
|
|
103
|
+
`JsonApprovals.verifyAsJson()` for structured responses, `WithTimeZone`-style helpers
|
|
104
|
+
to freeze time/locale. For read-only migrations, the "old query vs new query against prod"
|
|
105
|
+
pattern applies.
|
|
106
|
+
- **C++ / other** → a fixtures dir + a deterministic serializer + a diff runner (no
|
|
107
|
+
comfortable native ApprovalTests; go custom).
|
|
108
|
+
- For system I/O, a fixtures dir + custom runner that normalizes and diffs is often better
|
|
109
|
+
than relying on the library alone.
|
|
110
|
+
|
|
111
|
+
## Relationship to the other skills
|
|
112
|
+
|
|
113
|
+
- **reverse-discovery** orchestrates this skill as its Phase 2 (golden capture at the
|
|
114
|
+
boundaries).
|
|
115
|
+
- The captured `.approved` is the arbiter that `qa_ledger.py golden-diff` byte-compares
|
|
116
|
+
against during `/uscha-devloop`.
|
|
117
|
+
- If you maintain `golden-labels.json`, classify approved fixtures as `intended`,
|
|
118
|
+
`observed-accidental`, or leave them `unknown`; labels explain intent but never
|
|
119
|
+
replace the byte comparison.
|
|
120
|
+
|
|
121
|
+
## Tracked-markdown / tracked-golden protocol
|
|
122
|
+
|
|
123
|
+
Never overwrite an existing approved golden. If a `.received` already exists, regenerate it;
|
|
124
|
+
if a `.approved` exists, it is the human's — leave it untouched and surface the diff.
|