@andresmassello/uscha 1.40.1 → 1.43.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 (40) hide show
  1. package/README.md +21 -13
  2. package/bin/uscha.js +19 -7
  3. package/package.json +1 -1
  4. package/uscha-kit/.claude/skills/uscha-adr-refine/SKILL.md +2 -2
  5. package/uscha-kit/.claude/skills/uscha-devloop/SKILL.md +3 -1
  6. package/uscha-kit/.claude/skills/uscha-devloop/qa_ledger.py +729 -155
  7. package/uscha-kit/.claude/skills/uscha-mirador/SKILL.md +22 -7
  8. package/uscha-kit/.claude/skills/uscha-mirador/mirador-render.py +44 -5
  9. package/uscha-kit/.claude/skills/uscha-mirador/mirador-watch.ps1 +1 -1
  10. package/uscha-kit/.claude/skills/uscha-mirador/mirador-watch.sh +1 -1
  11. package/uscha-kit/.claude/skills/uscha-mirador/mirador.template.html +666 -586
  12. package/uscha-kit/.claude-plugin/plugin.json +1 -1
  13. package/uscha-kit/.codex-plugin/plugin.json +1 -1
  14. package/uscha-kit/CHANGELOG-1.40.2.md +13 -0
  15. package/uscha-kit/CHANGELOG-1.41.0.md +18 -0
  16. package/uscha-kit/CHANGELOG-1.41.1.md +53 -0
  17. package/uscha-kit/CHANGELOG-1.41.2.md +34 -0
  18. package/uscha-kit/CHANGELOG-1.41.3.md +30 -0
  19. package/uscha-kit/CHANGELOG-1.42.0.md +41 -0
  20. package/uscha-kit/CHANGELOG-1.43.0.md +37 -0
  21. package/uscha-kit/INSTALL.md +120 -0
  22. package/uscha-kit/README.md +40 -69
  23. package/uscha-kit/VERSION +1 -1
  24. package/uscha-kit/WORKBENCH.md +19 -5
  25. package/uscha-kit/hooks/block-approved-writes.py +25 -0
  26. package/uscha-kit/install-uscha.py +534 -267
  27. package/uscha-kit/skills/uscha-adr-refine/SKILL.md +2 -2
  28. package/uscha-kit/skills/uscha-devloop/SKILL.md +3 -1
  29. package/uscha-kit/skills/uscha-devloop/qa_ledger.py +729 -155
  30. package/uscha-kit/skills/uscha-mirador/SKILL.md +22 -7
  31. package/uscha-kit/skills/uscha-mirador/mirador-render.py +44 -5
  32. package/uscha-kit/skills/uscha-mirador/mirador-watch.ps1 +1 -1
  33. package/uscha-kit/skills/uscha-mirador/mirador-watch.sh +1 -1
  34. package/uscha-kit/skills/uscha-mirador/mirador.template.html +666 -586
  35. package/uscha-kit/templates/CONSTITUTION.md +4 -4
  36. package/uscha-kit/templates/docs/adr/README.md +19 -19
  37. package/uscha-kit/tests/ledger-integrity-regressions.py +136 -0
  38. package/uscha-kit/tests/smoke-engine.sh +1312 -29
  39. package/uscha-kit/uscha.config.json +1 -1
  40. package/uscha-kit/workbench-doctor.sh +47 -3
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "uscha",
4
- "version": "1.40.1",
4
+ "version": "1.43.0",
5
5
  "displayName": "Uscha",
6
6
  "description": "Spec-driven development for LLM coding agents: 8 skills (discovery, adr-refine, reverse-discovery, characterize, devloop, sysdoc, rubric, mirador) + a stdlib measurement engine (qa_ledger.py, 29 subcommands + universal installer + npm/npx router). Facts block, guesses advise; the human approves.",
7
7
  "author": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uscha",
3
- "version": "1.40.1",
3
+ "version": "1.43.0",
4
4
  "description": "Uscha spec-driven development methodology for coding agents. Includes npm/npx router.",
