@hivehub/rulebook 5.8.1 → 5.8.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hivehub/rulebook",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.2",
|
|
4
4
|
"description": "Tool-agnostic AI development framework. Standardize projects across Claude Code, Cursor, Gemini, Codex, Windsurf, Copilot with automated templates, quality gates, persistent memory, and framework detection for 28 languages, 17 frameworks, 13 MCP modules, and 20 services",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -2,7 +2,7 @@ export const meta = {
|
|
|
2
2
|
name: 'review-fanout',
|
|
3
3
|
description:
|
|
4
4
|
'Adversarial multi-dimension review of the current git diff (correctness, security, performance, tests). Each finding is independently verified before it survives, then synthesized into a prioritized report.',
|
|
5
|
-
phases: [{ title: 'Review' }, { title: 'Verify' }, { title: 'Synthesize', model: '
|
|
5
|
+
phases: [{ title: 'Review' }, { title: 'Verify' }, { title: 'Synthesize', model: 'sonnet' }],
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
const FINDINGS_SCHEMA = {
|
|
@@ -119,7 +119,7 @@ phase('Synthesize')
|
|
|
119
119
|
const report = await agent(
|
|
120
120
|
`Synthesize a prioritized code-review report from these confirmed findings (already verified as real). Group by severity, give each a one-line fix recommendation, and lead with blockers.
|
|
121
121
|
${JSON.stringify(confirmed, null, 2)}`,
|
|
122
|
-
{ label: 'synthesize', phase: 'Synthesize', model: '
|
|
122
|
+
{ label: 'synthesize', phase: 'Synthesize', model: 'sonnet' }
|
|
123
123
|
)
|
|
124
124
|
|
|
125
125
|
return { confirmedCount: confirmed.length, confirmed, blocking, report }
|
|
@@ -8,25 +8,31 @@ export const meta = {
|
|
|
8
8
|
{ title: 'Review', detail: 'independent full SDD+TDD review', model: 'opus' },
|
|
9
9
|
{ title: 'Document', detail: 'docs-writer updates README/CHANGELOG', model: 'haiku' },
|
|
10
10
|
{ title: 'Commit', detail: 'commit the approved item (conventional, hooks must pass)', model: 'sonnet' },
|
|
11
|
-
{ title: 'Fanout', detail: 'review-fanout adversarial review of the task changeset', model: 'sonnet' },
|
|
11
|
+
{ title: 'Fanout', detail: 'OPT-IN ({ fanout: true }) review-fanout adversarial review of the task changeset', model: 'sonnet' },
|
|
12
12
|
{ title: 'Gate', detail: 'release-gate go/no-go once the backlog is drained', model: 'sonnet' },
|
|
13
13
|
],
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// ---- Tunables (override via args) ------------------------------------------
|
|
17
|
-
// args: { once
|
|
17
|
+
// args: { once?, maxItems?, minBudget?, fanout?, fanoutRounds? }
|
|
18
18
|
// once — process a single item then stop (legacy one-shot behavior)
|
|
19
19
|
// maxItems — hard cap on items processed in one run (default 25 safety stop)
|
|
20
20
|
// minBudget — stop before the next item if remaining tokens fall below this
|
|
21
|
-
//
|
|
21
|
+
// fanout — run the per-task review-fanout adversarial gate. DEFAULT false
|
|
22
|
+
// (it is the most token-expensive phase). Pass { fanout: true } to
|
|
23
|
+
// enable. The per-item SDD+TDD opus review + the commit hooks still
|
|
24
|
+
// run regardless; fanout is the extra multi-dimension pass.
|
|
25
|
+
// fanoutRounds — max review-fanout remediation rounds per completed task (default 1)
|
|
22
26
|
const opts = args && typeof args === 'object' ? args : {}
|
|
23
27
|
const ONCE = opts.once === true
|
|
24
28
|
const MAX_ITEMS = typeof opts.maxItems === 'number' ? opts.maxItems : 25
|
|
25
29
|
const MIN_BUDGET = typeof opts.minBudget === 'number' ? opts.minBudget : 60_000
|
|
26
30
|
const MAX_REVIEW_ROUNDS = 3
|
|
31
|
+
// Fanout is OFF by default — opt in with { fanout: true }.
|
|
32
|
+
const FANOUT_ENABLED = opts.fanout === true
|
|
27
33
|
// Per-completed-task adversarial gate. Counted SEPARATELY from MAX_REVIEW_ROUNDS so a
|
|
28
34
|
// fanout finding never competes with the per-item SDD/TDD round budget.
|
|
29
|
-
const MAX_FANOUT_ROUNDS = typeof opts.fanoutRounds === 'number' ? opts.fanoutRounds :
|
|
35
|
+
const MAX_FANOUT_ROUNDS = typeof opts.fanoutRounds === 'number' ? opts.fanoutRounds : 1
|
|
30
36
|
|
|
31
37
|
// ---- Structured-output schemas --------------------------------------------
|
|
32
38
|
|
|
@@ -288,7 +294,13 @@ let currentTaskBaseRef = null
|
|
|
288
294
|
let halted = false
|
|
289
295
|
|
|
290
296
|
// Run the per-task review-fanout gate once, scoped to the task's committed changeset (baseRef).
|
|
297
|
+
// No-op (auto-pass) when fanout is disabled — the per-item SDD+TDD review + commit hooks
|
|
298
|
+
// already gated every item; fanout is the opt-in extra adversarial pass.
|
|
291
299
|
async function gateCompletedTask(taskId, specPaths, baseRef) {
|
|
300
|
+
if (!FANOUT_ENABLED) {
|
|
301
|
+
taskGates.push({ taskId, passed: true, rounds: 0, blockingCount: 0, baseRef, skipped: true })
|
|
302
|
+
return { passed: true, rounds: 0, blocking: [] }
|
|
303
|
+
}
|
|
292
304
|
const gate = await reviewFanoutGate(taskId, specPaths, baseRef)
|
|
293
305
|
taskGates.push({ taskId, passed: gate.passed, rounds: gate.rounds, blockingCount: gate.blocking.length, baseRef })
|
|
294
306
|
return gate
|