@alphazede/bearing-lite 0.1.11 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +25 -0
- package/README.md +46 -14
- package/hooks/assurance-budget.cjs +149 -0
- package/hooks/closeout.cjs +16 -0
- package/hooks/com.anthropic.claude-code/mapping.md +72 -0
- package/hooks/com.cursor/hooks.json +11 -1
- package/hooks/hooks.json +45 -1
- package/hooks/plan-package.cjs +177 -0
- package/hooks/planning-review.cjs +9 -14
- package/hooks/policy.cjs +45 -0
- package/hooks/reconcile.cjs +145 -0
- package/hooks/te-capability.cjs +137 -0
- package/hooks/te-host.cjs +644 -0
- package/hooks/transition-order.cjs +32 -2
- package/lineups.json +1 -0
- package/package.json +4 -2
- package/plugin.json +1 -1
- package/schemas/authority.schema.json +75 -0
- package/schemas/event.schema.json +59 -0
- package/schemas/implementation.schema.json +150 -0
- package/schemas/journey.schema.json +101 -0
- package/schemas/lineups.schema.json +145 -0
- package/schemas/seit.schema.json +108 -0
- package/skills/bearing-lite/SKILL.md +20 -21
- package/skills/bearing-lite/references/assurance-policy.md +66 -0
- package/skills/bearing-lite/references/lineups.md +107 -0
- package/skills/bearing-lite/references/peer-synthesis.md +7 -3
- package/skills/bearing-lite/references/role-routing.mmd +2 -2
- package/skills/bearing-lite/references/task-state.md +4 -4
- package/skills/bearing-lite/references/task-state.mmd +1 -1
- package/skills/bearing-lite/templates/task.md +20 -11
- package/skills/crewmate/SKILL.md +3 -0
- package/skills/explorer/SKILL.md +7 -6
- package/skills/gather-supplies/SKILL.md +7 -1
- package/skills/integration-engineer/SKILL.md +41 -0
- package/skills/light-implementer/SKILL.md +53 -0
- package/skills/map-the-route/SKILL.md +9 -7
- package/skills/map-the-route/references/artifact-grammar.md +67 -32
- package/skills/park-ranger/SKILL.md +14 -9
- package/skills/plan-integrator/SKILL.md +46 -0
- package/skills/requirements-engineer/SKILL.md +57 -0
- package/skills/scribe/SKILL.md +34 -0
- package/skills/set-bearings/SKILL.md +16 -7
- package/skills/set-bearings/templates/workspace.md +28 -0
- package/skills/surveyor/SKILL.md +15 -9
- package/skills/systems-modeler/SKILL.md +35 -0
- package/skills/test-engineer/SKILL.md +48 -0
- package/skills/validator/SKILL.md +20 -27
- package/skills/validator/references/grading-rubric.md +5 -4
- package/skills/bearing-lite/templates/default-role-lineup.md +0 -26
package/CONTRIBUTING.md
CHANGED
|
@@ -54,8 +54,33 @@ checkout):
|
|
|
54
54
|
node --test test/diagram-sync.test.mjs
|
|
55
55
|
node --test test/public-boundary.test.mjs
|
|
56
56
|
node --test test/skills-conformance.test.mjs
|
|
57
|
+
python3 test/schema-validation.py
|
|
57
58
|
```
|
|
58
59
|
|
|
60
|
+
Schema validation requires Python 3.12. `python3 test/schema-validation.py` is
|
|
61
|
+
the required developer and CI gate (`CMD-LITE-SCHEMA-VALIDATE`). It installs the
|
|
62
|
+
pinned hashes from `test/schema-validator-requirements.txt` into an isolated
|
|
63
|
+
temporary directory with `pip install --isolated --require-hashes --no-deps` and
|
|
64
|
+
runs Draft 2020-12 validation with no remote `$ref` retrieval. Do not install
|
|
65
|
+
those packages globally, with `--user`, or as production dependencies of this
|
|
66
|
+
package.
|
|
67
|
+
|
|
68
|
+
CI on `ubuntu-24.04` with Python 3.12 x64 performs the same isolated
|
|
69
|
+
`--require-hashes --no-deps` install into a job-local target directory, then
|
|
70
|
+
runs `python3 test/schema-validation.py`. To reuse a local isolated tree instead
|
|
71
|
+
of a temporary install:
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
python3.12 -m venv .venv-schema-validator
|
|
75
|
+
.venv-schema-validator/bin/python -m pip install \
|
|
76
|
+
--isolated --require-hashes --no-deps \
|
|
77
|
+
-r test/schema-validator-requirements.txt
|
|
78
|
+
BEARING_LITE_SCHEMA_ISOLATED_ROOT=.venv-schema-validator/lib/python3.12/site-packages \
|
|
79
|
+
python3 test/schema-validation.py
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Keep that virtualenv uncommitted.
|
|
83
|
+
|
|
59
84
|
Keep skills lean. Prefer references and assets only when progressive disclosure
|
|
60
85
|
needs them. Do not add dependencies or change the lockfile without explicit
|
|
61
86
|
maintainer approval. Do not add `mcp.json`, postinstall scripts, or global hook
|
package/README.md
CHANGED
|
@@ -30,9 +30,12 @@ Then give your agent a real task:
|
|
|
30
30
|
> responses. Require one independent review at the end.
|
|
31
31
|
|
|
32
32
|
Bearing Lite fills missing planning stages, then Map the Route creates the
|
|
33
|
-
complete five-artifact package
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
complete five-artifact package (`<journey-topic>-technical-plan.md`,
|
|
34
|
+
`design.md`, `seit.json`, `implementation.json`, and two-state `review.html`)
|
|
35
|
+
with proposed route, lineup, role states, reasoning, and at-end cadence. One
|
|
36
|
+
integrated owner review approves or changes that package before bounded
|
|
37
|
+
sessions dispatch, with visible Markdown task state over those JSON
|
|
38
|
+
authorities.
|
|
36
39
|
|
|
37
40
|
If Bearing Lite helps keep a long agent task scoped and reviewable,
|
|
38
41
|
[star the repository](https://github.com/alphazede/bearing-lite). It helps other
|
|
@@ -97,16 +100,25 @@ register hooks. That path remains first-class. See
|
|
|
97
100
|
1. **Fill only missing planning stages:** Repository Fit → Set Bearings → Gather
|
|
98
101
|
Supplies.
|
|
99
102
|
2. **Invoke Map the Route** after material intent is settled. It creates
|
|
100
|
-
|
|
103
|
+
technical-plan, `design.md`, `seit.json`, `implementation.json`, and
|
|
104
|
+
two-state `review.html` together.
|
|
101
105
|
3. **Review once:** approve or change the proposed route, user-owned
|
|
102
106
|
primary/fallback lineup, role states, reasoning, at-end cadence, and plan.
|
|
103
107
|
4. **Dispatch bounded sessions** with compact receipts. Crewmate and Explorer may
|
|
104
108
|
continue in-wave; assurance always starts fresh at the end.
|
|
105
|
-
5. **Record state visibly
|
|
109
|
+
5. **Record state visibly.** The project's human-readable Markdown plan is the
|
|
110
|
+
only task-state record: task blocks, task states, and their transitions. The
|
|
111
|
+
Journey, execution, V&V, and authority records are machine-readable JSON
|
|
112
|
+
validated against `schemas/`: `journey.json` (Journey identity, checkout
|
|
113
|
+
lease, decisions, planning receipts, lineup selection), `seit.json` (V&V
|
|
114
|
+
proof rows), `implementation.json` (nested execution authority, waves,
|
|
115
|
+
slices, dispatch), and `authority.json` (authority envelope). `review.html`
|
|
116
|
+
and diagrams present state; like diagrams, they never authorize a
|
|
117
|
+
transition, create state, or grant authority.
|
|
106
118
|
|
|
107
119
|
Bearing Lite never selects models, providers, credentials, or launchers. The
|
|
108
120
|
owner provides each role's primary/fallback agent or harness, model, and
|
|
109
|
-
reasoning level in `~/.agents/bearing-lite/
|
|
121
|
+
reasoning level in `~/.agents/bearing-lite/lineups.json`, then confirms
|
|
110
122
|
the applicable Journey snapshot before implementation.
|
|
111
123
|
|
|
112
124
|
## Routes and scaling
|
|
@@ -133,8 +145,8 @@ invokes only missing planning stages, has Map the Route generate all five
|
|
|
133
145
|
artifacts with proposed lineup and `review_cadence: at-end`, then presents one
|
|
134
146
|
integrated owner review before dispatching an Explorer Journey or Expedition. Explorer
|
|
135
147
|
coordinates proven-independent in-wave lanes without a nested coordinator.
|
|
136
|
-
|
|
137
|
-
end on the final integrated candidate. Diagrams
|
|
148
|
+
Assurance Test Engineer, Park Ranger, and Surveyor appear only when declared
|
|
149
|
+
and only at the end on the final integrated candidate. Diagrams
|
|
138
150
|
explain orientation; they never authorize a transition.
|
|
139
151
|
|
|
140
152
|
## Roles and authority
|
|
@@ -144,14 +156,27 @@ explain orientation; they never authorize a transition.
|
|
|
144
156
|
| **Router** | Stateful planning controller | no | User-facing; planning-state writer; Expedition sequencing |
|
|
145
157
|
| **Navigator** | Compatibility diagnostic | no | Not a normal role; existing plans reroute to Router |
|
|
146
158
|
| **Explorer** | One-wave controller | no | Dispatches Crewmates; owns proven-independent lanes |
|
|
147
|
-
| **Crewmate** | Bounded implementer | yes |
|
|
148
|
-
| **
|
|
149
|
-
| **
|
|
150
|
-
| **
|
|
159
|
+
| **Crewmate** | Bounded implementer | yes | Split test-writing versus product; neither self-certifies |
|
|
160
|
+
| **Light Implementer** | Mechanical implementer | yes | `work_class: light` slices only; verified by the packet's command; no repair loop |
|
|
161
|
+
| **Scribe** | Event side lane | no | Transcribes; cannot activate authority |
|
|
162
|
+
| **Plan Integrator** | Artifact reconciliation | no | Generates `implementation.json` and `review.html` |
|
|
163
|
+
| **Systems Modeler** | Engineering views | no | After requirements; before design finalization |
|
|
164
|
+
| **Integration Engineer** | Progressive assembly | no | Dual planning and execution sessions |
|
|
165
|
+
| **Test Engineer** | Planning and Assurance V&V | no | Retires Validator; Validator is not an active role |
|
|
166
|
+
| **Park Ranger** | Defect review | no | Consumes Assurance Test Engineer; no routine TE |
|
|
167
|
+
| **Surveyor** | User-facing acceptance | no | Read-only RE, SysML Modeling, and TE |
|
|
151
168
|
| **Owner Authority** | Human decision | n/a | Never an agent role |
|
|
152
169
|
|
|
153
|
-
**Independent review:** a candidate author never provides their own
|
|
154
|
-
Park Ranger, or Surveyor verdict.
|
|
170
|
+
**Independent review:** a candidate author never provides their own Assurance
|
|
171
|
+
Test Engineer, Park Ranger, or Surveyor verdict.
|
|
172
|
+
|
|
173
|
+
Public Bearing Lite remains usable without AlphaZede-specific skills
|
|
174
|
+
(`requirements-engineering`, `sysml-modeling`, `test-engineering`,
|
|
175
|
+
`integration-engineering`). Specialized capabilities activate when selected
|
|
176
|
+
or required. Unavailability of a selected-or-required capability is a typed capability gap,
|
|
177
|
+
not success and not invented behavior. Selected-only missing and required-only
|
|
178
|
+
missing are each typed gaps. Only unselected and unrequired absence remains
|
|
179
|
+
inactive / not a global failure.
|
|
155
180
|
|
|
156
181
|
Failure escalates to the nearest role whose scope can see it:
|
|
157
182
|
|
|
@@ -177,6 +202,11 @@ Ordinary execution corrections remain bounded. The assurance gate allows one
|
|
|
177
202
|
review-directed repair, followed by deterministic coordinator verification and
|
|
178
203
|
no second review. Diagrams never create state or authorize transitions.
|
|
179
204
|
|
|
205
|
+
`hooks/reconcile.cjs` deterministically applies evidence events to Journey state.
|
|
206
|
+
It is a short-lived Router-run invocation, not a daemon or host event adapter;
|
|
207
|
+
hosts emit no events today, so invocation remains a procedural limitation.
|
|
208
|
+
It observes merge and issue closure but never grants acceptance, merges, or closes issues.
|
|
209
|
+
|
|
180
210
|
## Implementation process (explanatory)
|
|
181
211
|
|
|
182
212
|
Default packet completion is author self-check plus coordinator confirmation.
|
|
@@ -204,6 +234,8 @@ flowchart LR
|
|
|
204
234
|
| `plugin.json` | Agent Plugins v1.0.0 manifest |
|
|
205
235
|
| `skills/` | Router, planning stages, and role skills |
|
|
206
236
|
| `hooks/` | Four portable class adapters plus the verified Claude Code / Codex mapping |
|
|
237
|
+
| `lineups.json` | Empty shipped catalog; no packaged providers, models, or defaults |
|
|
238
|
+
| `schemas/` | JSON Schema for `seit.json`, `implementation.json`, `authority.json`, and `journey.json` |
|
|
207
239
|
| `README.md` and governance docs | Public product and conduct surfaces |
|
|
208
240
|
|
|
209
241
|
There is no `mcp.json`, `bin` entrypoint, postinstall, or runtime dependency on
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Per-declared-phase-or-wave assurance budget (ROUTER-EMV-CADENCE-IMPLEMENTATION-001).
|
|
5
|
+
* Exact runtime mirror of `skills/bearing-lite/references/assurance-policy.md`.
|
|
6
|
+
* A pure evaluator behind the existing `transition` class, like planning-review.cjs:
|
|
7
|
+
* it declares no HOOK_CLASS and registers no host event.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require("node:fs");
|
|
11
|
+
|
|
12
|
+
const { ASSURANCE_BUDGET_POLICY: POLICY } = require("./policy.cjs");
|
|
13
|
+
|
|
14
|
+
/** The sentinel unit when the frozen declaration names neither waves nor phases. */
|
|
15
|
+
const DIRECT = "direct";
|
|
16
|
+
const PENDING_RECEIPTS = new Set(["WAITING_ON", "UNAVAILABLE"]);
|
|
17
|
+
|
|
18
|
+
const isCount = (value) => Number.isInteger(value) && value >= 0;
|
|
19
|
+
|
|
20
|
+
const isPlainObject = (value) =>
|
|
21
|
+
value !== null && typeof value === "object" && !Array.isArray(value);
|
|
22
|
+
|
|
23
|
+
function readJson(file) {
|
|
24
|
+
if (typeof file !== "string" || !file) return null;
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
27
|
+
return isPlainObject(parsed) ? parsed : null;
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Declared unit ids from the frozen declaration, in declaration order. */
|
|
34
|
+
function declaredUnits(declaration) {
|
|
35
|
+
const waves = Array.isArray(declaration.waves) ? declaration.waves : [];
|
|
36
|
+
const waveIds = waves.map((wave) => wave && wave.id).filter((id) => typeof id === "string" && id);
|
|
37
|
+
if (waveIds.length) return waveIds;
|
|
38
|
+
const phases = Array.isArray(declaration.phases) ? declaration.phases : [];
|
|
39
|
+
const phaseIds = phases
|
|
40
|
+
.map((phase) => phase && phase.phaseId)
|
|
41
|
+
.filter((id) => typeof id === "string" && id);
|
|
42
|
+
if (phaseIds.length) return phaseIds;
|
|
43
|
+
return [DIRECT];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const verdict = (outcome, reason) => ({ outcome, reason });
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {unknown} input assurance request
|
|
50
|
+
* @returns {{ outcome: string, reason: string }}
|
|
51
|
+
*/
|
|
52
|
+
function evaluateAssuranceBudget(input) {
|
|
53
|
+
try {
|
|
54
|
+
if (!isPlainObject(input)) {
|
|
55
|
+
return verdict("NEEDS_MORE_EVIDENCE", "assurance_request_missing");
|
|
56
|
+
}
|
|
57
|
+
if (
|
|
58
|
+
POLICY.automatic_per_slice_review === "prohibited" &&
|
|
59
|
+
(input.request_scope === "slice" || input.unit_kind === "slice")
|
|
60
|
+
) {
|
|
61
|
+
return verdict("OWNER_AMENDMENT_REQUIRED", "automatic_per_slice_review_prohibited");
|
|
62
|
+
}
|
|
63
|
+
if (
|
|
64
|
+
POLICY.automatic_rereview_of_same_unit === "prohibited" &&
|
|
65
|
+
(input.automatic_rereview_requested === true || input.review_after_repair === true)
|
|
66
|
+
) {
|
|
67
|
+
return verdict("OWNER_AMENDMENT_REQUIRED", "automatic_rereview_prohibited");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const declaration = readJson(input.declaration_path);
|
|
71
|
+
if (!declaration) {
|
|
72
|
+
return verdict("NEEDS_MORE_EVIDENCE", "frozen_declaration_unreadable");
|
|
73
|
+
}
|
|
74
|
+
const record = readJson(input.task_record_path);
|
|
75
|
+
if (!record) {
|
|
76
|
+
return verdict("NEEDS_MORE_EVIDENCE", "task_record_unreadable");
|
|
77
|
+
}
|
|
78
|
+
// The budget key is `journey + unit_kind + unit_id`; a record from another
|
|
79
|
+
// Journey never answers for this one.
|
|
80
|
+
if (
|
|
81
|
+
typeof record.journey === "string" &&
|
|
82
|
+
typeof input.journey === "string" &&
|
|
83
|
+
record.journey !== input.journey
|
|
84
|
+
) {
|
|
85
|
+
return verdict("NEEDS_MORE_EVIDENCE", "task_record_journey_mismatch");
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const declared = declaredUnits(declaration);
|
|
89
|
+
const requested =
|
|
90
|
+
typeof input.assurance_unit === "string" && input.assurance_unit
|
|
91
|
+
? input.assurance_unit
|
|
92
|
+
: declared.length === 1 && declared[0] === DIRECT
|
|
93
|
+
? DIRECT
|
|
94
|
+
: "";
|
|
95
|
+
if (!requested || !declared.includes(requested)) {
|
|
96
|
+
return verdict("OWNER_AMENDMENT_REQUIRED", "undeclared_review_unit");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const receipts = Array.isArray(input.receipts) ? input.receipts : [];
|
|
100
|
+
if (receipts.some((receipt) => PENDING_RECEIPTS.has(receipt && receipt.verdict))) {
|
|
101
|
+
return verdict("NEEDS_MORE_EVIDENCE", "assurance_transport_pending");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const units = Array.isArray(record.units) ? record.units : [];
|
|
105
|
+
const spent = units.find((unit) => {
|
|
106
|
+
if (!isPlainObject(unit)) return false;
|
|
107
|
+
const unitId = unit.unit_id || unit.assurance_unit;
|
|
108
|
+
const id = typeof unitId === "string" && unitId ? unitId : DIRECT;
|
|
109
|
+
if (id !== requested) return false;
|
|
110
|
+
if (typeof unit.journey === "string" && unit.journey !== input.journey) return false;
|
|
111
|
+
if (
|
|
112
|
+
typeof unit.unit_kind === "string" &&
|
|
113
|
+
typeof input.unit_kind === "string" &&
|
|
114
|
+
unit.unit_kind !== input.unit_kind
|
|
115
|
+
) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
const counter = (field) => {
|
|
121
|
+
const value = spent && spent[field];
|
|
122
|
+
return value === undefined || value === null ? 0 : value;
|
|
123
|
+
};
|
|
124
|
+
const rounds = counter("assurance_rounds");
|
|
125
|
+
const repairs = counter("assurance_repairs");
|
|
126
|
+
// A corrupt counter is not a spent-zero budget.
|
|
127
|
+
if (!isCount(rounds) || !isCount(repairs)) {
|
|
128
|
+
return verdict("NEEDS_MORE_EVIDENCE", "invalid_assurance_counter");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (repairs > POLICY.aggregated_repairs_max) {
|
|
132
|
+
return verdict("HALT", "assurance_repair_limit");
|
|
133
|
+
}
|
|
134
|
+
if (
|
|
135
|
+
repairs === POLICY.aggregated_repairs_max &&
|
|
136
|
+
(spent && spent.deterministic_gate) !== POLICY.post_repair_gate.split("_")[1]
|
|
137
|
+
) {
|
|
138
|
+
return verdict("HALT", "deterministic_post_repair_gate_required");
|
|
139
|
+
}
|
|
140
|
+
if (rounds >= POLICY.review_rounds) {
|
|
141
|
+
return verdict("HALT", "assurance_round_limit");
|
|
142
|
+
}
|
|
143
|
+
return verdict("PASS", "assurance_round_available");
|
|
144
|
+
} catch {
|
|
145
|
+
return verdict("NEEDS_MORE_EVIDENCE", "assurance_budget_unavailable");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = { POLICY, evaluateAssuranceBudget };
|
package/hooks/closeout.cjs
CHANGED
|
@@ -39,6 +39,19 @@ const VERDICT_VALUES = new Set([
|
|
|
39
39
|
"WAITING_ON",
|
|
40
40
|
]);
|
|
41
41
|
|
|
42
|
+
/** Closed verdicts that refuse protected completion (#55). */
|
|
43
|
+
const NEGATIVE_VERDICTS = new Set([
|
|
44
|
+
"BLOCK",
|
|
45
|
+
"FAIL",
|
|
46
|
+
"GAPS",
|
|
47
|
+
"NEEDS_MORE_EVIDENCE",
|
|
48
|
+
"OWNER_DECISION_REQUIRED",
|
|
49
|
+
"PARTIAL",
|
|
50
|
+
"REPAIR_REQUIRED",
|
|
51
|
+
"REROUTED",
|
|
52
|
+
"WAITING_ON",
|
|
53
|
+
]);
|
|
54
|
+
|
|
42
55
|
const RECOVERY_UNAVAILABLE =
|
|
43
56
|
"Report UNAVAILABLE, complete the handoff checklist manually, and do not request protected completion until required fields and assurance are present";
|
|
44
57
|
const RECOVERY_HANDOFF =
|
|
@@ -169,6 +182,8 @@ function evaluate(input) {
|
|
|
169
182
|
const blockers = [];
|
|
170
183
|
const handoffProblems = [...missing, ...invalid];
|
|
171
184
|
if (handoffProblems.length > 0) blockers.push("handoff:" + handoffProblems.join(","));
|
|
185
|
+
const verdict = String((isPlainObject(input.handoff) ? input.handoff : input).verdict ?? "").trim();
|
|
186
|
+
if (NEGATIVE_VERDICTS.has(verdict)) blockers.push("verdict:" + verdict);
|
|
172
187
|
if (missingAssurance.length > 0) {
|
|
173
188
|
blockers.push("assurance:" + missingAssurance.join(","));
|
|
174
189
|
}
|
|
@@ -283,6 +298,7 @@ module.exports = {
|
|
|
283
298
|
ENFORCEMENT,
|
|
284
299
|
HANDOFF_FIELDS,
|
|
285
300
|
VERDICT_VALUES,
|
|
301
|
+
NEGATIVE_VERDICTS,
|
|
286
302
|
evaluate,
|
|
287
303
|
};
|
|
288
304
|
|
|
@@ -31,8 +31,15 @@ adapters into global hook configuration.
|
|
|
31
31
|
|---|---|---|
|
|
32
32
|
| `SessionStart`, `sessionStart`, `session_start` | activation | yes, advisory |
|
|
33
33
|
| `Stop`, `stop` | closeout | yes, advisory only |
|
|
34
|
+
| `PreToolUse`, `preToolUse`, `beforeShellExecution`, `apply_patch` | te_test_write | only where the host has a native write-time deny |
|
|
35
|
+
| `Stop`, `stop`, `SubagentStop`, `subagentStop` | te_completion | only where the host has a native completion or child-stop deny |
|
|
34
36
|
| any other host event | none | unmapped; fail open as `UNAVAILABLE` |
|
|
35
37
|
|
|
38
|
+
`hooks/com.anthropic.claude-code/host.cjs` owns activation and closeout and
|
|
39
|
+
maps no Test Engineering class. `hooks/te-host.cjs` owns te_test_write and
|
|
40
|
+
te_completion and maps neither of the original four. The two adapters are
|
|
41
|
+
registered separately, and a `Stop` event reaches both.
|
|
42
|
+
|
|
36
43
|
The shared planning-review evaluator is used by transition and closeout when a
|
|
37
44
|
client supplies a structured `planning_review` record. Current session-start /
|
|
38
45
|
stop mappings cannot derive that nested record safely, so Claude Code, Codex,
|
|
@@ -41,9 +48,74 @@ AGY, Pi, and DeepCode remain skills-only. Do not claim full planning-review
|
|
|
41
48
|
enforcement for any of these hosts until a native event supplies the complete
|
|
42
49
|
record.
|
|
43
50
|
|
|
51
|
+
The per-declared-phase-or-wave assurance record
|
|
52
|
+
(`skills/bearing-lite/references/assurance-policy.md`) is evaluated by the same
|
|
53
|
+
`transition` class through the `assurance_transition` action_kind. No mapped
|
|
54
|
+
host exposes a hook event that carries the frozen declaration and the visible
|
|
55
|
+
task record, so the assurance budget is procedural on every mapped host:
|
|
56
|
+
Claude Code, Codex, Grok Build, Cursor, and Kimi Code stay partial, and AGY,
|
|
57
|
+
Pi, and DeepCode stay skills-only. No host may advertise an enforcement of the
|
|
58
|
+
assurance budget it cannot perform.
|
|
59
|
+
|
|
44
60
|
The adapter accepts snake_case and camelCase (`hook_event_name` /
|
|
45
61
|
`hookEventName`, `cwd` / `workspaceRoot`).
|
|
46
62
|
|
|
63
|
+
## Test Engineering classes
|
|
64
|
+
|
|
65
|
+
`te_test_write` and `te_completion` are **additional** classes, shipped by
|
|
66
|
+
`hooks/te-capability.cjs` and `hooks/te-host.cjs`. They do not rename or
|
|
67
|
+
replace activation, closeout, transition-order, or protected-action, and they
|
|
68
|
+
do not reuse those classes' outcome tokens. Their verdicts are `ALLOW`,
|
|
69
|
+
`DENY_ROUTE_TO_TE`, `DENY_RECEIPT_REQUIRED`, and `UNAVAILABLE`.
|
|
70
|
+
|
|
71
|
+
Bearing Lite ships no Test Engineering evaluator and no Test Engineering
|
|
72
|
+
method content. The adapter resolves the `test-engineering` capability, loads
|
|
73
|
+
the evaluator at `skills/test-engineering/hooks/te-evaluator.cjs` when that
|
|
74
|
+
capability is present in the workspace, builds the request from the real Git
|
|
75
|
+
checkout and the coordinator-authored plan, and returns the evaluator verdict
|
|
76
|
+
unchanged.
|
|
77
|
+
|
|
78
|
+
| Capability state | Class result |
|
|
79
|
+
|---|---|
|
|
80
|
+
| neither selected nor required | `UNAVAILABLE`; the class fails open and this is not a failure |
|
|
81
|
+
| selected or required, evaluator absent | `UNAVAILABLE` with `code: typed_capability_gap`; a typed gap, never silent success |
|
|
82
|
+
| selected or required, evaluator loaded | the evaluator verdict, verbatim |
|
|
83
|
+
|
|
84
|
+
Trusted assignment comes from the visible coordinator-authored plan, never
|
|
85
|
+
from the tool payload or the transcript. Candidate state comes from the
|
|
86
|
+
installed Git executable: the committed `diff_base..HEAD` change plus the
|
|
87
|
+
working tree, scoped to the trusted write set. An empty trusted scope covers
|
|
88
|
+
nothing, so unrelated shared dirt never enters the candidate. Derived runtime
|
|
89
|
+
state under the Bearing runtime directory is never a candidate change.
|
|
90
|
+
|
|
91
|
+
An artifact on disk is never a local pass token; only the evaluator reads it.
|
|
92
|
+
An `ALLOW` completion verdict is not user acceptance and grants no planning or
|
|
93
|
+
publication authority.
|
|
94
|
+
|
|
95
|
+
### Host honesty
|
|
96
|
+
|
|
97
|
+
`native` means the host exposes a verified hard deny for that channel.
|
|
98
|
+
Everything else is `UNAVAILABLE`: the class is procedural on that host and
|
|
99
|
+
this adapter must not advertise enforcement it cannot perform.
|
|
100
|
+
|
|
101
|
+
| Host | te_test_write channel | te_completion at parent stop | te_completion at child stop |
|
|
102
|
+
|---|---|---|---|
|
|
103
|
+
| Claude Code | native `PreToolUse` deny | native `Stop` deny | native `SubagentStop` deny |
|
|
104
|
+
| Codex | native `PreToolUse` deny | native `Stop` deny | native `SubagentStop` deny |
|
|
105
|
+
| Grok Build | native `PreToolUse` deny | native `Stop` deny | native `SubagentStop` deny |
|
|
106
|
+
| Cursor | native `preToolUse` and `beforeShellExecution` deny | te_completion UNAVAILABLE | child te_completion UNAVAILABLE |
|
|
107
|
+
| Kimi Code | te_test_write UNAVAILABLE | te_completion UNAVAILABLE | child te_completion UNAVAILABLE |
|
|
108
|
+
| Pi | te_test_write UNAVAILABLE | te_completion UNAVAILABLE | child te_completion UNAVAILABLE |
|
|
109
|
+
| AGY | te_test_write UNAVAILABLE | te_completion UNAVAILABLE | child te_completion UNAVAILABLE |
|
|
110
|
+
| DeepCode | te_test_write UNAVAILABLE | te_completion UNAVAILABLE | child te_completion UNAVAILABLE |
|
|
111
|
+
|
|
112
|
+
Cursor's `stop` guidance message is advisory text, not a hard completion
|
|
113
|
+
block, and Cursor exposes no distinct hard child-stop deny; neither is
|
|
114
|
+
registered as one. Kimi Code, Pi, AGY, and DeepCode carry no verified native
|
|
115
|
+
Test Engineering blocking at all, so `hooks/te-host.cjs` returns `UNAVAILABLE`
|
|
116
|
+
for every class on those hosts rather than claiming an enforcement it cannot
|
|
117
|
+
deliver.
|
|
118
|
+
|
|
47
119
|
## Derived fields
|
|
48
120
|
|
|
49
121
|
The host event supplies session metadata. The adapter reads visible Markdown
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Bearing Lite Cursor mapping. Partial coverage: sessionStart activation, stop closeout. Transition-order and protected-action remain procedural.",
|
|
2
|
+
"description": "Bearing Lite Cursor mapping. Partial coverage: sessionStart activation, stop closeout, and write-time te_test_write on preToolUse and beforeShellExecution. Cursor exposes no hard completion or child-stop deny, so te_completion stays procedural. Transition-order and protected-action remain procedural.",
|
|
3
3
|
"hooks": {
|
|
4
4
|
"sessionStart": [
|
|
5
5
|
{
|
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
{
|
|
11
11
|
"command": "node ./hooks/com.anthropic.claude-code/host.cjs"
|
|
12
12
|
}
|
|
13
|
+
],
|
|
14
|
+
"preToolUse": [
|
|
15
|
+
{
|
|
16
|
+
"command": "node ./hooks/te-host.cjs --host=cursor"
|
|
17
|
+
}
|
|
18
|
+
],
|
|
19
|
+
"beforeShellExecution": [
|
|
20
|
+
{
|
|
21
|
+
"command": "node ./hooks/te-host.cjs --host=cursor"
|
|
22
|
+
}
|
|
13
23
|
]
|
|
14
24
|
}
|
|
15
25
|
}
|
package/hooks/hooks.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Bearing Lite verified Claude Code and Codex mapping. Partial coverage: activation on SessionStart, closeout on Stop. Transition-order and protected-action remain procedural.",
|
|
2
|
+
"description": "Bearing Lite verified Claude Code and Codex mapping. Partial coverage: activation on SessionStart, closeout on Stop, and the Test Engineering classes te_test_write on PreToolUse and te_completion on Stop and SubagentStop. Transition-order and protected-action remain procedural.",
|
|
3
3
|
"hooks": {
|
|
4
4
|
"SessionStart": [
|
|
5
5
|
{
|
|
@@ -16,6 +16,22 @@
|
|
|
16
16
|
]
|
|
17
17
|
}
|
|
18
18
|
],
|
|
19
|
+
"PreToolUse": [
|
|
20
|
+
{
|
|
21
|
+
"matcher": "Write|Edit|MultiEdit|NotebookEdit|apply_patch|Bash",
|
|
22
|
+
"hooks": [
|
|
23
|
+
{
|
|
24
|
+
"type": "command",
|
|
25
|
+
"command": "node",
|
|
26
|
+
"args": [
|
|
27
|
+
"${CLAUDE_PLUGIN_ROOT}/hooks/te-host.cjs"
|
|
28
|
+
],
|
|
29
|
+
"timeout": 15,
|
|
30
|
+
"statusMessage": "Bearing Lite test-engineering write check"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
],
|
|
19
35
|
"Stop": [
|
|
20
36
|
{
|
|
21
37
|
"hooks": [
|
|
@@ -29,6 +45,34 @@
|
|
|
29
45
|
"statusMessage": "Bearing Lite closeout"
|
|
30
46
|
}
|
|
31
47
|
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"hooks": [
|
|
51
|
+
{
|
|
52
|
+
"type": "command",
|
|
53
|
+
"command": "node",
|
|
54
|
+
"args": [
|
|
55
|
+
"${CLAUDE_PLUGIN_ROOT}/hooks/te-host.cjs"
|
|
56
|
+
],
|
|
57
|
+
"timeout": 15,
|
|
58
|
+
"statusMessage": "Bearing Lite test-engineering completion check"
|
|
59
|
+
}
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
],
|
|
63
|
+
"SubagentStop": [
|
|
64
|
+
{
|
|
65
|
+
"hooks": [
|
|
66
|
+
{
|
|
67
|
+
"type": "command",
|
|
68
|
+
"command": "node",
|
|
69
|
+
"args": [
|
|
70
|
+
"${CLAUDE_PLUGIN_ROOT}/hooks/te-host.cjs"
|
|
71
|
+
],
|
|
72
|
+
"timeout": 15,
|
|
73
|
+
"statusMessage": "Bearing Lite test-engineering child completion check"
|
|
74
|
+
}
|
|
75
|
+
]
|
|
32
76
|
}
|
|
33
77
|
]
|
|
34
78
|
}
|