thumbgate 1.37.1 → 1.37.3
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/.agents/skills/article-syndication-pipeline/SKILL.md +37 -0
- package/.agents/skills/ci-gha-buildkite-patterns-not-clone/SKILL.md +72 -0
- package/.agents/skills/cobble-hot-store-compare-not-clone/SKILL.md +80 -0
- package/.agents/skills/colab-compute-honesty-not-clone/SKILL.md +70 -0
- package/.agents/skills/comet-session-logger/SKILL.md +59 -0
- package/.agents/skills/datadog-llm-obs-compare-not-clone/SKILL.md +75 -0
- package/.agents/skills/deeppattern-discipline-honesty-not-clone/SKILL.md +73 -0
- package/.agents/skills/thumbgate-board-loop/SKILL.md +72 -0
- package/.agents/skills/thumbgate-daily-discoveries/SKILL.md +57 -0
- package/.agents/skills/token-shunt-honesty-not-clone/SKILL.md +67 -0
- package/.agents/skills/typesafe-typed-questions-not-clone/SKILL.md +86 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.well-known/mcp/server-card.json +1 -1
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/forge/forge.yaml +3 -3
- package/adapters/future-agi/.mcp.json +1 -1
- package/adapters/future-agi/config.toml +1 -1
- package/adapters/future-agi/opencode.json +1 -1
- package/adapters/herdr/herdr-plugin.toml +2 -2
- package/adapters/mcp/server-stdio.js +1 -1
- package/adapters/opencode/opencode.json +1 -1
- package/bin/cli.js +257 -0
- package/config/gate-templates.json +96 -0
- package/package.json +55 -12
- package/public/blog/2026-09-23-datadog-llm-obs-four-practices.html +42 -0
- package/public/index.html +2 -2
- package/public/install.html +7 -7
- package/public/numbers.html +2 -2
- package/scripts/ci-gha-buildkite-patterns.js +393 -0
- package/scripts/cli-schema.js +90 -0
- package/scripts/cobble-hot-store-split.js +600 -0
- package/scripts/colab-compute-honesty.js +281 -0
- package/scripts/deeppattern-discipline-honesty.js +431 -0
- package/scripts/gates-engine.js +16 -5
- package/scripts/install-thumbgate-daily-publish-launchd.sh +83 -0
- package/scripts/llm-obs-honesty.js +478 -0
- package/scripts/thumbgate-board-loop.js +432 -0
- package/scripts/thumbgate-daily-discoveries-publish.js +413 -0
- package/scripts/thumbgate-daily-discoveries-publish.sh +18 -0
- package/scripts/token-shunt-honesty.js +502 -0
- package/scripts/typesafe-typed-questions.js +1138 -0
- package/server.json +2 -2
- package/skills/article-syndication-pipeline/SKILL.md +37 -0
- package/skills/comet-session-logger/SKILL.md +59 -0
- package/skills/thumbgate-daily-discoveries/SKILL.md +57 -0
- package/src/index.js +10 -0
- package/src/integrations/ideabrowser-connector.js +190 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: typesafe-typed-questions-not-clone
|
|
3
|
+
description: >
|
|
4
|
+
TypeSafe (console.typesafe.ai/hook, Jev System One) is a calibrated decision
|
|
5
|
+
model, not a ThumbGate clone. Steal typed noul/choice/score + code-owned
|
|
6
|
+
route() + confidence-as-second-axis onto existing PreToolUse rails. Never
|
|
7
|
+
install typesafe-sdk, call api.typesafe.ai, clone Jev, or unpark the LLM
|
|
8
|
+
adjudicator (#3690/#3687). Slash: /typesafe-typed-questions-not-clone.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# TypeSafe typed questions — compare, do not clone
|
|
12
|
+
|
|
13
|
+
## Goal
|
|
14
|
+
|
|
15
|
+
Produce fail-closed typed-question composition for whom: ThumbGate PreToolUse
|
|
16
|
+
— so a tool-call state is scored with independent noul/choice/score questions
|
|
17
|
+
and **code** routes pass|review|block. TypeSafe/Jev stays a neighbor FORMAT,
|
|
18
|
+
not a SKU, not an LLM adjudicator.
|
|
19
|
+
|
|
20
|
+
## Constraints
|
|
21
|
+
|
|
22
|
+
| NEVER | ALWAYS |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| Install `typesafe-sdk` / wire Jev as the PreToolUse gate | `npx thumbgate typesafe-typed-questions --json` |
|
|
25
|
+
| `--use-typesafe-api` (gate) | `--live` shadow vs `POST /v1/systemone`; code still owns `route()` |
|
|
26
|
+
| Clone Jev / System One as the gate | Deterministic matchers answer the battery |
|
|
27
|
+
| Unpark LLM adjudicator (#3690/#3687) | Code owns `route()`; model does not emit the verdict |
|
|
28
|
+
| One free-form "should we allow this?" judge | Atomic noul per hazard + score for severity |
|
|
29
|
+
| Dual-edit untracked `llm-adjudicator` theater | Map onto existing `gate-check` rails |
|
|
30
|
+
| N HTTP calls (one question each) | One POST with the whole battery (`parallel_questions`) |
|
|
31
|
+
|
|
32
|
+
HARD fail closed. REFUSE SKU clones. ECI: no net-new governance product.
|
|
33
|
+
Do NOT install `typesafe-sdk`. Do NOT let Jev emit `permissionDecision`. `--live` is a shadow scorer (grok-fleet key), not the gate.
|
|
34
|
+
|
|
35
|
+
Complementary to trading `/typesafe-system-one-not-clone` (AGENT-651 claim gate). Do **not** dual-edit `IgorGanapolsky/trading` `scripts/typesafe_claim_gate.py`. This skill is ThumbGate PreToolUse only.
|
|
36
|
+
|
|
37
|
+
## Reference
|
|
38
|
+
|
|
39
|
+
- https://console.typesafe.ai/hook (signed-in intro / Replay intro)
|
|
40
|
+
- https://docs.typesafe.ai/cookbooks/llm_guardrails.md
|
|
41
|
+
- https://docs.typesafe.ai/cookbooks/parallel_questions
|
|
42
|
+
- https://docs.typesafe.ai/patterns/confidence-routing.md
|
|
43
|
+
- Playground "Support agent audit" (noul battery + choice + score over one state)
|
|
44
|
+
- `scripts/typesafe-typed-questions.js`
|
|
45
|
+
- `/high-roi-steal-and-finish` · `/eci-thumbgate-ip-wall`
|
|
46
|
+
|
|
47
|
+
## Examples (show, don't tell)
|
|
48
|
+
|
|
49
|
+
Weak: Summarize Jev and `npm install typesafe-sdk` as the new PreToolUse hook.
|
|
50
|
+
|
|
51
|
+
Gold:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
$ npx thumbgate typesafe-typed-questions --json --map-only
|
|
55
|
+
codeOwnsRoute: true
|
|
56
|
+
$ npx thumbgate typesafe-typed-questions --json --tool-name=Bash --command='git push --force origin main'
|
|
57
|
+
{"route":"block","answers":{"destructive":{"noul":1,"source":"deterministic"}}}
|
|
58
|
+
$ node --test tests/typesafe-typed-questions.test.js
|
|
59
|
+
# --clone-jev / --use-typesafe-api / --llm-adjudicate → fail
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Procedures
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx thumbgate typesafe-typed-questions --json --map-only
|
|
66
|
+
npx thumbgate typesafe-typed-questions --json --tool-name=Bash --command='git push --force origin main'
|
|
67
|
+
npx thumbgate typesafe-typed-questions --json --clone-jev
|
|
68
|
+
npm run test:typesafe-typed-questions
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
1. Put the PreToolUse payload in `state`.
|
|
72
|
+
2. Ask independent typed questions (noul per hazard, choice for family, score for severity).
|
|
73
|
+
3. Answer them with deterministic matchers — never Jev.
|
|
74
|
+
4. `route()` in code: action threshold → block, review threshold → review, severity ≥ 2 promotes review to block.
|
|
75
|
+
5. Refuse `--clone-jev`, `--use-typesafe-api` (gate), `--llm-adjudicate`, and model-emitted verdicts.
|
|
76
|
+
6. Optional `--live` shadows the same battery against Jev in **one** POST. `--fan-out-questions` fails. Receipt is estimated N× input tokens, not the cookbook's 12.2×.
|
|
77
|
+
|
|
78
|
+
## Rubric
|
|
79
|
+
|
|
80
|
+
- empty / ordinary Read → `route=pass`, `ok=true`
|
|
81
|
+
- `git push --force` → `route=block`, `destructive.noul=1`
|
|
82
|
+
- `git add -A` → `route=review` (warn-level noul=0.55)
|
|
83
|
+
- `--clone-jev` / `--use-typesafe-api` / `--llm-adjudicate` → `ok=false`
|
|
84
|
+
- playground-shaped noul without a matcher → `unevaluated_question` (do not call Jev)
|
|
85
|
+
- doctor: `npm run test:typesafe-typed-questions` PASS
|
|
86
|
+
- evidence: command output in the same turn
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "thumbgate",
|
|
3
3
|
"description": "One 👎 becomes a hard rule the agent cannot bypass. Captures thumbs-down feedback, distills it into PreToolUse Pre-Action Checks, enforced across every future Claude Code session.",
|
|
4
|
-
"version": "1.37.
|
|
4
|
+
"version": "1.37.3",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Igor Ganapolsky",
|
|
7
7
|
"email": "ig5973700@gmail.com",
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"thumbgate": {
|
|
4
4
|
"command": "npx",
|
|
5
|
-
"args": ["--yes", "--package", "thumbgate@1.37.
|
|
5
|
+
"args": ["--yes", "--package", "thumbgate@1.37.3", "thumbgate", "serve"]
|
|
6
6
|
}
|
|
7
7
|
},
|
|
8
8
|
"hooks": {
|
|
9
9
|
"preToolUse": {
|
|
10
10
|
"command": "npx",
|
|
11
|
-
"args": ["--yes", "--package", "thumbgate@1.37.
|
|
11
|
+
"args": ["--yes", "--package", "thumbgate@1.37.3", "thumbgate", "gate-check"]
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
}
|
|
@@ -9,12 +9,12 @@ version: "1"
|
|
|
9
9
|
skills:
|
|
10
10
|
thumbgate-gate-check:
|
|
11
11
|
description: "ThumbGate PreToolUse gate — blocks known-bad tool calls"
|
|
12
|
-
command: "npx --yes --package thumbgate@1.37.
|
|
12
|
+
command: "npx --yes --package thumbgate@1.37.3 thumbgate gate-check"
|
|
13
13
|
trigger: pre_tool_use
|
|
14
14
|
|
|
15
15
|
thumbgate-feedback:
|
|
16
16
|
description: "ThumbGate feedback capture — logs user prompt context"
|
|
17
|
-
command: "npx --yes --package thumbgate@1.37.
|
|
17
|
+
command: "npx --yes --package thumbgate@1.37.3 thumbgate hook-auto-capture"
|
|
18
18
|
trigger: user_prompt
|
|
19
19
|
|
|
20
20
|
mcp:
|
|
@@ -23,6 +23,6 @@ mcp:
|
|
|
23
23
|
args:
|
|
24
24
|
- "--yes"
|
|
25
25
|
- "--package"
|
|
26
|
-
- "thumbgate@1.37.
|
|
26
|
+
- "thumbgate@1.37.3"
|
|
27
27
|
- "thumbgate"
|
|
28
28
|
- "serve"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[plugin]
|
|
2
2
|
id = "thumbgate-approvals"
|
|
3
3
|
name = "ThumbGate Approvals"
|
|
4
|
-
version = "1.37.
|
|
4
|
+
version = "1.37.3"
|
|
5
5
|
minHerdrVersion = "0.7.0"
|
|
6
6
|
description = "Pre-action governance, spend guard, and safety approval gates for multi-agent terminal sessions in Herdr."
|
|
7
7
|
platforms = ["linux", "macos", "windows"]
|
|
@@ -12,7 +12,7 @@ category = "Security & Governance"
|
|
|
12
12
|
|
|
13
13
|
[mcp_server]
|
|
14
14
|
command = "npx"
|
|
15
|
-
args = ["--yes", "--package", "thumbgate@1.37.
|
|
15
|
+
args = ["--yes", "--package", "thumbgate@1.37.3", "thumbgate", "serve"]
|
|
16
16
|
|
|
17
17
|
[mcp_server.env]
|
|
18
18
|
THUMBGATE_ENFORCE_ENTITLEMENTS = "1"
|
|
@@ -334,7 +334,7 @@ const {
|
|
|
334
334
|
finalizeSession: finalizeFeedbackSession,
|
|
335
335
|
} = require('../../scripts/feedback-session');
|
|
336
336
|
|
|
337
|
-
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.37.
|
|
337
|
+
const SERVER_INFO = { name: 'thumbgate-mcp', version: '1.37.3' };
|
|
338
338
|
const COMMERCE_CATEGORIES = [
|
|
339
339
|
'product_recommendation',
|
|
340
340
|
'brand_compliance',
|
package/bin/cli.js
CHANGED
|
@@ -2692,6 +2692,175 @@ function jitHarnessCompose() {
|
|
|
2692
2692
|
if (report.status === 'fail') process.exitCode = 1;
|
|
2693
2693
|
}
|
|
2694
2694
|
|
|
2695
|
+
function tokenShuntHonesty() {
|
|
2696
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2697
|
+
const {
|
|
2698
|
+
buildTokenShuntHonestyReport,
|
|
2699
|
+
formatTokenShuntHonestyReport,
|
|
2700
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'token-shunt-honesty'));
|
|
2701
|
+
const report = buildTokenShuntHonestyReport(args);
|
|
2702
|
+
if (args.json) {
|
|
2703
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2704
|
+
} else {
|
|
2705
|
+
process.stdout.write(formatTokenShuntHonestyReport(report));
|
|
2706
|
+
}
|
|
2707
|
+
if (args.strict && report.status !== 'ready') {
|
|
2708
|
+
process.exitCode = 1;
|
|
2709
|
+
return;
|
|
2710
|
+
}
|
|
2711
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2712
|
+
}
|
|
2713
|
+
|
|
2714
|
+
async function typesafeTypedQuestionsDoctor() {
|
|
2715
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2716
|
+
const {
|
|
2717
|
+
buildTypesafeTypedQuestionsReportAsync,
|
|
2718
|
+
formatTypesafeTypedQuestionsReport,
|
|
2719
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'typesafe-typed-questions'));
|
|
2720
|
+
const report = await buildTypesafeTypedQuestionsReportAsync(args);
|
|
2721
|
+
if (args.json) {
|
|
2722
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2723
|
+
} else {
|
|
2724
|
+
process.stdout.write(formatTypesafeTypedQuestionsReport(report));
|
|
2725
|
+
}
|
|
2726
|
+
if (args.strict && report.status !== 'ready') {
|
|
2727
|
+
process.exitCode = 1;
|
|
2728
|
+
return;
|
|
2729
|
+
}
|
|
2730
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
function ciGhaBuildkitePatternsDoctor() {
|
|
2734
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2735
|
+
const {
|
|
2736
|
+
buildCiGhaBuildkitePatternsReport,
|
|
2737
|
+
formatCiGhaBuildkitePatternsReport,
|
|
2738
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'ci-gha-buildkite-patterns'));
|
|
2739
|
+
const report = args['map-only']
|
|
2740
|
+
? buildCiGhaBuildkitePatternsReport({ ...args, mapOnly: true })
|
|
2741
|
+
: buildCiGhaBuildkitePatternsReport({
|
|
2742
|
+
json: Boolean(args.json),
|
|
2743
|
+
strict: Boolean(args.strict),
|
|
2744
|
+
mapOnly: Boolean(args['map-only']),
|
|
2745
|
+
annotate: Boolean(args.annotate),
|
|
2746
|
+
cloneBuildkite: Boolean(args['clone-buildkite']),
|
|
2747
|
+
migrate: Boolean(args.migrate),
|
|
2748
|
+
rerunQueued: Boolean(args['rerun-queued']),
|
|
2749
|
+
quarantine: Boolean(args.quarantine),
|
|
2750
|
+
jobsJson: args['jobs-json'] || '',
|
|
2751
|
+
workflow: args.workflow || '',
|
|
2752
|
+
});
|
|
2753
|
+
if (args.json) {
|
|
2754
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2755
|
+
} else {
|
|
2756
|
+
process.stdout.write(formatCiGhaBuildkitePatternsReport(report));
|
|
2757
|
+
}
|
|
2758
|
+
if (args.strict && report.status !== 'ready') {
|
|
2759
|
+
process.exitCode = 1;
|
|
2760
|
+
return;
|
|
2761
|
+
}
|
|
2762
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2765
|
+
function deeppatternDisciplineHonestyDoctor() {
|
|
2766
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2767
|
+
const {
|
|
2768
|
+
buildDeeppatternDisciplineHonestyReport,
|
|
2769
|
+
formatDeeppatternDisciplineHonestyReport,
|
|
2770
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'deeppattern-discipline-honesty'));
|
|
2771
|
+
const report = buildDeeppatternDisciplineHonestyReport(args);
|
|
2772
|
+
if (args.json) {
|
|
2773
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2774
|
+
} else {
|
|
2775
|
+
process.stdout.write(formatDeeppatternDisciplineHonestyReport(report));
|
|
2776
|
+
}
|
|
2777
|
+
if (args.strict && report.status !== 'ready') {
|
|
2778
|
+
process.exitCode = 1;
|
|
2779
|
+
return;
|
|
2780
|
+
}
|
|
2781
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2782
|
+
}
|
|
2783
|
+
|
|
2784
|
+
|
|
2785
|
+
function thumbgateBoardLoop() {
|
|
2786
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2787
|
+
const { buildReport, formatReport } = require(path.join(PKG_ROOT, 'scripts', 'thumbgate-board-loop'));
|
|
2788
|
+
const truthy = (value) => value === true || /^(1|true|yes|on)$/i.test(String(value || '').trim());
|
|
2789
|
+
const report = buildReport({
|
|
2790
|
+
json: truthy(args.json),
|
|
2791
|
+
apply: truthy(args.apply),
|
|
2792
|
+
maxUpdateBranch: Number(args['max-update-branch'] ?? 1),
|
|
2793
|
+
maxPrManage: Number(args['max-pr-manage'] ?? 1),
|
|
2794
|
+
maxComments: Number(args['max-comments'] ?? 4),
|
|
2795
|
+
skipPr: args['skip-pr'] ? Number(args['skip-pr']) : null,
|
|
2796
|
+
});
|
|
2797
|
+
|
|
2798
|
+
if (args.json) {
|
|
2799
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2800
|
+
} else {
|
|
2801
|
+
process.stdout.write(formatReport(report));
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2805
|
+
function colabComputeHonestyDoctor() {
|
|
2806
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2807
|
+
const {
|
|
2808
|
+
buildColabComputeHonestyReport,
|
|
2809
|
+
formatColabComputeHonestyReport,
|
|
2810
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'colab-compute-honesty'));
|
|
2811
|
+
const report = buildColabComputeHonestyReport(args);
|
|
2812
|
+
if (args.json) {
|
|
2813
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2814
|
+
} else {
|
|
2815
|
+
process.stdout.write(formatColabComputeHonestyReport(report));
|
|
2816
|
+
}
|
|
2817
|
+
if (args.strict && report.status !== 'ready') {
|
|
2818
|
+
process.exitCode = 1;
|
|
2819
|
+
return;
|
|
2820
|
+
}
|
|
2821
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
function llmObsHonesty() {
|
|
2825
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2826
|
+
const {
|
|
2827
|
+
buildLlmObsHonestyReport,
|
|
2828
|
+
formatLlmObsHonestyReport,
|
|
2829
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'llm-obs-honesty'));
|
|
2830
|
+
const report = buildLlmObsHonestyReport(args);
|
|
2831
|
+
if (args.json) {
|
|
2832
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2833
|
+
} else {
|
|
2834
|
+
process.stdout.write(formatLlmObsHonestyReport(report));
|
|
2835
|
+
}
|
|
2836
|
+
if (args.strict && report.status !== 'ready') {
|
|
2837
|
+
process.exitCode = 1;
|
|
2838
|
+
return;
|
|
2839
|
+
}
|
|
2840
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
function cobbleHotStoreSplit() {
|
|
2844
|
+
const args = parseArgs(process.argv.slice(3));
|
|
2845
|
+
const {
|
|
2846
|
+
buildCobbleHotStoreSplitReport,
|
|
2847
|
+
formatCobbleHotStoreSplitReport,
|
|
2848
|
+
} = require(path.join(PKG_ROOT, 'scripts', 'cobble-hot-store-split'));
|
|
2849
|
+
const report = buildCobbleHotStoreSplitReport(args);
|
|
2850
|
+
|
|
2851
|
+
if (args.json) {
|
|
2852
|
+
console.log(JSON.stringify(report, null, 2));
|
|
2853
|
+
} else {
|
|
2854
|
+
process.stdout.write(formatCobbleHotStoreSplitReport(report));
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
if (args.strict && report.status !== 'ready') {
|
|
2858
|
+
process.exitCode = 1;
|
|
2859
|
+
return;
|
|
2860
|
+
}
|
|
2861
|
+
if (report.status === 'fail') process.exitCode = 1;
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2695
2864
|
function allowlistBridgeHonestyDoctor() {
|
|
2696
2865
|
const args = parseArgs(process.argv.slice(3));
|
|
2697
2866
|
const {
|
|
@@ -3015,6 +3184,25 @@ async function gateCheck() {
|
|
|
3015
3184
|
return;
|
|
3016
3185
|
}
|
|
3017
3186
|
|
|
3187
|
+
const { evaluatePreToolUse } = require(path.join(PKG_ROOT, 'scripts', 'token-shunt-honesty'));
|
|
3188
|
+
const shunt = evaluatePreToolUse({
|
|
3189
|
+
toolName: input.tool_name || input.toolName,
|
|
3190
|
+
toolInput: input.tool_input || input.toolInput || {},
|
|
3191
|
+
cwd: input.cwd || process.cwd(),
|
|
3192
|
+
});
|
|
3193
|
+
if (shunt && shunt.ok === false) {
|
|
3194
|
+
process.stdout.write(`${JSON.stringify({
|
|
3195
|
+
decision: 'block',
|
|
3196
|
+
reason: `token-shunt: ${shunt.reason}`,
|
|
3197
|
+
hookSpecificOutput: {
|
|
3198
|
+
hookEventName: 'PreToolUse',
|
|
3199
|
+
permissionDecision: 'deny',
|
|
3200
|
+
permissionDecisionReason: `token-shunt: ${shunt.reason}`,
|
|
3201
|
+
},
|
|
3202
|
+
})}\n`);
|
|
3203
|
+
return;
|
|
3204
|
+
}
|
|
3205
|
+
|
|
3018
3206
|
const output = await gatesEngine.runAsync(input);
|
|
3019
3207
|
process.stdout.write(output + '\n');
|
|
3020
3208
|
} catch (err) {
|
|
@@ -3562,6 +3750,14 @@ function help() {
|
|
|
3562
3750
|
console.log(' openui-catalog-compose-honesty Catalog-compose-only + repair-before-claim (OpenUI FORMAT)');
|
|
3563
3751
|
console.log(' allowlist-bridge-honesty Audit allowlisted registries/proxies as hops, not trust boundaries');
|
|
3564
3752
|
console.log(' jit-harness-compose Compose memory/planning/action/capability onto existing rails (JIT FORMAT)');
|
|
3753
|
+
console.log(' cobble-hot-store-split Split durable/delivery/hot lesson planes (CobbleDB FORMAT)');
|
|
3754
|
+
console.log(' token-shunt-honesty Intercept untargeted bulk reads (Portal FORMAT; not shunt@portal)');
|
|
3755
|
+
console.log(' typesafe-typed-questions Typed noul/choice/score + code-owned route (TypeSafe FORMAT; not Jev)');
|
|
3756
|
+
console.log(' ci-gha-buildkite-patterns First-fail + PR fail-fast on GitHub Actions (Buildkite FORMAT; not Buildkite)');
|
|
3757
|
+
console.log(' deeppattern-discipline-honesty Layer-check + evidence-closeout (DeepPattern FORMAT; not AQG/DE)');
|
|
3758
|
+
console.log(' colab-compute-honesty Compute-unit honesty from Colab /signup (not a GPU SKU)');
|
|
3759
|
+
console.log(' llm-obs-honesty Four LLM-obs practices on existing rails (Datadog FORMAT, not a clone)');
|
|
3760
|
+
console.log(' board-loop Classify+drain Issues/PR wall (BEHIND Dependabot, never approve)');
|
|
3565
3761
|
console.log(' workspace-search-route Route query to rg/fts/vector/hybrid/graph (zg FORMAT)');
|
|
3566
3762
|
console.log(' intent-governed-execution NL intent → classify/authorize/gate/HITL/evidence (CyberStrike FORMAT)');
|
|
3567
3763
|
console.log(' background-governance Background-agent run report and dispatch risk check');
|
|
@@ -3605,6 +3801,14 @@ function help() {
|
|
|
3605
3801
|
console.log(' npx thumbgate openui-catalog-compose-honesty --catalog=catalog.json --stream=compose.txt --repair --json');
|
|
3606
3802
|
console.log(' npx thumbgate allowlist-bridge-honesty --json');
|
|
3607
3803
|
console.log(' npx thumbgate jit-harness-compose --task="implement PreToolUse gate fix" --json');
|
|
3804
|
+
console.log(' npx thumbgate cobble-hot-store-split --json');
|
|
3805
|
+
console.log(' npx thumbgate token-shunt-honesty --json --lines=800');
|
|
3806
|
+
console.log(' npx thumbgate typesafe-typed-questions --json --tool-name=Bash --command="git push --force origin main"');
|
|
3807
|
+
console.log(' npx thumbgate ci-gha-buildkite-patterns --json --map-only');
|
|
3808
|
+
console.log(' npx thumbgate deeppattern-discipline-honesty --json --map-only');
|
|
3809
|
+
console.log(' npx thumbgate colab-compute-honesty --json --map-only');
|
|
3810
|
+
console.log(' npx thumbgate llm-obs-honesty --json');
|
|
3811
|
+
console.log(' npx thumbgate board-loop --json');
|
|
3608
3812
|
console.log(' npx thumbgate workspace-search-route --query="how does X connect" --json');
|
|
3609
3813
|
console.log(' npx thumbgate intent-governed-execution --intent="railway deploy" --json');
|
|
3610
3814
|
console.log(' npx thumbgate upstream-contributions --max-repos=10 --write');
|
|
@@ -3646,6 +3850,11 @@ const SUBCOMMAND_HELP = {
|
|
|
3646
3850
|
lessons: 'Usage: npx thumbgate lessons [--query="..."] [--limit=N]\n\nSearch the lesson database (Pro feature).',
|
|
3647
3851
|
search: 'Usage: npx thumbgate search <query>\n\nSearch ThumbGate knowledge base (Pro feature).',
|
|
3648
3852
|
'gate-check': 'Usage: npx thumbgate gate-check\n\nPreToolUse hook interface: reads tool call JSON from stdin, outputs gate verdict.',
|
|
3853
|
+
'typesafe-typed-questions': 'Usage: npx thumbgate typesafe-typed-questions [--payload=path] [--tool-name=Bash] [--command="..."] [--json] [--map-only] [--clone-jev]\n\nTypeSafe FORMAT steal: typed noul/choice/score over a PreToolUse payload, code-owned pass/review/block. Does not install typesafe-sdk or call Jev.',
|
|
3854
|
+
'ci-gha-buildkite-patterns': 'Usage: npx thumbgate ci-gha-buildkite-patterns [--jobs-json=path] [--workflow=path] [--json] [--map-only]\n\nBuildkite pipeline FORMAT on GitHub Actions: first-fail step, PR fail-fast, needs:/skip/annotations. Does not add Buildkite.',
|
|
3855
|
+
'deeppattern-discipline-honesty': 'Usage: npx thumbgate deeppattern-discipline-honesty [--claim="..."] [--closeout=path.md] [--json] [--map-only]\n\nDeepPattern FORMAT steal: layer-check + evidence-closeout. Does not install AQG/Decision Engine.',
|
|
3856
|
+
'board-loop': 'Usage: npx thumbgate board-loop [--apply] [--json] [--max-update-branch=1] [--max-pr-manage=1] [--max-comments=4] [--skip-pr=N]\n\nClassify Issues+PR wall: update-branch BEHIND green Dependabot, pr:manage READY, comment DIRTY/ECI. Never approve.',
|
|
3857
|
+
'colab-compute-honesty': 'Usage: npx thumbgate colab-compute-honesty [--claim="..."] [--plan-proof=proplus] [--json] [--map-only]\n\nColab /signup FORMAT steal: Compute Units ≠ dedicated GPU; Subscribe ≠ receipt. Does not buy Pro/Pro+.',
|
|
3649
3858
|
'claim-stop-check': 'Usage: npx thumbgate claim-stop-check\n\nClaude Stop-hook interface: reads the hook payload from stdin and blocks factual claims that disagree with configured sources.',
|
|
3650
3859
|
'verify-claims': 'Usage: npx thumbgate verify-claims --claim="the row count is 1,284" [--config=.thumbgate/claim-verifiers.json] [--cwd=path] [--json]\n\nRecheck supported factual claims against operator-configured SQLite, filesystem, and JSON sources. Exits non-zero on mismatch, missing verifier, or verifier error.',
|
|
3651
3860
|
'hermes-gate': 'Usage: npx thumbgate hermes-gate\n\nNous Research Hermes Agent pre_tool_call shell hook: reads Hermes tool-call JSON from stdin, runs the ThumbGate gate pipeline (strict by default), and outputs {"decision":"block","reason":...} to veto or {} to allow. Gates terminal/patch/skill_manage etc. See adapters/hermes/config.yaml.',
|
|
@@ -4265,6 +4474,54 @@ switch (COMMAND) {
|
|
|
4265
4474
|
case 'harness-compose':
|
|
4266
4475
|
jitHarnessCompose();
|
|
4267
4476
|
break;
|
|
4477
|
+
case 'cobble-hot-store-split':
|
|
4478
|
+
case 'cobble-hot-store':
|
|
4479
|
+
case 'cobbledb-split':
|
|
4480
|
+
case 'hot-store-split':
|
|
4481
|
+
cobbleHotStoreSplit();
|
|
4482
|
+
break;
|
|
4483
|
+
case 'token-shunt-honesty':
|
|
4484
|
+
case 'token-shunt':
|
|
4485
|
+
case 'shunt-honesty':
|
|
4486
|
+
tokenShuntHonesty();
|
|
4487
|
+
break;
|
|
4488
|
+
case 'typesafe-typed-questions':
|
|
4489
|
+
case 'typesafe-hook':
|
|
4490
|
+
case 'typed-questions':
|
|
4491
|
+
case 'jev-typed-questions':
|
|
4492
|
+
typesafeTypedQuestionsDoctor().catch((err) => {
|
|
4493
|
+
console.error(err && err.stack ? err.stack : err);
|
|
4494
|
+
process.exitCode = 1;
|
|
4495
|
+
});
|
|
4496
|
+
break;
|
|
4497
|
+
case 'board-loop':
|
|
4498
|
+
case 'thumbgate-board-loop':
|
|
4499
|
+
case 'pr-issue-loop':
|
|
4500
|
+
thumbgateBoardLoop();
|
|
4501
|
+
break;
|
|
4502
|
+
case 'colab-compute-honesty':
|
|
4503
|
+
case 'colab-honesty':
|
|
4504
|
+
case 'compute-unit-honesty':
|
|
4505
|
+
colabComputeHonestyDoctor();
|
|
4506
|
+
break;
|
|
4507
|
+
case 'llm-obs-honesty':
|
|
4508
|
+
case 'datadog-llm-obs':
|
|
4509
|
+
case 'llm-observability-honesty':
|
|
4510
|
+
llmObsHonesty();
|
|
4511
|
+
break;
|
|
4512
|
+
case 'ci-gha-buildkite-patterns':
|
|
4513
|
+
case 'ci-buildkite-patterns':
|
|
4514
|
+
case 'gha-buildkite-honesty':
|
|
4515
|
+
case 'first-fail-gha':
|
|
4516
|
+
ciGhaBuildkitePatternsDoctor();
|
|
4517
|
+
break;
|
|
4518
|
+
case 'deeppattern-discipline-honesty':
|
|
4519
|
+
case 'deeppattern-honesty':
|
|
4520
|
+
case 'layer-check-honesty':
|
|
4521
|
+
case 'evidence-closeout-honesty':
|
|
4522
|
+
case 'aqg-de-honesty':
|
|
4523
|
+
deeppatternDisciplineHonestyDoctor();
|
|
4524
|
+
break;
|
|
4268
4525
|
case 'workspace-search-route':
|
|
4269
4526
|
case 'zg-search-route':
|
|
4270
4527
|
case 'zvec-grep-route':
|
|
@@ -61,6 +61,102 @@
|
|
|
61
61
|
"roi": "Mirrors OpenUI Gateway's repair-before-users-see-it FORMAT on ThumbGate rails: invalid compose never becomes a completion claim.",
|
|
62
62
|
"rollout": "Require openui-catalog-compose-honesty --repair --claim-ready evidence before any compose/UI done claim. Does not install OpenUI Gateway."
|
|
63
63
|
},
|
|
64
|
+
{
|
|
65
|
+
"id": "require-typed-pretool-questions",
|
|
66
|
+
"name": "Require typed noul/choice/score PreToolUse questions",
|
|
67
|
+
"category": "Agent Honesty",
|
|
68
|
+
"signal": "👎",
|
|
69
|
+
"defaultAction": "block",
|
|
70
|
+
"severity": "high",
|
|
71
|
+
"pattern": "(?=[\\s\\S]*(should we allow this tool call|free-?form judge|llm[- ]adjudicat|typesafe-sdk|api\\.typesafe\\.ai|clone\\s+jev|jev-latest))(?=[\\s\\S]*(pretooluse|gate-check))|question type (prompt|text|chat)",
|
|
72
|
+
"problem": "Blocks free-form LLM judges and TypeSafe/Jev SKU clones as the PreToolUse gate. TypeSafe FORMAT: atomic noul/choice/score questions over one tool-call state, answered deterministically.",
|
|
73
|
+
"roi": "Keeps PreToolUse as typed, inspectable questions instead of a prompt-and-parse adjudicator. Does not install typesafe-sdk.",
|
|
74
|
+
"rollout": "Pair with typesafe-typed-questions --json. Enable wherever an agent wants to add a second-model judge in front of gate-check."
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "require-code-owned-route",
|
|
78
|
+
"name": "Require code-owned pass/review/block route",
|
|
79
|
+
"category": "Agent Honesty",
|
|
80
|
+
"signal": "👎",
|
|
81
|
+
"defaultAction": "block",
|
|
82
|
+
"severity": "high",
|
|
83
|
+
"pattern": "(?=[\\s\\S]*(model-emitted verdict|wire jev as the gate|use-typesafe-api|llm[- ]adjudicat|clone jev))(?=[\\s\\S]*(route|verdict|pretooluse))|permissionDecision[\\s\\S]*(allow|deny)[\\s\\S]*from[\\s\\S]*(jev|llm)",
|
|
84
|
+
"problem": "Blocks letting Jev, an LLM adjudicator, or any model emit the PreToolUse verdict. TypeSafe FORMAT: code owns route(); confidence is a second axis.",
|
|
85
|
+
"roi": "Same probabilities, different policies. Thresholds live in code, not in a prompt. LLM adjudicator #3690/#3687 stays parked.",
|
|
86
|
+
"rollout": "Require typesafe-typed-questions --claim-ready evidence before claiming a typed-question hook is ready. Does not call api.typesafe.ai."
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": "require-compute-unit-proof",
|
|
90
|
+
"name": "Require Compute Unit / plan receipt before Colab GPU claims",
|
|
91
|
+
"category": "Agent Honesty",
|
|
92
|
+
"signal": "👎",
|
|
93
|
+
"defaultAction": "block",
|
|
94
|
+
"severity": "high",
|
|
95
|
+
"pattern": "(?=[\\s\\S]*(colab pro\\+|proplus|a100|v100|background execution|24 hours?|compute units?))(?=[\\s\\S]*(eval|offload|gpu|notebook|colab))",
|
|
96
|
+
"problem": "Blocks treating a Colab Subscribe button or CU pack as a dedicated GPU. Live /signup: paid SKUs sell Compute Units; Subscribe visible is not a receipt.",
|
|
97
|
+
"roi": "Stops A100/Pro+ offload theater. ThumbGate evals stay on GitHub Actions.",
|
|
98
|
+
"rollout": "Pair with colab-compute-honesty --json. Require --plan-proof from a Current-plan receipt."
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"id": "refuse-colab-sku-clone",
|
|
102
|
+
"name": "Refuse Colab-runner SKU clones and surprise Pro spend",
|
|
103
|
+
"category": "Agent Honesty",
|
|
104
|
+
"signal": "👎",
|
|
105
|
+
"defaultAction": "block",
|
|
106
|
+
"severity": "high",
|
|
107
|
+
"pattern": "colab-cli|google-colab-pro-runner|ngrok.{0,40}colab|colab.{0,40}ssh|zero-cost a100|buy.{0,20}colab pro",
|
|
108
|
+
"problem": "Blocks cloning Colab as a ThumbGate GPU harness or buying Pro/Pro+/CU from an agent session.",
|
|
109
|
+
"roi": "No surprise $9.99/$49.99 spend. No fake colab-cli.",
|
|
110
|
+
"rollout": "Enable wherever an agent proposes Colab offload. Does not purchase a plan."
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"id": "require-same-layer-comparison",
|
|
114
|
+
"name": "Require same-layer product comparisons (DeepPattern layer-check)",
|
|
115
|
+
"category": "Agent Honesty",
|
|
116
|
+
"signal": "👎",
|
|
117
|
+
"defaultAction": "block",
|
|
118
|
+
"severity": "high",
|
|
119
|
+
"pattern": "(?=[\\s\\S]*(openrouter|litellm|token aggregat|api gateway|raw (model )?api|foundation model))(?=[\\s\\S]*(replace[sd]?|substitut|commoditiz|competes? with|instead of)[\\s\\S]*(thumbgate|pretooluse))",
|
|
120
|
+
"problem": "Blocks treating L4 transport / L2 models as substitutes for L7 ThumbGate PreToolUse governance (DeepPattern layer-check FORMAT).",
|
|
121
|
+
"roi": "Stops category-error competitive analysis. Gateways are inputs; hosted multi-model panels are complements.",
|
|
122
|
+
"rollout": "Pair with deeppattern-discipline-honesty --json. Tag L1–L8 before competitor claims."
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "require-evidence-closeout-items",
|
|
126
|
+
"name": "Require evidence-closeout items before done claims",
|
|
127
|
+
"category": "Agent Honesty",
|
|
128
|
+
"signal": "👎",
|
|
129
|
+
"defaultAction": "block",
|
|
130
|
+
"severity": "high",
|
|
131
|
+
"pattern": "(?=[\\s\\S]*(done|shipped|fixed|complete|merged))(?![\\s\\S]*(scope completed|verification run|production boundary))",
|
|
132
|
+
"problem": "Blocks summary-without-evidence closeouts. AQG evidence-closeout FORMAT: six required items under an Evidence heading.",
|
|
133
|
+
"roi": "Aligns with Completion Claim Contract. Fresh verification before the word done.",
|
|
134
|
+
"rollout": "Pair with deeppattern-discipline-honesty --closeout=path.md --strict."
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"id": "refuse-buildkite-vendor-migration",
|
|
138
|
+
"name": "Refuse Buildkite vendor migration on public GitHub Actions",
|
|
139
|
+
"category": "Agent Honesty",
|
|
140
|
+
"signal": "👎",
|
|
141
|
+
"defaultAction": "block",
|
|
142
|
+
"severity": "high",
|
|
143
|
+
"pattern": "migrate.{0,40}buildkite|replace github actions with buildkite|add buildkite as.{0,20}required|buildkite-agent|test engine auto-?quarantine",
|
|
144
|
+
"problem": "Blocks adding Buildkite Pipelines/agents/Test Engine as a second CI vendor. Steal first-fail + fail-fast onto existing GHA.",
|
|
145
|
+
"roi": "Public repo GHA minutes stay $0. No second required check. Diagnosis stays the first failed step.",
|
|
146
|
+
"rollout": "Pair with ci-gha-buildkite-patterns --json. Keep ubuntu-latest required contexts."
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"id": "refuse-deeppattern-sku-clone",
|
|
150
|
+
"name": "Refuse DeepPattern AQG/Decision-Engine SKU clones",
|
|
151
|
+
"category": "Agent Honesty",
|
|
152
|
+
"signal": "👎",
|
|
153
|
+
"defaultAction": "block",
|
|
154
|
+
"severity": "high",
|
|
155
|
+
"pattern": "dp-install|install_aqg|agent-quality-gates|decision-engine.{0,40}(clone|install|sku)|clone.{0,20}(aqg|decision.engine|deeppattern)",
|
|
156
|
+
"problem": "Blocks cloning Agent Quality Gates or Decision Engine as a ThumbGate product surface.",
|
|
157
|
+
"roi": "FORMAT steal only (layer-check + evidence-closeout). No hosted cross-vendor audit SKU.",
|
|
158
|
+
"rollout": "Enable on competitive-steal and install prompts. Does not vendor DeepPattern."
|
|
159
|
+
},
|
|
64
160
|
{
|
|
65
161
|
"id": "require-broker-signed-execution-receipt",
|
|
66
162
|
"name": "Require broker-signed execution receipts",
|