5
5
  "author": {
6
6
  "name": "Andres Massello",
@@ -0,0 +1,13 @@
1
+ # uscha-kit 1.40.2
2
+
3
+ ## Changed
4
+
5
+ - Reworked install documentation around the npm/npx path for Codex, Claude Code, and mixed-machine setups.
6
+ - Added `uscha-kit/INSTALL.md` as the focused install guide.
7
+ - Kept Git checkout/link mode, Claude Code plugin commands, and manual copy as secondary/debugging options with tradeoffs.
8
+
9
+ ## Verification
10
+
11
+ - `npm view @andresmassello/uscha version`
12
+ - `npx --yes @andresmassello/uscha@latest version --json`
13
+ - `bash uscha-kit/tests/smoke-engine.sh`
@@ -0,0 +1,18 @@
1
+ # uscha-kit 1.41.0 — safety release
2
+
3
+ Significant backwards-compatible release covering WU1–WU7.
4
+
5
+ - **WU1:** measured `pr-ready`, fail-closed Ruff/JUnit schemas, and validated counters.
6
+ - **WU2:** safe init, authoritative doctor, portable active Claude hook, marketplace preflight, and staged rollback.
7
+ - **WU3:** evidence-bearing PF/SD/SCR closure, config validation, and monotonic iterations/counters.
8
+ - **WU4:** integration readiness heterogeneous-event false-green prevention, unknown escalation repo rejection, and Spanish ADR label folding.
9
+ - **WU5:** ADR templates use AC IDs; the resolved constitution blocker example includes `--escape-analysis`.
10
+ - **WU6:** npm router probes usable Python >=3.8 before one installer invocation with no retry; workbench-doctor uses portable Python and the current skill roster.
11
+ - **WU7:** complete Claude installation transaction with rollback across managed skills, hook, settings, and marker; T77 covers existing and absent marker rollback.
12
+ - **P0 hardening:** Mirador script/DOM injection removed; structured static reports including Clippy fail closed; stale JUnit evidence cannot satisfy `pr-ready`.
13
+ - **P1 installer hardening:** init preflights all targets and rejects symlinks; Codex restores marketplace state during rollback; hook matcher and malformed Claude settings are validated.
14
+ - **P1 ledger hardening:** readiness configuration is validated completely and PF/SD/SCR closure is immutable after its first resolution.
15
+ - **Documentation truth-pass:** exact 29-command reference, npx-first Codex/Claude adoption, eight-skill inventory, completed EN twins, and refreshed diagrams.
16
+ - Smoke suite: **351/351 green**.
17
+
18
+ Known boundary: Codex and Claude targets are independently transactional; `--target both` remains sequential rather than cross-target atomic.
@@ -0,0 +1,53 @@
1
+ # uscha-kit 1.41.1 — adversarial-review hardening (2026-07-11)
2
+
3
+ An independent adversarial review of the 1.41.0 "safety hardening" release (4 parallel
4
+ reviewers, each tasked to REFUTE the safety claims) confirmed three real defects — two of
5
+ them in the engine's core "measured beats narrated" promise. Fixed here, each with a
6
+ regression check that fails without the fix. Smoke suite: 355/355.
7
+
8
+ ## Fixes
9
+
10
+ ### 1 — `pr-ready` accepted a JUnit that LIES (HIGH, core-promise)
11
+ `_junit_counts` read `tests`/`failures`/`errors` from the `<testsuite>` **attributes** and
12
+ never reconciled them against the actual `<testcase>`/`<failure>`/`<error>` **elements**. A
13
+ report declaring `failures="0"` while containing a real `<failure>` element read as all-green
14
+ and could satisfy `pr-ready`. Fix: honor the child elements, fail-closed —
15
+ `failures = max(attr, element_failures)`, same for errors. A present failure can no longer be
16
+ attribute-declared away. Attribute-only summary suites (no `<testcase>` elements — the form
17
+ many emitters legitimately use) keep their counts, so real adapters are unaffected.
18
+ `qa_ledger.py:_junit_counts`. Regression: smoke **T69b**.
19
+
20
+ ### 2 — integration readiness trusted the single last event (MEDIUM-HIGH, core-promise)
21
+ The integration dimension read `integ_steps[-1]`, so a trailing green test-only step masked
22
+ an earlier FAILING integration gate (dim → 1.0). Fix: green now requires **0 open gated
23
+ findings across the latest record per integration tool** AND the latest test event passing —
24
+ so a failing gate is not masked, while a same-tool re-run that clears the gate is still seen.
25
+ `qa_ledger.py:cmd_readiness`. Regression: smoke **T69c**. (The 1.41.0 CHANGELOG claimed WU4
26
+ fixed this; the code still used `integ_steps[-1]` — the claim was inaccurate.)
27
+
28
+ ### 3 — Codex install rollback destroyed the pre-existing plugin (HIGH, data loss)
29
+ `install_codex` gated its restore on `swapped` (only true after BOTH the backup-move and the
30
+ install-move succeeded), then the `finally` deleted the backup unconditionally. If the
31
+ `stage → plugin_root` swap failed after the original was moved to backup (a real Windows AV /
32
+ locked-handle failure on reinstall), the restore was skipped and the `finally` deleted the
33
+ only surviving copy — silently. Fix: gate the restore on the **backup existing** (not on
34
+ `swapped`), and drop the backup only on SUCCESS (never in `finally`), so a failure restores
35
+ the original and a hard interrupt leaves it intact. Mirrors the Claude path, which already did
36
+ this. `install-uscha.py:install_codex`. Regression: smoke **T77b**. (This is exactly the
37
+ "rollback leaves partial state" category 1.41.0 claimed to close — it closed it for Claude,
38
+ not Codex.)
39
+
40
+ ## Honest limits (not fixed here, by design)
41
+ - A JUnit `<testsuite tests="3"/>` with ZERO `<testcase>` elements is still credited as 3
42
+ tests. This is the same trust the engine extends to any tool-emitted summary (a coverage %
43
+ in a coverage report), and closing it would reject the legitimate attribute-only reports
44
+ many emitters produce. The defense against a **forged** bare report is the "evidence
45
+ captured by execution" invariant (the SKILL runs the real test command; the agent does not
46
+ hand-write the XML) + the human merge gate — not per-report forgery detection.
47
+
48
+ ## Also
49
+ - `docs/skills-referencia.html` + `-EN.html`: stale "24 subcommands" → 29 (truth-pass).
50
+
51
+ ## Note on the test suite
52
+ The installer/npm smoke checks hardcode the version string, so a version bump requires
53
+ updating those literals (done here). A follow-up could have them read `VERSION` dynamically.
@@ -0,0 +1,34 @@
1
+ # uscha-kit 1.41.2 — mirador launch UX (2026-07-18)
2
+
3
+ A usability release for the mirador (the bird's-eye dashboard). No engine measurement
4
+ logic changed; this makes the mirador honest about "not ready" and trivial to launch from
5
+ inside a running project — "nada de magia oculta". Smoke suite: 357/357.
6
+
7
+ ## Fixes
8
+
9
+ ### 1 — "NOT READY" no longer reads as "hasn't started" (readiness title)
10
+ The mirador mapped the `NOT READY` band (score 0–49) to a fixed title `"Todavia no arranca"`
11
+ ("hasn't started yet"). But a project at, say, readiness 22 HAS started — it simply lacks
12
+ enough **measured** evidence. The wording contradicted the score right next to it. Fix: the
13
+ `NOT READY` title is now score-aware — `"Todavia sin evidencia medida"` only at score 0, and
14
+ `"En construccion -- evidencia insuficiente"` above 0. The dead fixed entry was removed from
15
+ `_MIRADOR_TITLE` so the old wording cannot reappear. `qa_ledger.py:cmd_dashboard`.
16
+ Regression: smoke **T78**.
17
+
18
+ ## Launch UX
19
+
20
+ ### 2 — `mirador-render.py` self-resolves its siblings
21
+ `--engine` (the `qa_ledger.py` path) and `--template` (the mirador HTML) now default to the
22
+ renderer's **sibling** skill files. From any project you can run the renderer — or
23
+ `/uscha-mirador` — with just `--ledger`, no long absolute paths. `mirador-render.py:main`.
24
+
25
+ ### 3 — the rendered mirador opens itself, and always prints where it is
26
+ After writing `mirador.html` the renderer opens it in the default browser (best-effort:
27
+ `os.startfile` on Windows, `open`/`xdg-open` elsewhere — never fails on headless/CI) and
28
+ prints the **absolute path** on an `OPEN IT:` line. A new `--no-open` flag suppresses the
29
+ auto-open; the live-watch loop (`mirador-watch.sh`/`.ps1`) and the smoke suite pass it so
30
+ they never spawn browser tabs on every refresh. `mirador-render.py`.
31
+
32
+ ## Note on the test suite
33
+ The installer/npm smoke checks still hardcode the version string, so this bump updated those
34
+ literals (T44, T66/T67 assertions). A follow-up could have them read `VERSION` dynamically.
@@ -0,0 +1,30 @@
1
+ # uscha-kit 1.41.3 — mirador live-view no longer spams browser tabs (2026-07-18)
2
+
3
+ A hotfix for a regression shipped in 1.41.2. Smoke suite: 358/358.
4
+
5
+ ## Fix
6
+
7
+ ### mirador-render auto-open + `--refresh` spawned a new browser tab every cycle (HIGH, regression)
8
+ 1.41.2 made `mirador-render.py` auto-open the rendered file in the browser. But the live
9
+ second-screen view (`mirador-watch`, and any render with `--refresh N`) injects a
10
+ `<meta http-equiv="refresh">` so a single open tab **reloads itself** every N seconds — and
11
+ the renderer is re-invoked each cycle. Auto-opening on every invocation therefore spawned a
12
+ **new browser tab on every refresh** (30s → a wall of tabs), making the machine unusable while
13
+ a watch loop ran. The `--no-open` flag was not enough on its own: a watch process started
14
+ before 1.41.2 calls the renderer without it.
15
+
16
+ Fix: auto-open is now suppressed whenever `--refresh > 0` (live mode) — the meta-refresh owns
17
+ the reload, in one tab. Auto-open remains for a genuine **one-shot** render (`/uscha-mirador`
18
+ with no `--refresh`), and `--no-open` still suppresses it everywhere. The `OPEN IT: <abs path>`
19
+ line is always printed, so the live view is one manual open away and never hidden.
20
+ `mirador-render.py:main`. Regression: smoke **T79** (live → 0 opens, one-shot → 1, `--no-open`
21
+ → 0).
22
+
23
+ Because the renderer is a fresh subprocess each cycle, a running watch loop picks up this fix
24
+ on its **next** render with no restart — and for a link/junction skill install (the renderer
25
+ lives in this repo), no reinstall either. A copy-mode install needs a reinstall to get the
26
+ fixed file.
27
+
28
+ ## Note on the test suite
29
+ The installer/npm smoke checks still hardcode the version string, so this bump updated those
30
+ literals. A follow-up could have them read `VERSION` dynamically.
@@ -0,0 +1,41 @@
1
+ # uscha-kit 1.42.0 — the mirador answers "how's it going / what's blocking / what's next" (2026-07-18)
2
+
3
+ Until now the mirador showed the project's SKELETON — the phase trail, the counters, the
4
+ invariant names — but a real early-stage project rendered as a wall of empty-looking cards
5
+ that left you with "sabor a nada": you could not tell, at a glance, how it was going, what was
6
+ blocking it, or what to do next. This release makes the mirador lead with exactly those three
7
+ answers — and every one of them is **measured**, not narrated. Smoke suite: 359/359.
8
+
9
+ ## The status story (hero block)
10
+
11
+ A three-line block sits under the verdict, each line derived purely from fields the engine
12
+ already emits in `dashboard --json` (no new engine logic, still model-agnostic):
13
+
14
+ - **Cómo viene** — the measured sub-scores, verbatim: e.g. `coverage 0% · simplicity FAIL`.
15
+ - **Qué lo traba** — the hard blockers, each traceable to a measured field: failing gates
16
+ (sub-scores reading FAIL/MISS), the readiness cap (`readiness.sub`), open discovery intake
17
+ (production findings / spec doubts / spec change requests), and expired/malformed ADR
18
+ experiments. A failing gate is NOT double-reported as its flipped CONSTITUTION invariant.
19
+ When nothing blocks, it says so and names the dimensions still lacking measured evidence.
20
+ - **Qué sigue** — the active phase in the derived FSM plus its method and execution hint
21
+ (`tier` / `model` / `effort`), so the operator sees the next concrete move.
22
+
23
+ `mirador.template.html:renderStatus`. Regression: smoke **T80**.
24
+
25
+ ## Empty cards earn their place
26
+
27
+ Cards no longer render as dead space when a real project has nothing for them yet:
28
+
29
+ - **The 6 layers of truth** (`capas`) — the engine never feeds this for a real project (it was
30
+ demo-only), so the whole card now HIDES when empty instead of showing an empty grid.
31
+ - **Specifications / ADRs / QA loops** — when empty, show a one-line hint of what fills them
32
+ and in which phase, instead of a blank list or a bare `0/0`.
33
+
34
+ ## Safety
35
+ All status/hint DOM is built with `textContent` / `createTextNode` (no `innerHTML`), so the
36
+ 1.41.0 Mirador XSS hardening still holds — smoke P0-A (script-context escaping, no HTML sinks)
37
+ stays green.
38
+
39
+ ## Note on the test suite
40
+ The installer/npm smoke checks still hardcode the version string, so this bump updated those
41
+ literals. A follow-up could have them read `VERSION` dynamically.
@@ -0,0 +1,37 @@
1
+ # uscha-kit 1.43.0 — `uscha mirador`: one command, no python, no paths (2026-07-18)
2
+
3
+ Adoption fix. Bringing up the mirador for a running project meant typing
4
+ `python <long-skill-path>/mirador-render.py --ledger QA-LEDGER.json` — friction that pushed
5
+ users away. The kit already had an npm/npx router (`bin/uscha.js`) forwarding to
6
+ `install-uscha.py`; it was missing one verb. Smoke suite: 361/361.
7
+
8
+ ## New: the `mirador` verb
9
+
10
+ From the root of any project that has a `QA-LEDGER.json`:
11
+
12
+ ```
13
+ uscha mirador # render + open the dashboard
14
+ uscha mirador --watch # live second-screen view (auto-refresh, one tab)
15
+ npx @andresmassello/uscha mirador # same, zero install
16
+ ```
17
+
18
+ No python, no paths, no flags required. The verb:
19
+ - resolves the renderer inside the kit (either skill-tree layout), which self-resolves its own
20
+ engine + template siblings;
21
+ - defaults the ledger to the `QA-LEDGER.json` convention in the current directory
22
+ (`--ledger` to point elsewhere);
23
+ - one-shot renders and opens the file; `--watch` opens ONE self-reloading tab and re-renders
24
+ every `--interval` seconds (default 30) WITHOUT re-opening — no browser-tab spam (honors the
25
+ 1.41.3 live-mode rule);
26
+ - fails clearly (exit 1) when the ledger is missing, instead of a stack trace.
27
+
28
+ `install-uscha.py:cmd_mirador` (exposed through the existing `bin/uscha.js` router).
29
+ Regression: smoke **T81**.
30
+
31
+ ## Docs
32
+ `INSTALL.md` gains a "See the dashboard (mirador)" section; the uscha-mirador `SKILL.md`
33
+ leads its human/terminal path with `uscha mirador`.
34
+
35
+ ## Note on the test suite
36
+ The installer/npm smoke checks still hardcode the version string, so this bump updated those
37
+ literals. A follow-up could have them read `VERSION` dynamically.
@@ -0,0 +1,120 @@
1
+ # Install Uscha
2
+
3
+ Uscha installs as a machine-level helper for coding agents. The recommended path
4
+ is npm/npx because it works the same on a fresh Codex or Claude Code machine.
5
+
6
+ ## Quick path
7
+
8
+ ### Codex Desktop
9
+
10
+ ```bash
11
+ npx --yes @andresmassello/uscha@latest version
12
+ npx --yes @andresmassello/uscha@latest install --target codex --dry-run
13
+ npx --yes @andresmassello/uscha@latest install --target codex
14
+ npx --yes @andresmassello/uscha@latest doctor --target codex
15
+ ```
16
+
17
+ Then restart Codex or open a new thread. The installer registers Uscha as a
18
+ personal local plugin under `~/plugins/uscha` and updates
19
+ `~/.agents/plugins/marketplace.json`. It preflights that marketplace before replacing the plugin tree and writes the install marker last.
20
+
21
+ ### Claude Code
22
+
23
+ ```bash
24
+ npx --yes @andresmassello/uscha@latest install --target claude --dry-run
25
+ npx --yes @andresmassello/uscha@latest install --target claude
26
+ npx --yes @andresmassello/uscha@latest doctor --target claude
27
+ ```
28
+
29
+ This installs the `uscha-*` skills and registers a portable Python `PreToolUse` hook under `~/.claude` while preserving unrelated `settings.json` entries. Restart or reload Claude Code after installing.
30
+
31
+ ### Same machine uses both
32
+
33
+ ```bash
34
+ npx --yes @andresmassello/uscha@latest install --target both --dry-run
35
+ npx --yes @andresmassello/uscha@latest install --target both
36
+ npx --yes @andresmassello/uscha@latest doctor --target both
37
+ ```
38
+
39
+ ## Prepare a project repo
40
+
41
+ After the machine install, initialize each project where Uscha should govern the
42
+ workflow:
43
+
44
+ ```bash
45
+ npx --yes @andresmassello/uscha@latest init --repo . --dry-run
46
+ npx --yes @andresmassello/uscha@latest init --repo .
47
+ # Existing differing files are preserved; use --force only to replace them deliberately.
48
+ npx --yes @andresmassello/uscha@latest init --repo . --force
49
+ ```
50
+
51
+ `init` exits nonzero and reports conflicts for differing `uscha.config.json`, `CLAUDE.md`, `CONSTITUTION.md`, or `.gitattributes`; `--dry-run` performs the same conflict check without writing.
52
+
53
+ Project state stays in the project: `uscha.config.json`, `QA-LEDGER.json`,
54
+ `ACCEPTANCE.md`, and approved golden fixtures when used.
55
+
56
+ ## See the dashboard (mirador)
57
+
58
+ From the root of any project that has a `QA-LEDGER.json`, one command renders the mirador and
59
+ opens it — no python, no paths:
60
+
61
+ ```bash
62
+ npx --yes @andresmassello/uscha@latest mirador # one glance: render + open
63
+ npx --yes @andresmassello/uscha@latest mirador --watch # live second-screen view (auto-refresh)
64
+ ```
65
+
66
+ It defaults to the `QA-LEDGER.json` convention in the current directory (pass `--ledger` to
67
+ point elsewhere) and prints the absolute path it wrote. `--watch` re-renders every `--interval`
68
+ seconds (default 30) into one self-reloading tab.
69
+
70
+ ## Requirements
71
+
72
+ | Requirement | Why |
73
+ |-------------|-----|
74
+ | Node.js + npm | Runs the universal `npx` entrypoint. |
75
+ | Python 3.8+ | Runs the canonical stdlib installer and engine. |
76
+ | Git | Used by the method and by project setup checks. |
77
+ | Codex Desktop and/or Claude Code | The agent runtime you want to install Uscha into. |
78
+
79
+ No `pip install` is required. The engine is Python stdlib-only.
80
+
81
+ ## Other install options
82
+
83
+ | Option | Use when | Tradeoff |
84
+ |--------|----------|----------|
85
+ | `npx @andresmassello/uscha@latest ...` | Normal install/update on any machine. | Requires npm registry access. |
86
+ | Git checkout + `python uscha-kit/install-uscha.py ...` | Developing Uscha itself or testing unreleased changes. | You must clone/pull the repo yourself. |
87
+ | `--mode link` from a checkout | This machine develops the kit and installed skills should follow local edits. | Links are great for development, risky for normal users. |
88
+ | Claude Code plugin commands | You specifically want Claude Code's native plugin flow. | Codex still needs the npm/git installer path. |
89
+ | Manual copy | Debugging the installer. | Easy to drift; not recommended for adoption. |
90
+
91
+ Development checkout example:
92
+
93
+ ```bash
94
+ git clone https://github.com/andresmassello/uscha.git
95
+ cd uscha
96
+ python uscha-kit/install-uscha.py install --target both --mode link --dry-run
97
+ python uscha-kit/install-uscha.py install --target both --mode link
98
+ ```
99
+
100
+ Claude Code plugin option:
101
+
102
+ ```text
103
+ /plugin marketplace add andresmassello/uscha
104
+ /plugin install uscha@uscha
105
+ ```
106
+
107
+ ## Update and verify
108
+
109
+ ```bash
110
+ npm view @andresmassello/uscha version
111
+ npx --yes @andresmassello/uscha@latest version
112
+ npx --yes @andresmassello/uscha@latest install --target both
113
+ npx --yes @andresmassello/uscha@latest doctor --target both
114
+ ```
115
+
116
+ `doctor` exits 1 for any unhealthy target in either text or `--json` mode. It checks installed skill presence, manifest/marketplace or hook registration, marker, and version; it does not measure file-content integrity.
117
+
118
+ If `npm view` returns `404` immediately after a new release, wait a few minutes:
119
+ npm search/dist-tags can propagate before the package metadata endpoint used by
120
+ `npx`. Do not republish the same version while propagation is in progress.
@@ -1,6 +1,6 @@
1
1
  # uscha-kit
2
2
 
3
- **Kit version:** v1.40.1 <!-- uscha:version -->
3
+ **Kit version:** v1.43.0 <!-- uscha:version -->
4
4
 
5
5
  Spec-driven orchestrator + multi-repo QA for Claude Code, with a deterministic ledger.
6
6
  **Eight skills** (`uscha-discovery`, `uscha-adr-refine`, `uscha-devloop`, `uscha-sysdoc`, `uscha-reverse-discovery`,
@@ -14,6 +14,8 @@ changes (a one-liner runs build+test and that's it).
14
14
 
15
15
  ```
16
16
  uscha-kit/
17
+ ?? INSTALL.md # install guide: npx, Codex, Claude Code, alternatives
18
+ ?? install-uscha.py # canonical installer used by npm/npx
17
19
  ├─ uscha.config.json # config: repos, thresholds, commands
18
20
  ├─ hooks/
19
21
  │ └─ block-approved-writes.ps1 # PreToolUse: the agent CANNOT write .approved (INV-GOLDEN-01)
@@ -128,8 +130,11 @@ BEFORE touching anything.
128
130
  | test count | `cargo nextest run` + copy (see note) | `reports/junit.xml` (wrapped JUnit supported) |
129
131
  | clippy | `cargo clippy --message-format=json > reports/clippy.json` | `reports/clippy.json` (JSONL: error→HIGH · warning→MEDIUM · `code:null` compile-error→HIGH; summaries without span ignored) |
130
132
 
131
- `ingest-gate` with explicit `--clippy` or by type. The inline `#[cfg(test)]` tests
132
- count as prod LOC (documented limitation); `tests/` = integration.
133
+ `ingest-gate` with explicit `--clippy` or by type. Its JSONL evidence is fail-closed:
134
+ each nonblank line must be a UTF-8 Cargo JSON object with a string `reason`; malformed
135
+ records or malformed compiler diagnostics are rejected before ledger mutation. An empty
136
+ file plus valid Cargo summaries and span-less diagnostic summaries remain clean/noise.
137
+ The inline `#[cfg(test)]` tests count as prod LOC (documented limitation); `tests/` = integration.
133
138
  **Watch out for junit**: nextest does NOT emit JUnit by default — you have to enable it in
134
139
  `.config/nextest.toml` (`[profile.default.junit] path = "junit.xml"`) and the file
135
140
  lands in `target/nextest/default/junit.xml`; copy it to `reports/junit.xml`
@@ -164,6 +169,13 @@ BEFORE touching anything.
164
169
  Bazel/make) belongs to the per-repo adapter — the kit only requires that the reports exist.
165
170
  `cmake-build-*` (any CLion profile) and `_deps` are excluded from the LOC.
166
171
 
172
+ **Text-report boundary:** mypy, tsc, and clang-tidy ingest only their recognized diagnostic
173
+ lines. Their legitimate clean/noise forms include status/success text, tool summaries, and
174
+ (for clang-tidy) passed-through compiler output, so a nonempty unmatched line is not safely
175
+ distinguishable from a clean report. The kit deliberately does **not** invent fail-closed
176
+ heuristics for those text formats; use their structured output where a fail-closed schema is
177
+ required.
178
+
167
179
  Kotlin/JVM with Gradle (`type: gradle`, kit 1.9.0) — **Kotlin over Maven already
168
180
  works with `type: maven`** (`.kt` has always counted; JaCoCo/Surefire don't
169
181
  distinguish JVM language). This type is for the common Gradle case:
@@ -206,76 +218,34 @@ BEFORE touching anything.
206
218
 
207
219
  ## Installation
208
220
 
209
- **Preferred public install (kit 1.40.1): use npm/npx.** The npm package is a
210
- thin router over the canonical Python installer, so adoption is easy without
211
- duplicating installer logic. You need Node/npm for this path and Python 3.8+ for
212
- the underlying installer.
213
-
214
- Codex-only machine:
215
-
216
- ```bash
217
- npx @andresmassello/uscha@latest version
218
- npx @andresmassello/uscha@latest install --target codex --dry-run
219
- npx @andresmassello/uscha@latest install --target codex
220
- npx @andresmassello/uscha@latest doctor --target codex
221
- ```
222
-
223
- Machine used by both Codex and Claude:
221
+ **Recommended path: npm/npx.** Use the same installer for Codex, Claude Code,
222
+ or both. Full guide: [`INSTALL.md`](INSTALL.md).
224
223
 
225
224
  ```bash
226
- npx @andresmassello/uscha@latest install --target both --dry-run
227
- npx @andresmassello/uscha@latest install --target both
228
- npx @andresmassello/uscha@latest doctor --target both
225
+ npx --yes @andresmassello/uscha@latest version
226
+ npx --yes @andresmassello/uscha@latest install --target codex --dry-run
227
+ npx --yes @andresmassello/uscha@latest install --target codex
228
+ npx --yes @andresmassello/uscha@latest doctor --target codex
229
229
  ```
230
230
 
231
- **Repo checkout install still works and is preferred when developing the kit
232
- itself.** One interface, two adapters: Codex gets a personal local plugin
233
- (`~/plugins/uscha` + `~/.agents/plugins/marketplace.json`), Claude gets global
234
- skills/hooks under `~/.claude`. Use `--dry-run` first on every new machine.
231
+ For a machine used by both Codex and Claude Code:
235
232
 
236
233
  ```bash
237
- python uscha-kit/install-uscha.py version
238
- python uscha-kit/install-uscha.py install --target codex --dry-run
239
- python uscha-kit/install-uscha.py install --target codex
240
- python uscha-kit/install-uscha.py doctor --target codex
234
+ npx --yes @andresmassello/uscha@latest install --target both --dry-run
235
+ npx --yes @andresmassello/uscha@latest install --target both
236
+ npx --yes @andresmassello/uscha@latest doctor --target both
241
237
  ```
242
238
 
243
- For the machine where you DEVELOP the kit, use links instead of copies so the
244
- installed skills follow the canonical repo after `git pull`:
239
+ Use a Git checkout only when developing Uscha itself or testing unreleased
240
+ changes:
245
241
 
246
242
  ```bash
247
243
  python uscha-kit/install-uscha.py install --target both --mode link --dry-run
248
244
  python uscha-kit/install-uscha.py install --target both --mode link
249
245
  ```
250
246
 
251
- Prepare a repo after the machine install:
252
-
253
- ```bash
254
- npx @andresmassello/uscha@latest init --repo <repo> --dry-run
255
- npx @andresmassello/uscha@latest init --repo <repo>
256
- # or from a checkout:
257
- python uscha-kit/install-uscha.py init --repo <repo>
258
- ```
259
-
260
- What remains PER PROJECT (state, not installable): `uscha.config.json` in the
261
- repo root where you run the run (the `path` values are relative to there ? and your declared
262
- quality bar lives there), the `QA-LEDGER.json`, the `ACCEPTANCE.md`, and for migration
263
- work the `.gitattributes` from `templates/` (`*.approved.* binary`).
264
-
265
- **Legacy/manual install** still works: copy `.claude/` and `uscha.config.json`
266
- per project, or copy the `uscha-*` skills to `~/.claude/skills/`. Prefer the
267
- installer unless you are debugging the installer itself.
268
-
269
- **Claude Code plugin** remains available for Claude Code users:
270
-
271
- ```
272
- /plugin marketplace add andresmassello/uscha
273
- /plugin install uscha@uscha
274
- ```
275
-
276
- Updates: `/plugin update uscha@uscha` for Claude Code plugin installs,
277
- `npx @andresmassello/uscha@latest install ...` for npm installs, or rerun
278
- `install-uscha.py install ...` from a repo checkout.
247
+ Claude Code's native plugin flow remains available for Claude-only users, but
248
+ `npx` is the universal path and also covers Codex.
279
249
 
280
250
 
281
251
 
@@ -327,7 +297,7 @@ claude --add-dir ../backend-api --add-dir ../mobile-app
327
297
  Inside Claude Code, invoke the orchestrator (with the ADR/PLAN ready or ask it for one):
328
298
 
329
299
  ```
330
- /dev-loop
300
+ /uscha-devloop
331
301
  ```
332
302
 
333
303
  The skill handles the phases on its own: plan → coverage gate → (characterization if needed)
@@ -367,7 +337,7 @@ result, not on effort spent**:
367
337
 
368
338
  ```bash
369
339
  python3 $QL readiness --acceptance ACCEPTANCE.md
370
- python3 $QL readiness --json # consumed by sys-doc (traffic-light widget)
340
+ python3 $QL readiness --json # consumed by uscha-sysdoc (traffic-light widget)
371
341
  python3 $QL execution-policy --phase qa # one-line methodology/model/effort routing
372
342
  python3 $QL production-finding --repo backend-api --severity HIGH --title "..." --evidence "..."
373
343
  python3 $QL spec-doubt --repo backend-api --kind spec-wrong --note "..." --evidence "..."
@@ -411,7 +381,7 @@ python3 $QL rebuild --mode baseline --config uscha.config.json # → REBUILD-B
411
381
  # SPEC/ADR/ACCEPTANCE, PRESERVING the tests, and run the suite.
412
382
  # 3) score the regenerated tree against the baseline
413
383
  python3 $QL rebuild --mode compare --baseline REBUILD-BASELINE.json # exit 0 = COVERS
414
- python3 $QL rebuild --mode compare --baseline REBUILD-BASELINE.json --json # consumed by sys-doc
384
+ python3 $QL rebuild --mode compare --baseline REBUILD-BASELINE.json --json # consumed by uscha-sysdoc
415
385
  ```
416
386
 
417
387
  - Dimensions/weights: tests 60, acceptance 20, coverage 15, surface 5. The dominant signal
@@ -428,7 +398,7 @@ The **Simplicity** invariant of the CONSTITUTION made a deterministic gate: it s
428
398
  ```bash
429
399
  git diff --unified=0 <base> | python3 $QL simplicity-check --config uscha.config.json
430
400
  python3 $QL simplicity-check --from-git --base main # uses git for you
431
- python3 $QL simplicity-check --diff changes.diff --json # consumed by sys-doc / CI
401
+ python3 $QL simplicity-check --diff changes.diff --json # consumed by uscha-sysdoc / CI
432
402
  ```
433
403
 
434
404
  - Dimensions/weights: diff_size 35, nesting 30, net_growth 20, fan_out 8, blob 7
@@ -443,10 +413,11 @@ python3 $QL simplicity-check --diff changes.diff --json # consumed by sys
443
413
 
444
414
  ## Ledger subcommands
445
415
 
446
- `doctor · init · snapshot · check-coverage · log-step · ingest-gate · log-gate · flag-blocker ·
447
- converged · oscillation · escalate · resolve-escalation · summary · readiness · execution-policy · production-finding · spec-doubt · rebuild ·
448
- simplicity-check · pit-check · gate-check · spec-check · golden-diff · regression-check ·
449
- phase · rubric-ingest · doctor` — each with `--help`.
416
+ `doctor - rubric-ingest - init - snapshot - check-coverage - log-step - ingest-gate - phase -
417
+ converged - oscillation - escalate - resolve-escalation - log-gate - flag-blocker -
418
+ production-finding - spec-doubt - spec-change-request - regression-check - summary - readiness -
419
+ execution-policy - dashboard - rebuild - simplicity-check - waste-check - pit-check - gate-check -
420
+ spec-check - golden-diff` - the exact current `qa_ledger.py` parser surface; each supports `--help`.
450
421
 
451
422
  The **fact gates** (golden-diff, gate-check, pit-check, simplicity) are PERSISTED with
452
423
  `log-gate`: a fail blocks convergence and caps readiness ≤65 via the ledger. A CONSTITUTION
@@ -493,5 +464,5 @@ Inside Claude Code, ask it:
493
464
  List the active rules from CLAUDE.md and the available skills.
494
465
  ```
495
466
 
496
- The protocol rules and the commands /uscha-discovery /uscha-adr-refine
497
- /uscha-devloop /uscha-sysdoc should appear. (For the machine's toolchain: `bash uscha-kit/workbench-doctor.sh`.)
467
+ The protocol rules and the commands `/uscha-discovery`, `/uscha-adr-refine`,
468
+ `/uscha-devloop`, and `/uscha-sysdoc` should appear. (For the machine's toolchain: `bash uscha-kit/workbench-doctor.sh`.)
package/uscha-kit/VERSION CHANGED
@@ -1 +1 @@
1
- uscha-kit 1.40.1
1
+ uscha-kit 1.43.0
@@ -18,11 +18,23 @@ los linters del static gate, drivers) es el *adapter* del proyecto y vive en el
18
18
  | **Python 3.8+** | corre `qa_ledger.py` (stdlib pura, sin dependencias) | `python3` en PATH |
19
19
  | **git** | versionado | 2.x, con `user.name`/`user.email` |
20
20
  | **gh** (GitHub CLI) | crear repo / abrir PR | opcional pero recomendado |
21
- | **skills del kit** | `discovery`, `adr-refine`, `dev-loop`, `sys-doc` | copiados a `~/.claude/skills/` |
21
+ | **skills del kit (8)** | `uscha-discovery`, `uscha-adr-refine`, `uscha-devloop`, `uscha-sysdoc`, `uscha-reverse-discovery`, `uscha-characterize`, `uscha-rubric`, `uscha-mirador` | instalados por `npx` en Codex y/o Claude Code |
22
22
  | **skills de QA** | `code-review`, `judgment-day`, `improve` | tus skills globales (el dev-loop los **orquesta**, no los trae) |
23
23
 
24
24
  ---
25
25
 
26
+ ## Camino feliz: instalar Uscha con npx
27
+
28
+ Uscha instala los skills y la configuracion para Codex, Claude Code o ambos:
29
+
30
+ ```bash
31
+ npx --yes @andresmassello/uscha@latest version
32
+ npx --yes @andresmassello/uscha@latest install --target both
33
+ npx --yes @andresmassello/uscha@latest doctor --target both
34
+ ```
35
+
36
+ `--target codex` o `--target claude` limita la instalacion a un solo entorno. Este es el camino recomendado y portable.
37
+
26
38
  ## 2. Instalar Claude Code
27
39
 
28
40
  **Native installer (recomendado — no requiere Node, se auto-actualiza):**
@@ -87,6 +99,8 @@ gh auth login # habilita gh repo create / gh pr
87
99
 
88
100
  ## 5. Instalar los skills del kit
89
101
 
102
+ **Manual, avanzado/legacy (solo Claude Code; preferi `npx` arriba):**
103
+
90
104
  **Global (todos los repos):**
91
105
 
92
106
  ```bash
@@ -102,14 +116,14 @@ cp -r uscha-kit/.claude/skills <repo>/.claude/
102
116
  cp uscha-kit/uscha.config.json <repo>/ # config en la raíz del repo
103
117
  ```
104
118
 
105
- **Verificar:** abrí `claude` y mirá `/help` — deberían aparecer `/discovery`,
106
- `/adr-refine`, `/dev-loop`, `/sys-doc`. O `ls ~/.claude/skills`.
119
+ **Verificar:** abra `claude` y mire `/help`: deberian aparecer `/uscha-discovery`,
120
+ `/uscha-adr-refine`, `/uscha-devloop`, `/uscha-sysdoc` y las otras cuatro skills del kit. O `ls ~/.claude/skills`.
107
121
 
108
122
  ---
109
123
 
110
124
  ## 6. Los skills de QA externos (dependencia)
111
125
 
112
- El `dev-loop` **orquesta** `code-review` / `judgment-day` / `improve` — **no los empaqueta**.
126
+ El `uscha-devloop` **orquesta** `code-review` / `judgment-day` / `improve` — **no los empaqueta**.
113
127
  Tienen que estar en `~/.claude/skills/` (tus skills globales). Si usás otros nombres,
114
128
  editá `qa_tools_order` en `uscha.config.json`. Si no los tenés, el loop no encuentra
115
129
  las tools de juicio (igual corre el static gate determinístico).
@@ -173,6 +187,6 @@ claude whoami # cuenta autenticada
173
187
  - [ ] `python3 --version` ≥ 3.8
174
188
  - [ ] git configurado (`user.name` / `user.email`)
175
189
  - [ ] `gh auth login` hecho (si vas a abrir PRs)
176
- - [ ] `/discovery` `/adr-refine` `/dev-loop` `/sys-doc` aparecen en `/help`
190
+ - [ ] `/uscha-discovery` `/uscha-adr-refine` `/uscha-devloop` `/uscha-sysdoc` aparecen en `/help`
177
191
  - [ ] `code-review` / `judgment-day` / `improve` presentes (o `qa_tools_order` ajustado)
178
192
  - [ ] `uscha.config.json` en la raíz del repo