wicked-crew 0.7.30 → 0.7.32
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/dist/api/chat-scope.d.ts +15 -2
- package/dist/api/chat-scope.d.ts.map +1 -1
- package/dist/api/chat-scope.js +7 -2
- package/dist/api/chat-scope.js.map +1 -1
- package/dist/api/eval-sample.d.ts +12 -12
- package/dist/api/routes.d.ts +10 -0
- package/dist/api/routes.d.ts.map +1 -1
- package/dist/api/routes.js +231 -37
- package/dist/api/routes.js.map +1 -1
- package/dist/api/run-files.d.ts +26 -0
- package/dist/api/run-files.d.ts.map +1 -1
- package/dist/api/run-files.js +78 -0
- package/dist/api/run-files.js.map +1 -1
- package/dist/api/seat-health.d.ts +33 -0
- package/dist/api/seat-health.d.ts.map +1 -1
- package/dist/api/seat-health.js +86 -2
- package/dist/api/seat-health.js.map +1 -1
- package/dist/api/seat-signin.d.ts +8 -0
- package/dist/api/seat-signin.d.ts.map +1 -1
- package/dist/api/seat-signin.js +48 -3
- package/dist/api/seat-signin.js.map +1 -1
- package/dist/api/seat-standing.d.ts +14 -2
- package/dist/api/seat-standing.d.ts.map +1 -1
- package/dist/api/seat-standing.js +14 -4
- package/dist/api/seat-standing.js.map +1 -1
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +41 -4
- package/dist/api/server.js.map +1 -1
- package/dist/api/skills.d.ts +2 -2
- package/dist/api/testing.d.ts +28 -1
- package/dist/api/testing.d.ts.map +1 -1
- package/dist/api/testing.js +190 -0
- package/dist/api/testing.js.map +1 -1
- package/dist/campaigns/rollup.d.ts +4 -0
- package/dist/campaigns/rollup.d.ts.map +1 -1
- package/dist/campaigns/rollup.js.map +1 -1
- package/dist/campaigns/routes.d.ts +3 -1
- package/dist/campaigns/routes.d.ts.map +1 -1
- package/dist/campaigns/routes.js +3 -0
- package/dist/campaigns/routes.js.map +1 -1
- package/dist/core/adapter.d.ts.map +1 -1
- package/dist/core/adapter.js +23 -2
- package/dist/core/adapter.js.map +1 -1
- package/dist/core/deliver-text.d.ts +7 -0
- package/dist/core/deliver-text.d.ts.map +1 -1
- package/dist/core/deliver-text.js +41 -2
- package/dist/core/deliver-text.js.map +1 -1
- package/dist/core/engine-roster.d.ts +68 -0
- package/dist/core/engine-roster.d.ts.map +1 -0
- package/dist/core/engine-roster.js +156 -0
- package/dist/core/engine-roster.js.map +1 -0
- package/dist/interactive/chat-events.d.ts.map +1 -1
- package/dist/interactive/chat-events.js +26 -4
- package/dist/interactive/chat-events.js.map +1 -1
- package/dist/interactive/council-outcome.d.ts +28 -1
- package/dist/interactive/council-outcome.d.ts.map +1 -1
- package/dist/interactive/council-outcome.js +51 -1
- package/dist/interactive/council-outcome.js.map +1 -1
- package/dist/interactive/demo-events.d.ts.map +1 -1
- package/dist/interactive/demo-events.js +26 -4
- package/dist/interactive/demo-events.js.map +1 -1
- package/dist/interactive/doc-run-index.d.ts +56 -0
- package/dist/interactive/doc-run-index.d.ts.map +1 -0
- package/dist/interactive/doc-run-index.js +100 -0
- package/dist/interactive/doc-run-index.js.map +1 -0
- package/dist/interactive/docs-index.d.ts +68 -0
- package/dist/interactive/docs-index.d.ts.map +1 -0
- package/dist/interactive/docs-index.js +114 -0
- package/dist/interactive/docs-index.js.map +1 -0
- package/dist/interactive/draft-events.d.ts +18 -0
- package/dist/interactive/draft-events.d.ts.map +1 -1
- package/dist/interactive/draft-events.js +36 -3
- package/dist/interactive/draft-events.js.map +1 -1
- package/dist/interactive/edit-events.d.ts.map +1 -1
- package/dist/interactive/edit-events.js +26 -4
- package/dist/interactive/edit-events.js.map +1 -1
- package/dist/interactive/ledger.d.ts +2 -0
- package/dist/interactive/ledger.d.ts.map +1 -1
- package/dist/interactive/ledger.js +4 -0
- package/dist/interactive/ledger.js.map +1 -1
- package/dist/qe/acceptance.d.ts +72 -3
- package/dist/qe/acceptance.d.ts.map +1 -1
- package/dist/qe/acceptance.js +137 -17
- package/dist/qe/acceptance.js.map +1 -1
- package/dist/qe/author-workflow.d.ts +165 -0
- package/dist/qe/author-workflow.d.ts.map +1 -0
- package/dist/qe/author-workflow.js +377 -0
- package/dist/qe/author-workflow.js.map +1 -0
- package/dist/qe/ledger.d.ts +128 -28
- package/dist/qe/ledger.d.ts.map +1 -1
- package/dist/qe/ledger.js +272 -42
- package/dist/qe/ledger.js.map +1 -1
- package/dist/qe/test-sets.d.ts +112 -0
- package/dist/qe/test-sets.d.ts.map +1 -0
- package/dist/qe/test-sets.js +170 -0
- package/dist/qe/test-sets.js.map +1 -0
- package/dist/skills/refs.d.ts +37 -0
- package/dist/skills/refs.d.ts.map +1 -1
- package/dist/skills/refs.js +22 -0
- package/dist/skills/refs.js.map +1 -1
- package/dist/skills/runtime.d.ts +13 -1
- package/dist/skills/runtime.d.ts.map +1 -1
- package/dist/skills/runtime.js +88 -1
- package/dist/skills/runtime.js.map +1 -1
- package/dist/skills/store.d.ts +82 -5
- package/dist/skills/store.d.ts.map +1 -1
- package/dist/skills/store.js +109 -21
- package/dist/skills/store.js.map +1 -1
- package/dist/studio/assets/{index-_ydd-jKd.css → index-C0UZ2BxT.css} +1 -1
- package/dist/studio/assets/index-Clm0MXDF.js +544 -0
- package/dist/studio/index.html +2 -2
- package/dist/studio/testid-inventory.json +251 -5
- package/endpoint-manifest.json +24 -1
- package/package.json +3 -3
- package/dist/studio/assets/index-CWUS9Ump.js +0 -542
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `qe-author-tests` — the governed test-authoring workflow (wave 6: F-7R2-003/004/005/012/014/015,
|
|
3
|
+
* acceptance verdict R4-r2), workflows-as-data.
|
|
4
|
+
*
|
|
5
|
+
* ## Why a workflow, not a free-text run
|
|
6
|
+
*
|
|
7
|
+
* The studio's "New test" used to `POST /testing/recon` a plain free-text governed run: the planner
|
|
8
|
+
* split the brief at sentence boundaries into seven alternating agent units, two of them chat
|
|
9
|
+
* replies ("Gate protocol acknowledged … What is the next task?"), every gate a vacuous
|
|
10
|
+
* default-allow, no `skill_ref` anywhere (the 40-specialist QE domain never routed), no deliver
|
|
11
|
+
* phase (the LAST worker opened the PR from its own shell — invisible to the ledger), no campaign
|
|
12
|
+
* registered (the Test landing stayed empty), and the produced Playwright e2e was never executed by
|
|
13
|
+
* the run — it failed at its first check on the first independent run (R4-r2: 0 of 12 checks).
|
|
14
|
+
*
|
|
15
|
+
* This def is the fix, as data the engine validates AS AUTHORED (wicked-core#414 — a code-writing
|
|
16
|
+
* agent phase carries the evidence-floor pin, the verified-evidence phase carries it too):
|
|
17
|
+
*
|
|
18
|
+
* recon (agent, neutral, `wicked-garden-qe` plan) — read the repo + its tests, detect the
|
|
19
|
+
* harness, map intent → behaviours → gaps
|
|
20
|
+
* author (agent, CREATOR, `wicked-garden-qe` author, — write behaviour tests against the repo's
|
|
21
|
+
* executes_code, evidence-floor pinned) own harness + `tests/PLAN-<slug>.md`
|
|
22
|
+
* verify (TOOL, verified_evidence, pinned) — {@link qeVerifyScript}: run the repo's own
|
|
23
|
+
* checks INCLUDING every produced test;
|
|
24
|
+
* FAIL if any fails or was never executed
|
|
25
|
+
* review (agent, EVALUATOR, `wicked-garden-qe` review,— independent fitness verdict; escalates a
|
|
26
|
+
* pinned, human_confirm_if verdict_not_pass) not-pass to a human, never auto-denies
|
|
27
|
+
* deliver — NOT here. Appended per run by the ENGINE-side composition (`deliver: "pr"`, the
|
|
28
|
+
* crew#393 default for a repo-scoped code-work def): the engine lifts, re-verifies,
|
|
29
|
+
* pushes and opens the PR so the ledger records the delivery. A worker seat never
|
|
30
|
+
* pushes (the wave-6 engine's remote-write fence refuses `git push`/`gh pr create`).
|
|
31
|
+
*
|
|
32
|
+
* The METHOD lives in the garden skill (`wicked-garden-qe`, actions plan/author/review) — each
|
|
33
|
+
* phase's inline `instructions` is a one-line orientation only, because a governed worker's prompt
|
|
34
|
+
* rides a single PTY line capped at 1022 bytes (wicked-core execute_wrapped.rs) and the planner
|
|
35
|
+
* folds the instructions onto that line beside the run intent.
|
|
36
|
+
*
|
|
37
|
+
* Crew-authored drop-in (like `capture-learnings`): NOT core-seeded, so `launchRun`'s
|
|
38
|
+
* `_writeBuiltinOverlay` write is the only way the engine resolves the id. Not `is_system`: it IS an
|
|
39
|
+
* operator-selectable work mode (the catalog finally carries something labelled test/QE — F-075).
|
|
40
|
+
*/
|
|
41
|
+
import { EVIDENCE_FLOOR_PIN } from '../core/deliver.js';
|
|
42
|
+
/** The workflow id — `GET /workflows` lists it; `POST /testing/author` launches it. */
|
|
43
|
+
export const QE_AUTHOR_TESTS_WORKFLOW = 'qe-author-tests';
|
|
44
|
+
/** The garden skill every agent phase routes through (`skills/qe/SKILL.md`, actions by name). */
|
|
45
|
+
export const QE_SKILL = 'wicked-garden-qe';
|
|
46
|
+
/** The deterministic verification phase's id (its unit is `<run>:verify` on the wire). */
|
|
47
|
+
export const QE_VERIFY_PHASE_ID = 'verify';
|
|
48
|
+
/** Per-produced-file marker the verify phase prints: `QE-VERIFY: file=… harness=… exit=… status=…`. */
|
|
49
|
+
export const QE_VERIFY_MARKER = 'QE-VERIFY:';
|
|
50
|
+
/** Repo-own-checks marker: `QE-VERIFY-CHECK: harness=… cmd="…" exit=…`. */
|
|
51
|
+
export const QE_VERIFY_CHECK_MARKER = 'QE-VERIFY-CHECK:';
|
|
52
|
+
/** The one summary line: `QE-VERIFY-SUMMARY: produced=N executed=N passed=N failed=N …`. */
|
|
53
|
+
export const QE_VERIFY_SUMMARY_MARKER = 'QE-VERIFY-SUMMARY:';
|
|
54
|
+
/** Where the author phase must record its plan (glob, repo-relative). */
|
|
55
|
+
export const QE_PLAN_GLOB = 'tests/PLAN-*.md';
|
|
56
|
+
/** Ceiling for each phase's inline orientation — the PTY line also carries the intent. */
|
|
57
|
+
export const QE_MAX_INLINE_INSTRUCTION_BYTES = 600;
|
|
58
|
+
const RECON_INSTRUCTIONS = 'Phase 1/4 PLAN (qe skill, plan action): read the repository and its existing tests, detect the ' +
|
|
59
|
+
'test harness (vitest/jest/pytest/Playwright and any loopback e2e fixture), map the operator ' +
|
|
60
|
+
'intent to behaviours, and list the coverage gaps — cite file:line for anything you claim is ' +
|
|
61
|
+
'already covered. Analysis only: write no files.';
|
|
62
|
+
const AUTHOR_INSTRUCTIONS = 'Phase 2/4 AUTHOR (qe skill, author action): write BEHAVIOUR tests for the planned gaps against ' +
|
|
63
|
+
"the repository's own harness, plus tests/PLAN-<slug>.md recording each test, the exact command " +
|
|
64
|
+
'that runs it and its observed result. RUN every test you write before claiming it. Never push, ' +
|
|
65
|
+
"never open or edit a pull request — the run's deliver phase does that.";
|
|
66
|
+
const REVIEW_INSTRUCTIONS = 'Phase 4/4 REVIEW (qe skill, review action): judge the produced tests independently — behaviour ' +
|
|
67
|
+
'vs implementation coupling, every claim of existing coverage verified at file:line, no sleeps ' +
|
|
68
|
+
"or flaky waits, the PLAN matches what shipped, and the verify phase's QE-VERIFY report shows " +
|
|
69
|
+
'every produced test executed. Verdict PASS or FAIL with reasons. Read-only: change nothing.';
|
|
70
|
+
/**
|
|
71
|
+
* The verify phase's script — the R4-r2 floor: a produced test that fails, or was never run, FAILS
|
|
72
|
+
* the unit. Runs in the run worktree as `bash -lc`:
|
|
73
|
+
*
|
|
74
|
+
* 1. BASE — the run branch's fork point off origin's default branch (the engine's own derivation
|
|
75
|
+
* order: origin/HEAD, origin/main, origin/master; then a local main/master; else HEAD).
|
|
76
|
+
* 2. PRODUCED — every path changed/added since BASE plus every untracked file: the run's own work,
|
|
77
|
+
* committed or not. Test files are the conventional shapes (`*.test.*`, `*.spec.*`, `*_test.py`,
|
|
78
|
+
* `test_*.py`, `__tests__/`); fixtures, factories and the PLAN are produced but not "tests".
|
|
79
|
+
* 3. HARNESS per file — the REPOSITORY's own, resolved PER FILE by walking up from the file's
|
|
80
|
+
* directory to the nearest marker (monorepo-aware — review H-1/M-1 of #536): Playwright
|
|
81
|
+
* (`playwright.config.*` / `@playwright/test` in the nearest package.json) for `*.spec.*`, a
|
|
82
|
+
* Python Playwright rig (imports `playwright`), vitest/jest from the nearest package.json that
|
|
83
|
+
* declares them, pytest for every other test-shaped `.py` (nearest `pytest.ini` / `conftest.py`
|
|
84
|
+
* / `tox.ini` / `pyproject.toml [tool.pytest]` / `setup.cfg [tool:pytest]` dir, else the root).
|
|
85
|
+
* The RUNNER is the nearest `node_modules/.bin/<tool>` (or `.venv/bin/pytest` / an importable
|
|
86
|
+
* pytest) from that package dir up to the worktree root — NEVER `npx` (a registry fetch on the
|
|
87
|
+
* verify path) and NEVER a plain interpreter for a test-shaped file (a pytest module run as
|
|
88
|
+
* `python3 file.py` defines its functions and exits 0 with zero assertions — a vacuous PASS).
|
|
89
|
+
* A missing/unrunnable runner is NOT EXECUTED = fail, with "harness not available: <tool>" and
|
|
90
|
+
* the remedy (install the dependencies in the worktree in the author phase). The runner runs
|
|
91
|
+
* FROM its package dir with a package-relative path.
|
|
92
|
+
* 4. COLLECTED — every executed file must show ≥ 1 test in the RUNNER's own summary (pytest
|
|
93
|
+
* `N passed` / `collected N items`, vitest `Tests N passed`, jest `N total`, Playwright
|
|
94
|
+
* `N passed`, a Python rig's check/pass lines); exit 0 with 0 tests reported = NOT EXECUTED.
|
|
95
|
+
* 5. REPO CHECKS — the full unit suite of every (harness, package dir) a produced test used
|
|
96
|
+
* (vitest/jest/pytest) runs once too, so the produced tests are verified INSIDE the repository's
|
|
97
|
+
* own check, not beside it. The Playwright suite is not re-run whole (its produced specs ran
|
|
98
|
+
* individually).
|
|
99
|
+
* 6. VERDICT — `QE-VERIFY-SUMMARY:` then exit 0 only when: ≥ 1 produced test, every one executed
|
|
100
|
+
* with ≥ 1 test collected, none failed, the PLAN exists, and the repo checks passed. Every
|
|
101
|
+
* refusal names its reason.
|
|
102
|
+
*
|
|
103
|
+
* `set -u -o pipefail` but NOT `-e`: each command's exit is captured deliberately. `exec 2>&1`
|
|
104
|
+
* keeps the transcript chronological (the engine appends stderr after stdout otherwise).
|
|
105
|
+
*/
|
|
106
|
+
export function qeVerifyScript() {
|
|
107
|
+
return [
|
|
108
|
+
'set -uo pipefail',
|
|
109
|
+
'exec 2>&1',
|
|
110
|
+
'echo "QE-VERIFY-BEGIN worktree=$PWD"',
|
|
111
|
+
// 1. base
|
|
112
|
+
'D=$(git symbolic-ref -q --short refs/remotes/origin/HEAD || true)',
|
|
113
|
+
'if [ -z "$D" ] || ! git rev-parse --verify -q "$D^{commit}" >/dev/null; then',
|
|
114
|
+
' if git rev-parse --verify -q origin/main^{commit} >/dev/null; then D=origin/main;',
|
|
115
|
+
' elif git rev-parse --verify -q origin/master^{commit} >/dev/null; then D=origin/master;',
|
|
116
|
+
' elif git rev-parse --verify -q main^{commit} >/dev/null; then D=main;',
|
|
117
|
+
' elif git rev-parse --verify -q master^{commit} >/dev/null; then D=master;',
|
|
118
|
+
' else D=""; fi',
|
|
119
|
+
'fi',
|
|
120
|
+
'if [ -n "$D" ]; then BASE=$(git merge-base "$D" HEAD 2>/dev/null || git rev-parse HEAD); else BASE=$(git rev-parse HEAD); fi',
|
|
121
|
+
'echo "QE-VERIFY-BASE ref=${D:-HEAD} commit=$BASE"',
|
|
122
|
+
// 2. produced
|
|
123
|
+
'PRODUCED=$( { git diff --name-only --diff-filter=AMR "$BASE" -- . ; git ls-files --others --exclude-standard ; } | sort -u )',
|
|
124
|
+
'is_test_path() {',
|
|
125
|
+
' case "$1" in *.md|*.json|*.snap|*.txt|*.yml|*.yaml|*.toml|*.lock|*.html|*.css|*.png|*.svg) return 1;; esac',
|
|
126
|
+
' case "$1" in *.test.*|*.spec.*|*_test.py|test_*.py|*/test_*.py|__tests__/*|*/__tests__/*) return 0;; esac',
|
|
127
|
+
' return 1',
|
|
128
|
+
'}',
|
|
129
|
+
// 3. harness detection — PER FILE, nearest marker dir walking UP from the file (monorepo-aware)
|
|
130
|
+
'pkg_has_dep() { [ -f "$1/package.json" ] && grep -Eq "\\"$2\\"[[:space:]]*:" "$1/package.json"; }',
|
|
131
|
+
'is_pw_dir() { ls "$1"/playwright.config.* >/dev/null 2>&1 || pkg_has_dep "$1" "@playwright/test"; }',
|
|
132
|
+
'is_vitest_dir() { pkg_has_dep "$1" vitest; }',
|
|
133
|
+
'is_jest_dir() { pkg_has_dep "$1" jest; }',
|
|
134
|
+
'is_py_dir() { [ -f "$1/pytest.ini" ] || [ -f "$1/conftest.py" ] || [ -f "$1/tox.ini" ] || { [ -f "$1/pyproject.toml" ] && grep -q "tool.pytest" "$1/pyproject.toml"; } || { [ -f "$1/setup.cfg" ] && grep -q "tool:pytest" "$1/setup.cfg"; }; }',
|
|
135
|
+
'nearest() { local d; d=$(dirname "$1"); while :; do if "$2" "$d"; then echo "$d"; return 0; fi; [ "$d" = "." ] && break; d=$(dirname "$d"); done; echo ""; return 1; }',
|
|
136
|
+
// the runner: the nearest node_modules/.bin/<tool> from the package dir up to the worktree root,
|
|
137
|
+
// spelled RELATIVE TO the package dir (every command runs from there: `./…` or `../…`) — NEVER npx
|
|
138
|
+
'find_bin() { local d="$1" up=""; while :; do if [ -x "$d/node_modules/.bin/$2" ]; then echo "${up:-./}node_modules/.bin/$2"; return 0; fi; [ "$d" = "." ] && break; d=$(dirname "$d"); up="../$up"; done; echo ""; return 1; }',
|
|
139
|
+
'find_pytest() { local d="$1" up=""; while :; do if [ -x "$d/.venv/bin/pytest" ]; then echo "${up:-./}.venv/bin/pytest"; return 0; fi; [ "$d" = "." ] && break; d=$(dirname "$d"); up="../$up"; done; if python3 -c "import pytest" >/dev/null 2>&1; then echo "python3 -m pytest"; return 0; fi; echo ""; return 1; }',
|
|
140
|
+
'resolve() {',
|
|
141
|
+
' local d',
|
|
142
|
+
' case "$1" in',
|
|
143
|
+
' *.py)',
|
|
144
|
+
' if grep -Eq "^[[:space:]]*(from|import)[[:space:]]+playwright" "$1" 2>/dev/null; then echo "playwright-python $(dirname "$1")"; return; fi',
|
|
145
|
+
' d=$(nearest "$1" is_py_dir); [ -n "$d" ] || d="."',
|
|
146
|
+
' echo "pytest $d"; return;;',
|
|
147
|
+
' esac',
|
|
148
|
+
' case "$1" in *.spec.*) d=$(nearest "$1" is_pw_dir); if [ -n "$d" ]; then echo "playwright $d"; return; fi;; esac',
|
|
149
|
+
' d=$(nearest "$1" is_vitest_dir); if [ -n "$d" ]; then echo "vitest $d"; return; fi',
|
|
150
|
+
' d=$(nearest "$1" is_jest_dir); if [ -n "$d" ]; then echo "jest $d"; return; fi',
|
|
151
|
+
' d=$(nearest "$1" is_pw_dir); if [ -n "$d" ]; then echo "playwright $d"; return; fi',
|
|
152
|
+
' echo "unknown ."',
|
|
153
|
+
'}',
|
|
154
|
+
// how many tests the RUNNER says it executed (its own summary line) — 0 = nothing ran
|
|
155
|
+
'sum_counts() { grep -E "$2" "$1" | tail -1 | awk \'{s=0; for(i=1;i<=NF;i++) if($i ~ /^[0-9]+$/ && $(i+1) ~ /^(passed|failed|flaky|skipped|total)/) s+=$i; print s}\'; }',
|
|
156
|
+
'collected() {',
|
|
157
|
+
' local n=""',
|
|
158
|
+
' case "$1" in',
|
|
159
|
+
' pytest) n=$(sum_counts "$2" "[0-9]+ (passed|failed)"); [ "${n:-0}" -gt 0 ] || n=$(grep -Eo "collected [0-9]+ item" "$2" | tail -1 | grep -Eo "[0-9]+");;',
|
|
160
|
+
' vitest) n=$(sum_counts "$2" "^[[:space:]]*Tests[[:space:]]");;',
|
|
161
|
+
' jest) n=$(grep -Eo "[0-9]+ total" "$2" | tail -1 | grep -Eo "[0-9]+");;',
|
|
162
|
+
' playwright) n=$(sum_counts "$2" "[0-9]+ (passed|failed|flaky)");;',
|
|
163
|
+
' playwright-python) n=$(grep -Eci "passed|\\bpass\\b|✓|\\"checks\\"|\\bok\\b" "$2");;',
|
|
164
|
+
' esac',
|
|
165
|
+
' echo "${n:-0}"',
|
|
166
|
+
'}',
|
|
167
|
+
'P=0; E=0; PASS=0; FAIL=0; NX=0; PLAN=""; HARNESSES=""',
|
|
168
|
+
'not_executed() { NX=$((NX+1)); echo "QE-VERIFY: file=$1 harness=$2 pkg=$3 cmd=\\"\\" exit=- tests=0 status=not-executed reason=\\"$4\\""; echo "qe-verify: $1 — $4"; }',
|
|
169
|
+
'while IFS= read -r f; do',
|
|
170
|
+
' [ -n "$f" ] || continue',
|
|
171
|
+
' case "$f" in tests/PLAN-*.md|*/tests/PLAN-*.md) PLAN="$f";; esac',
|
|
172
|
+
' is_test_path "$f" || continue',
|
|
173
|
+
' P=$((P+1))',
|
|
174
|
+
' R=$(resolve "$f"); H="${R%% *}"; PKG="${R#* }"',
|
|
175
|
+
' rel="$f"; [ "$PKG" = "." ] || rel="${f#$PKG/}"',
|
|
176
|
+
' case "$H" in',
|
|
177
|
+
' playwright) BIN=$(find_bin "$PKG" playwright) || { not_executed "$f" "$H" "$PKG" "harness not available: playwright (@playwright/test) — no node_modules/.bin/playwright from $PKG up to the worktree root; install the repository dependencies in the worktree (npm ci) in the author phase. The verify path never runs npx"; continue; }; CMD=("$BIN" test "$rel");;',
|
|
178
|
+
' vitest) BIN=$(find_bin "$PKG" vitest) || { not_executed "$f" "$H" "$PKG" "harness not available: vitest — no node_modules/.bin/vitest from $PKG up to the worktree root; install the repository dependencies in the worktree (npm ci) in the author phase. The verify path never runs npx"; continue; }; CMD=("$BIN" run "$rel");;',
|
|
179
|
+
' jest) BIN=$(find_bin "$PKG" jest) || { not_executed "$f" "$H" "$PKG" "harness not available: jest — no node_modules/.bin/jest from $PKG up to the worktree root; install the repository dependencies in the worktree (npm ci) in the author phase. The verify path never runs npx"; continue; }; CMD=("$BIN" "$rel");;',
|
|
180
|
+
' pytest) PT=$(find_pytest "$PKG") || { not_executed "$f" "$H" "$PKG" "harness not available: pytest — no .venv/bin/pytest from $PKG up to the worktree root and python3 cannot import pytest; a test-shaped .py file is NEVER run as a plain script (it would pass with zero assertions). Install pytest in the worktree in the author phase"; continue; }; if [ "$PT" = "python3 -m pytest" ]; then CMD=(python3 -m pytest -q "$rel"); else CMD=("$PT" -q "$rel"); fi;;',
|
|
181
|
+
' playwright-python) python3 -c "import playwright" >/dev/null 2>&1 || { not_executed "$f" "$H" "$PKG" "harness not available: playwright (python) — python3 cannot import playwright; pip install playwright && playwright install chromium in the author phase"; continue; }; CMD=(python3 "$rel");;',
|
|
182
|
+
' *) not_executed "$f" unknown "$PKG" "no harness recognised — declare one the repository owns (playwright.config.*, vitest/jest in the nearest package.json, a pytest marker)"; continue;;',
|
|
183
|
+
' esac',
|
|
184
|
+
' case " $HARNESSES " in *" $H|$PKG "*) ;; *) HARNESSES="$HARNESSES $H|$PKG";; esac',
|
|
185
|
+
' echo "QE-VERIFY-RUN file=$f harness=$H pkg=$PKG cmd=\\"${CMD[*]}\\""',
|
|
186
|
+
' OUT=$(mktemp)',
|
|
187
|
+
' ( cd "$PKG" && "${CMD[@]}" ) 2>&1 | tee "$OUT"; RC=${PIPESTATUS[0]}',
|
|
188
|
+
' N=$(collected "$H" "$OUT"); rm -f "$OUT"',
|
|
189
|
+
' E=$((E+1))',
|
|
190
|
+
' if [ "$RC" -ne 0 ]; then FAIL=$((FAIL+1)); ST=failed;',
|
|
191
|
+
' elif [ "${N:-0}" -lt 1 ]; then NX=$((NX+1)); E=$((E-1)); ST=not-executed; echo "qe-verify: $f — the $H runner exited 0 but reported 0 tests (nothing was collected or executed)";',
|
|
192
|
+
' else PASS=$((PASS+1)); ST=passed; fi',
|
|
193
|
+
' echo "QE-VERIFY: file=$f harness=$H pkg=$PKG cmd=\\"${CMD[*]}\\" exit=$RC tests=${N:-0} status=$ST"',
|
|
194
|
+
"done < <(printf '%s\\n' \"$PRODUCED\")",
|
|
195
|
+
// 4. repo checks — the full unit suite once per (harness, package dir) the produced tests used
|
|
196
|
+
'C=0; CF=0',
|
|
197
|
+
'for HP in $HARNESSES; do',
|
|
198
|
+
' H="${HP%%|*}"; PKG="${HP#*|}"',
|
|
199
|
+
' case "$H" in',
|
|
200
|
+
' vitest) BIN=$(find_bin "$PKG" vitest); CMD=("$BIN" run);;',
|
|
201
|
+
' jest) BIN=$(find_bin "$PKG" jest); CMD=("$BIN");;',
|
|
202
|
+
' pytest) PT=$(find_pytest "$PKG"); if [ "$PT" = "python3 -m pytest" ]; then CMD=(python3 -m pytest -q); else CMD=("$PT" -q); fi;;',
|
|
203
|
+
' *) echo "QE-VERIFY-CHECK: harness=$H pkg=$PKG skipped=full-suite (produced files ran individually)"; continue;;',
|
|
204
|
+
' esac',
|
|
205
|
+
' C=$((C+1))',
|
|
206
|
+
' echo "QE-VERIFY-CHECK-RUN harness=$H pkg=$PKG cmd=\\"${CMD[*]}\\""',
|
|
207
|
+
' ( cd "$PKG" && "${CMD[@]}" ); RC=$?',
|
|
208
|
+
' [ "$RC" -eq 0 ] || CF=$((CF+1))',
|
|
209
|
+
' echo "QE-VERIFY-CHECK: harness=$H pkg=$PKG cmd=\\"${CMD[*]}\\" exit=$RC"',
|
|
210
|
+
'done',
|
|
211
|
+
// 5. verdict
|
|
212
|
+
'echo "QE-VERIFY-SUMMARY: produced=$P executed=$E passed=$PASS failed=$FAIL not_executed=$NX plan=${PLAN:-missing} checks=$C checks_failed=$CF"',
|
|
213
|
+
'[ "$P" -gt 0 ] || { echo "qe-verify: FAIL — the author phase produced no test files; nothing was verified, so done cannot be asserted"; exit 1; }',
|
|
214
|
+
'[ -n "$PLAN" ] || { echo "qe-verify: FAIL — no tests/PLAN-*.md was produced (the plan records every test, the command that ran it and its result)"; exit 1; }',
|
|
215
|
+
'[ "$NX" -eq 0 ] || { echo "qe-verify: FAIL — $NX produced test file(s) were never executed (no available harness, or the runner reported 0 tests); a test that never ran proves nothing"; exit 1; }',
|
|
216
|
+
'[ "$FAIL" -eq 0 ] || { echo "qe-verify: FAIL — $FAIL of $E produced test file(s) failed under the repository harness"; exit 1; }',
|
|
217
|
+
'[ "$CF" -eq 0 ] || { echo "qe-verify: FAIL — $CF repository check(s) failed with the produced tests in the tree"; exit 1; }',
|
|
218
|
+
'echo "qe-verify: PASS — $E produced test file(s) executed and passed under the repository harness; plan $PLAN"',
|
|
219
|
+
].join('\n');
|
|
220
|
+
}
|
|
221
|
+
function agentPhase(id, kind, instructions, over) {
|
|
222
|
+
return {
|
|
223
|
+
id,
|
|
224
|
+
kind,
|
|
225
|
+
instructions,
|
|
226
|
+
gate_type: 'execution',
|
|
227
|
+
gate: 'auto',
|
|
228
|
+
executes_code: false,
|
|
229
|
+
verified_evidence: false,
|
|
230
|
+
required_deliverables: [],
|
|
231
|
+
depends_on: [],
|
|
232
|
+
role: 'neutral',
|
|
233
|
+
skill_ref: QE_SKILL,
|
|
234
|
+
allowed_skills: [],
|
|
235
|
+
validator_pin: null,
|
|
236
|
+
...over,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
/** The verify TOOL phase — deterministic, pinned to the evidence floor (the run left a change),
|
|
240
|
+
* `executes_code: false` like the deliver phase: engine-owned tooling, not governed agent work
|
|
241
|
+
* (a Tool unit is never worktree-guarded, so the harness's caches cannot deny it). */
|
|
242
|
+
export function qeVerifyPhase(dependsOn = ['author']) {
|
|
243
|
+
return {
|
|
244
|
+
id: QE_VERIFY_PHASE_ID,
|
|
245
|
+
kind: 'test',
|
|
246
|
+
executor: { type: 'tool', cmd: ['bash', '-lc', qeVerifyScript()] },
|
|
247
|
+
gate_type: 'execution',
|
|
248
|
+
gate: 'auto',
|
|
249
|
+
executes_code: false,
|
|
250
|
+
verified_evidence: true,
|
|
251
|
+
required_deliverables: [],
|
|
252
|
+
depends_on: dependsOn,
|
|
253
|
+
role: 'neutral',
|
|
254
|
+
skill_ref: null,
|
|
255
|
+
allowed_skills: [],
|
|
256
|
+
validator_pin: EVIDENCE_FLOOR_PIN,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/** The shipped definition (see the module doc). Exported as data — tests assert it, the adapter
|
|
260
|
+
* serves it from `BUILTIN_WORKFLOWS`, and the engine validates it as authored at the overlay write. */
|
|
261
|
+
export const QE_AUTHOR_TESTS_WORKFLOW_DEF = {
|
|
262
|
+
id: QE_AUTHOR_TESTS_WORKFLOW,
|
|
263
|
+
phases: [
|
|
264
|
+
agentPhase('recon', 'recon', RECON_INSTRUCTIONS, { gate_type: 'strategy', role: 'neutral' }),
|
|
265
|
+
agentPhase('author', 'build', AUTHOR_INSTRUCTIONS, {
|
|
266
|
+
depends_on: ['recon'],
|
|
267
|
+
role: 'creator',
|
|
268
|
+
executes_code: true,
|
|
269
|
+
validator_pin: EVIDENCE_FLOOR_PIN,
|
|
270
|
+
}),
|
|
271
|
+
qeVerifyPhase(['author']),
|
|
272
|
+
agentPhase('review', 'review', REVIEW_INSTRUCTIONS, {
|
|
273
|
+
depends_on: [QE_VERIFY_PHASE_ID],
|
|
274
|
+
role: 'evaluator',
|
|
275
|
+
gate: { human_confirm_if: 'verdict_not_pass' },
|
|
276
|
+
validator_pin: EVIDENCE_FLOOR_PIN,
|
|
277
|
+
}),
|
|
278
|
+
],
|
|
279
|
+
};
|
|
280
|
+
/** `key=value` and `key="quoted value"` pairs of one marker line. */
|
|
281
|
+
function fields(rest) {
|
|
282
|
+
const out = {};
|
|
283
|
+
const re = /([a-z_]+)=("([^"]*)"|\S*)/g;
|
|
284
|
+
for (const m of rest.matchAll(re))
|
|
285
|
+
out[m[1]] = m[3] !== undefined ? m[3] : (m[2] ?? '');
|
|
286
|
+
return out;
|
|
287
|
+
}
|
|
288
|
+
function int(v) {
|
|
289
|
+
const n = Number(v);
|
|
290
|
+
return Number.isInteger(n) && n >= 0 ? n : 0;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Parse the verify unit's transcript into a {@link QeVerifyReport}. `null` when the transcript
|
|
294
|
+
* carries no `QE-VERIFY-SUMMARY:` line (the phase never reached its verdict — the unit's status
|
|
295
|
+
* and `denial_reason` say why).
|
|
296
|
+
*/
|
|
297
|
+
export function parseQeVerifyOutput(text) {
|
|
298
|
+
const files = [];
|
|
299
|
+
const checks = [];
|
|
300
|
+
let summary = null;
|
|
301
|
+
for (const raw of text.split('\n')) {
|
|
302
|
+
const line = raw.trim();
|
|
303
|
+
if (line.startsWith(QE_VERIFY_SUMMARY_MARKER)) {
|
|
304
|
+
summary = fields(line.slice(QE_VERIFY_SUMMARY_MARKER.length));
|
|
305
|
+
}
|
|
306
|
+
else if (line.startsWith(QE_VERIFY_CHECK_MARKER)) {
|
|
307
|
+
const f = fields(line.slice(QE_VERIFY_CHECK_MARKER.length));
|
|
308
|
+
if (f['skipped'] !== undefined || f['harness'] === undefined || f['exit'] === undefined)
|
|
309
|
+
continue;
|
|
310
|
+
checks.push({ harness: f['harness'], cmd: f['cmd'] ?? '', exit: int(f['exit']) });
|
|
311
|
+
}
|
|
312
|
+
else if (line.startsWith(QE_VERIFY_MARKER)) {
|
|
313
|
+
const f = fields(line.slice(QE_VERIFY_MARKER.length));
|
|
314
|
+
if (f['file'] === undefined)
|
|
315
|
+
continue;
|
|
316
|
+
const status = f['status'] === 'passed' || f['status'] === 'failed' ? f['status'] : 'not-executed';
|
|
317
|
+
// A file the runner ran but reported 0 tests for carries its exit code; a file never handed
|
|
318
|
+
// to a runner has `exit=-` (→ null).
|
|
319
|
+
const exit = f['exit'] === undefined || f['exit'] === '-' ? null : int(f['exit']);
|
|
320
|
+
files.push({
|
|
321
|
+
path: f['file'],
|
|
322
|
+
harness: f['harness'] ?? 'unknown',
|
|
323
|
+
cmd: f['cmd'] ?? '',
|
|
324
|
+
exit,
|
|
325
|
+
tests: int(f['tests']),
|
|
326
|
+
pkg: f['pkg'] === undefined || f['pkg'] === '' ? '.' : f['pkg'],
|
|
327
|
+
status,
|
|
328
|
+
...(f['reason'] !== undefined && f['reason'] !== '' ? { reason: f['reason'] } : {}),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (summary === null)
|
|
333
|
+
return null;
|
|
334
|
+
return {
|
|
335
|
+
files,
|
|
336
|
+
checks,
|
|
337
|
+
produced: int(summary['produced']),
|
|
338
|
+
executed: int(summary['executed']),
|
|
339
|
+
passed: int(summary['passed']),
|
|
340
|
+
failed: int(summary['failed']),
|
|
341
|
+
notExecuted: int(summary['not_executed']),
|
|
342
|
+
plan: summary['plan'] === undefined || summary['plan'] === 'missing' ? null : summary['plan'],
|
|
343
|
+
checksFailed: int(summary['checks_failed']),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function gateLabel(gate) {
|
|
347
|
+
if (typeof gate === 'object' && gate !== null && 'human_confirm' in gate)
|
|
348
|
+
return 'human';
|
|
349
|
+
if (typeof gate === 'object' && gate !== null && 'human_confirm_if' in gate)
|
|
350
|
+
return 'human_if_not_pass';
|
|
351
|
+
return 'auto';
|
|
352
|
+
}
|
|
353
|
+
export function qeAuthorPlan(def, seats, deliver) {
|
|
354
|
+
const phases = def.phases.map((p) => ({
|
|
355
|
+
id: p.id,
|
|
356
|
+
kind: p.kind,
|
|
357
|
+
role: p.role,
|
|
358
|
+
executor: p.executor?.type === 'tool' ? 'tool' : 'agent',
|
|
359
|
+
skillRef: p.skill_ref,
|
|
360
|
+
gate: gateLabel(p.gate),
|
|
361
|
+
executesCode: p.executes_code,
|
|
362
|
+
}));
|
|
363
|
+
if (deliver) {
|
|
364
|
+
phases.push({
|
|
365
|
+
id: 'deliver',
|
|
366
|
+
kind: 'build',
|
|
367
|
+
role: 'neutral',
|
|
368
|
+
executor: 'tool',
|
|
369
|
+
skillRef: null,
|
|
370
|
+
gate: 'auto',
|
|
371
|
+
executesCode: false,
|
|
372
|
+
engine: true,
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
return { workflow: def.id, phases, seats };
|
|
376
|
+
}
|
|
377
|
+
//# sourceMappingURL=author-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"author-workflow.js","sourceRoot":"","sources":["../../src/qe/author-workflow.ts"],"names":[],"mappings":"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"}
|
package/dist/qe/ledger.d.ts
CHANGED
|
@@ -6,15 +6,31 @@
|
|
|
6
6
|
* this daemon owns: a DomainStore rooted at `<repo>/.wicked-qe/` (legacy
|
|
7
7
|
* `<repo>/.wicked-testing/` — see qeLedgerRoot) holding `runs` and
|
|
8
8
|
* `verdicts`, plus the public evidence manifest at
|
|
9
|
-
* `<root>/evidence/<run-id>/manifest.json`.
|
|
10
|
-
* through the wicked-ledger package API (public entry, no deep imports) and
|
|
11
|
-
* never writes a domain record — the QE pipeline is the only writer.
|
|
9
|
+
* `<root>/evidence/<run-id>/manifest.json`.
|
|
12
10
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
11
|
+
* READ-ONLY means read-only (F-E2E-013). This module reads the ledger's
|
|
12
|
+
* CANONICAL JSON files directly and never opens a `DomainStore`: opening one
|
|
13
|
+
* is a write — `new DomainStore(root)` mkdirs the root, reaps `.tmp.*` files,
|
|
14
|
+
* creates `wicked-qe.db` (+ WAL/SHM) inside the checkout, runs migrations and
|
|
15
|
+
* a stale-run UPDATE sweep — and the index-healing `rebuildIndex()` this
|
|
16
|
+
* module used to call on top of that bulk-inserted every canonical row into
|
|
17
|
+
* the fresh index, which is where a legacy ledger's scenarios without
|
|
18
|
+
* `format_version` failed ("SQLite write failed … NOT NULL constraint"). A
|
|
19
|
+
* GET must leave the repository byte-identical. Canonical JSON is
|
|
20
|
+
* authoritative by the ledger's own schema contract (the SQLite index is a
|
|
21
|
+
* derived cache), so reading it directly loses nothing — and a record that
|
|
22
|
+
* cannot be parsed is surfaced as a read failure (`error`), never skipped
|
|
23
|
+
* into a cleaner answer.
|
|
24
|
+
*
|
|
25
|
+
* ATTRIBUTION (F-E2E-013): the gate answers about ONE crew run, so a verdict
|
|
26
|
+
* is served only when it can be tied to that run — see {@link ReadSubject}.
|
|
27
|
+
* "The newest PASS in the store" is not evidence about a run that recorded
|
|
28
|
+
* none (the regression: an onboarding run that failed at plan time was shown a
|
|
29
|
+
* two-month-old PASS from the repo's committed legacy ledger). Among the QE
|
|
30
|
+
* runs that ARE this run's, deny-dominates holds ACROSS them: each QE run's
|
|
31
|
+
* newest verdict is its current judgment, and one non-PASS among those denies
|
|
32
|
+
* (review of #539, F2 — a later PASS on scenario Y must not mask a FAIL on
|
|
33
|
+
* scenario X inside the same crew run).
|
|
18
34
|
*/
|
|
19
35
|
import type { EvidenceManifest, RunRecord, VerdictRecord } from 'wicked-ledger';
|
|
20
36
|
/**
|
|
@@ -28,6 +44,15 @@ import type { EvidenceManifest, RunRecord, VerdictRecord } from 'wicked-ledger';
|
|
|
28
44
|
*/
|
|
29
45
|
export declare const DEFAULT_QE_LEDGER_DIRNAME = ".wicked-qe";
|
|
30
46
|
export declare const LEGACY_QE_LEDGER_DIRNAME = ".wicked-testing";
|
|
47
|
+
/**
|
|
48
|
+
* The field a QE writer running INSIDE a governed run stamps on the ledger run
|
|
49
|
+
* (and/or verdict) it records: the crew run id the engine hands every worker as
|
|
50
|
+
* `WICKED_RUN_ID`. Canonical JSON preserves any field a writer supplies, so this
|
|
51
|
+
* needs no ledger schema change; a record carrying it is attributed to that run
|
|
52
|
+
* regardless of timing. (garden's QE runner does not stamp it yet — a wave-7
|
|
53
|
+
* follow-up; until then lifetime linkage below is the inferred fallback.)
|
|
54
|
+
*/
|
|
55
|
+
export declare const CREW_RUN_ID_FIELD = "crew_run_id";
|
|
31
56
|
/** The configured ledger dir name: `WICKED_QE_LEDGER_DIR` env override, else the default. */
|
|
32
57
|
export declare function qeLedgerDirName(): string;
|
|
33
58
|
/**
|
|
@@ -41,48 +66,123 @@ export declare function qeLedgerDirName(): string;
|
|
|
41
66
|
*/
|
|
42
67
|
export declare function qeLedgerRoot(repoRoot: string): string;
|
|
43
68
|
/**
|
|
44
|
-
* The
|
|
69
|
+
* The crew run a ledger read is FOR — what a verdict has to be tied to before
|
|
70
|
+
* it is served as that run's acceptance evidence.
|
|
71
|
+
*/
|
|
72
|
+
export interface RunLinkage {
|
|
73
|
+
/** The crew run id (what a QE writer inside the run sees as `WICKED_RUN_ID`). */
|
|
74
|
+
runId: string;
|
|
75
|
+
/**
|
|
76
|
+
* Epoch millis the crew run started — its `sessionStarted` capture time from
|
|
77
|
+
* the durable event log. `null` when the log records no start (an unknown
|
|
78
|
+
* window links nothing: evidence that cannot be placed inside the run is not
|
|
79
|
+
* the run's evidence).
|
|
80
|
+
*/
|
|
81
|
+
startedAt: number | null;
|
|
82
|
+
/**
|
|
83
|
+
* Epoch millis the run reached a terminal state — the FIRST terminal frame in
|
|
84
|
+
* its log (`sessionCompleted` / `sessionFailed` / `runCancelled`); `null`
|
|
85
|
+
* while it is live (window open).
|
|
86
|
+
*/
|
|
87
|
+
finishedAt: number | null;
|
|
88
|
+
/**
|
|
89
|
+
* Set when the run's event log could not be read at all (the read binding
|
|
90
|
+
* threw) — a different fact from "the log records no start", with a
|
|
91
|
+
* different remedy, so the denial names it (review of #539, F5).
|
|
92
|
+
*/
|
|
93
|
+
logUnreadable?: string;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* What a read is scoped to: an explicit QE run (`?qeRun=<id>` — the caller
|
|
97
|
+
* asserts the linkage), or the crew run whose evidence is wanted.
|
|
98
|
+
*/
|
|
99
|
+
export type ReadSubject = {
|
|
100
|
+
qeRunId: string;
|
|
101
|
+
} | {
|
|
102
|
+
run: RunLinkage;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* How the served verdict was tied to the crew run — or why none was. Always
|
|
106
|
+
* populated on a found ledger; the route serves it so the answer explains itself.
|
|
107
|
+
*/
|
|
108
|
+
export type QeAttribution =
|
|
109
|
+
/** The caller pinned the QE run (`?qeRun=`); its newest verdict is served. */
|
|
110
|
+
{
|
|
111
|
+
kind: 'pinned';
|
|
112
|
+
qeRunId: string;
|
|
113
|
+
}
|
|
114
|
+
/** The ledger run (or one of its verdicts) carries `crew_run_id` naming this crew run. */
|
|
115
|
+
| {
|
|
116
|
+
kind: 'stamped';
|
|
117
|
+
qeRunId: string;
|
|
118
|
+
}
|
|
119
|
+
/** INFERRED: the QE run started inside this crew run's recorded lifetime (not stamped by the writer). */
|
|
120
|
+
| {
|
|
121
|
+
kind: 'run-window';
|
|
122
|
+
qeRunId: string;
|
|
123
|
+
qeRunStartedAt: string;
|
|
124
|
+
}
|
|
125
|
+
/** Nothing in the ledger is this run's evidence; `reason` says what the ledger does hold. */
|
|
126
|
+
| {
|
|
127
|
+
kind: 'none';
|
|
128
|
+
reason: string;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* One line a human can read on `gate.reason`: HOW the served verdict was tied to
|
|
132
|
+
* the run, with the inferred kind labelled as such — an operator must be able to
|
|
133
|
+
* tell "the writer said so" from "it happened while the run was live".
|
|
134
|
+
*/
|
|
135
|
+
export declare function describeAttribution(a: QeAttribution): string;
|
|
136
|
+
/**
|
|
137
|
+
* The acceptance-relevant slice of a repo's ledger, scoped to one subject.
|
|
45
138
|
*
|
|
46
139
|
* `found: false` means the repo has no ledger at all (the dir is absent) —
|
|
47
140
|
* a distinct fact from "a ledger with no verdicts", and the gate treats both
|
|
48
141
|
* as a deny with different reasons. `error` carries a read-layer failure
|
|
49
|
-
* (
|
|
142
|
+
* (unreadable dir, a record that is not valid JSON); it is never set on an
|
|
143
|
+
* ordinary empty ledger.
|
|
50
144
|
*/
|
|
51
145
|
export interface QeAcceptanceState {
|
|
52
146
|
/** Absolute ledger root that was read (or probed). */
|
|
53
147
|
root: string;
|
|
54
148
|
/** Whether the ledger root exists on disk. */
|
|
55
149
|
found: boolean;
|
|
56
|
-
/** The QE run the verdict belongs to, when resolvable. */
|
|
150
|
+
/** The QE run the served verdict belongs to, when resolvable. */
|
|
57
151
|
run: RunRecord | null;
|
|
58
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* The governing verdict for the subject: among the attributed QE runs' newest
|
|
154
|
+
* verdicts, the newest non-PASS if there is one (deny-dominates), else the
|
|
155
|
+
* newest PASS.
|
|
156
|
+
*/
|
|
59
157
|
verdict: VerdictRecord | null;
|
|
60
158
|
/** The public evidence manifest for that run, when present and parseable. */
|
|
61
159
|
manifest: EvidenceManifest | null;
|
|
62
160
|
/** Absolute path the manifest was read from (null when absent). */
|
|
63
161
|
manifestPath: string | null;
|
|
64
|
-
/**
|
|
162
|
+
/** How `verdict` was tied to the subject, or why nothing was. */
|
|
163
|
+
attribution: QeAttribution;
|
|
164
|
+
/** How many live verdicts the ledger holds in total — the repo-level picture the scoped read was carved from. */
|
|
165
|
+
ledgerVerdicts: number;
|
|
166
|
+
/**
|
|
167
|
+
* How many QE runs are attributed to the subject (each contributes its newest
|
|
168
|
+
* verdict to the deny-dominates set `verdict` was resolved over). 1 for a pin.
|
|
169
|
+
*/
|
|
170
|
+
attributedVerdicts: number;
|
|
171
|
+
/** Read-layer failure detail (a record could not be read or parsed). */
|
|
65
172
|
error?: string;
|
|
66
173
|
}
|
|
67
174
|
/**
|
|
68
|
-
* Read the ledger's
|
|
175
|
+
* Read the ledger's acceptance state for a repo, scoped to `subject`.
|
|
69
176
|
*
|
|
70
|
-
* The
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* re-reviewed after its manifest was built, and the newer verdict row wins.
|
|
177
|
+
* The verdicts TABLE is the system of record — the manifest is the public
|
|
178
|
+
* artifact built from it at run finalization, returned here as display
|
|
179
|
+
* evidence, never as a gate input: a run can legitimately be re-reviewed
|
|
180
|
+
* after its manifest was built, and the newer verdict row wins.
|
|
75
181
|
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* behind. When the index answers "no verdicts" but canonical verdict files
|
|
79
|
-
* exist, the index is provably stale, so it is rebuilt from JSON once and
|
|
80
|
-
* re-read — otherwise a ledger full of evidence would read as "missing
|
|
81
|
-
* evidence ⇒ deny", a wrong answer in the honest direction but still wrong.
|
|
182
|
+
* Reads canonical JSON only (see the module header): nothing under the ledger
|
|
183
|
+
* root is created, modified or removed by this call.
|
|
82
184
|
*/
|
|
83
|
-
export declare function readAcceptanceState(repoRoot: string,
|
|
84
|
-
qeRunId?: string;
|
|
85
|
-
}): Promise<QeAcceptanceState>;
|
|
185
|
+
export declare function readAcceptanceState(repoRoot: string, subject: ReadSubject): Promise<QeAcceptanceState>;
|
|
86
186
|
/** The summary of a manifest the acceptance route serves (never the full artifact list). */
|
|
87
187
|
export interface QeManifestSummary {
|
|
88
188
|
manifestVersion: string;
|
package/dist/qe/ledger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/qe/ledger.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../../src/qe/ledger.ts"],"names":[],"mappings":"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"}
|