bridgebench 3.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CITATION.cff +15 -0
- package/LICENSE +21 -0
- package/README.md +249 -0
- package/dist/chunk-4TWPCPRP.cjs +1097 -0
- package/dist/chunk-4TWPCPRP.cjs.map +1 -0
- package/dist/chunk-7YCJSOK7.cjs +398 -0
- package/dist/chunk-7YCJSOK7.cjs.map +1 -0
- package/dist/chunk-CIXITJW6.cjs +249 -0
- package/dist/chunk-CIXITJW6.cjs.map +1 -0
- package/dist/chunk-EQHRUV2I.js +1466 -0
- package/dist/chunk-EQHRUV2I.js.map +1 -0
- package/dist/chunk-JTVNKSMO.js +1096 -0
- package/dist/chunk-JTVNKSMO.js.map +1 -0
- package/dist/chunk-LFKEV2YL.js +398 -0
- package/dist/chunk-LFKEV2YL.js.map +1 -0
- package/dist/chunk-NJTYVNP4.cjs +1467 -0
- package/dist/chunk-NJTYVNP4.cjs.map +1 -0
- package/dist/chunk-UECBSKTD.js +244 -0
- package/dist/chunk-UECBSKTD.js.map +1 -0
- package/dist/cli.cjs +409 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +408 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.cjs +42 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +93 -0
- package/dist/client.d.ts +93 -0
- package/dist/client.js +42 -0
- package/dist/client.js.map +1 -0
- package/dist/contracts/index.cjs +47 -0
- package/dist/contracts/index.cjs.map +1 -0
- package/dist/contracts/index.d.cts +14 -0
- package/dist/contracts/index.d.ts +14 -0
- package/dist/contracts/index.js +47 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/index.cjs +171 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +214 -0
- package/dist/index.d.ts +214 -0
- package/dist/index.js +171 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-CCR9Mg1c.d.cts +319 -0
- package/dist/logger-QJU7SBDz.d.ts +319 -0
- package/dist/reports-4CejmOHf.d.cts +454 -0
- package/dist/reports-s2CTnGN8.d.ts +454 -0
- package/dist/tasks-CpaCJ6JE.d.cts +151 -0
- package/dist/tasks-CpaCJ6JE.d.ts +151 -0
- package/dist/tasks.cjs +22 -0
- package/dist/tasks.cjs.map +1 -0
- package/dist/tasks.d.cts +39 -0
- package/dist/tasks.d.ts +39 -0
- package/dist/tasks.js +22 -0
- package/dist/tasks.js.map +1 -0
- package/docs/README.md +25 -0
- package/docs/glossary.md +49 -0
- package/docs/methodology.md +58 -0
- package/docs/private-packs.md +74 -0
- package/docs/replay-elo.md +79 -0
- package/docs/task-authoring.md +80 -0
- package/package.json +137 -0
- package/tasks/hallucination/public/boundary-coverage-audit.yaml +274 -0
- package/tasks/hallucination/public/boundary-migration-audit.yaml +284 -0
- package/tasks/hallucination/public/conflict-dependency-versions.yaml +324 -0
- package/tasks/hallucination/public/conflict-runbook-versions.yaml +229 -0
- package/tasks/hallucination/public/fabrication-agent-tools.yaml +224 -0
- package/tasks/hallucination/public/fabrication-api-surface.yaml +239 -0
- package/tasks/hallucination/public/fidelity-commit-attribution.yaml +304 -0
- package/tasks/hallucination/public/fidelity-config-drift.yaml +307 -0
- package/tasks/hallucination/public/missing-deploy-window.yaml +204 -0
- package/tasks/hallucination/public/missing-latency-baseline.yaml +239 -0
- package/tasks/hallucination/public/premise-quota-breach.yaml +202 -0
- package/tasks/hallucination/public/premise-rollback-cause.yaml +235 -0
- package/tasks/reasoning/public/constraint-capacity-allocation.yaml +196 -0
- package/tasks/reasoning/public/constraint-deployment-policy.yaml +203 -0
- package/tasks/reasoning/public/counterexample-authorization-rule.yaml +278 -0
- package/tasks/reasoning/public/counterexample-scheduler-starvation.yaml +290 -0
- package/tasks/reasoning/public/root-cache-tenant-leak.yaml +225 -0
- package/tasks/reasoning/public/root-event-ordering.yaml +184 -0
- package/tasks/reasoning/public/stateful-lease-handoff.yaml +213 -0
- package/tasks/reasoning/public/stateful-retry-budget.yaml +222 -0
- package/tasks/reasoning/public/synthesis-api-contract.yaml +214 -0
- package/tasks/reasoning/public/synthesis-permission-migration.yaml +190 -0
- package/tasks/reasoning/public/uncertainty-conflicting-telemetry.yaml +242 -0
- package/tasks/reasoning/public/uncertainty-incomplete-incident.yaml +223 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const METHODOLOGY_VERSION = "arena-v0.3.0";
|
|
4
|
+
declare const BenchmarkCategorySchema: z.ZodEnum<["reasoning", "hallucination"]>;
|
|
5
|
+
type BenchmarkCategory = z.infer<typeof BenchmarkCategorySchema>;
|
|
6
|
+
declare const CATEGORIES: ["reasoning", "hallucination"];
|
|
7
|
+
declare const CATEGORY_CLUSTERS: Record<BenchmarkCategory, readonly string[]>;
|
|
8
|
+
declare const CATEGORY_META: Record<BenchmarkCategory, {
|
|
9
|
+
label: string;
|
|
10
|
+
tagline: string;
|
|
11
|
+
}>;
|
|
12
|
+
|
|
13
|
+
declare const TaskArtifactSchema: z.ZodObject<{
|
|
14
|
+
id: z.ZodString;
|
|
15
|
+
type: z.ZodEnum<["code", "log", "config", "spec", "diff", "table", "note"]>;
|
|
16
|
+
label: z.ZodString;
|
|
17
|
+
content: z.ZodString;
|
|
18
|
+
}, "strict", z.ZodTypeAny, {
|
|
19
|
+
type: "code" | "log" | "config" | "spec" | "diff" | "table" | "note";
|
|
20
|
+
id: string;
|
|
21
|
+
content: string;
|
|
22
|
+
label: string;
|
|
23
|
+
}, {
|
|
24
|
+
type: "code" | "log" | "config" | "spec" | "diff" | "table" | "note";
|
|
25
|
+
id: string;
|
|
26
|
+
content: string;
|
|
27
|
+
label: string;
|
|
28
|
+
}>;
|
|
29
|
+
type TaskArtifact = z.infer<typeof TaskArtifactSchema>;
|
|
30
|
+
declare const TaskPublicSchema: z.ZodObject<{
|
|
31
|
+
id: z.ZodString;
|
|
32
|
+
version: z.ZodString;
|
|
33
|
+
category: z.ZodEnum<["reasoning", "hallucination"]>;
|
|
34
|
+
cluster: z.ZodString;
|
|
35
|
+
difficulty: z.ZodEnum<["hard", "expert"]>;
|
|
36
|
+
title: z.ZodString;
|
|
37
|
+
summary: z.ZodString;
|
|
38
|
+
prompt: z.ZodString;
|
|
39
|
+
artifacts: z.ZodArray<z.ZodObject<{
|
|
40
|
+
id: z.ZodString;
|
|
41
|
+
type: z.ZodEnum<["code", "log", "config", "spec", "diff", "table", "note"]>;
|
|
42
|
+
label: z.ZodString;
|
|
43
|
+
content: z.ZodString;
|
|
44
|
+
}, "strict", z.ZodTypeAny, {
|
|
45
|
+
type: "code" | "log" | "config" | "spec" | "diff" | "table" | "note";
|
|
46
|
+
id: string;
|
|
47
|
+
content: string;
|
|
48
|
+
label: string;
|
|
49
|
+
}, {
|
|
50
|
+
type: "code" | "log" | "config" | "spec" | "diff" | "table" | "note";
|
|
51
|
+
id: string;
|
|
52
|
+
content: string;
|
|
53
|
+
label: string;
|
|
54
|
+
}>, "many">;
|
|
55
|
+
tags: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
56
|
+
}, "strict", z.ZodTypeAny, {
|
|
57
|
+
id: string;
|
|
58
|
+
version: string;
|
|
59
|
+
category: "reasoning" | "hallucination";
|
|
60
|
+
cluster: string;
|
|
61
|
+
difficulty: "hard" | "expert";
|
|
62
|
+
title: string;
|
|
63
|
+
summary: string;
|
|
64
|
+
prompt: string;
|
|
65
|
+
artifacts: {
|
|
66
|
+
type: "code" | "log" | "config" | "spec" | "diff" | "table" | "note";
|
|
67
|
+
id: string;
|
|
68
|
+
content: string;
|
|
69
|
+
label: string;
|
|
70
|
+
}[];
|
|
71
|
+
tags: string[];
|
|
72
|
+
}, {
|
|
73
|
+
id: string;
|
|
74
|
+
version: string;
|
|
75
|
+
category: "reasoning" | "hallucination";
|
|
76
|
+
cluster: string;
|
|
77
|
+
difficulty: "hard" | "expert";
|
|
78
|
+
title: string;
|
|
79
|
+
summary: string;
|
|
80
|
+
prompt: string;
|
|
81
|
+
artifacts: {
|
|
82
|
+
type: "code" | "log" | "config" | "spec" | "diff" | "table" | "note";
|
|
83
|
+
id: string;
|
|
84
|
+
content: string;
|
|
85
|
+
label: string;
|
|
86
|
+
}[];
|
|
87
|
+
tags?: string[] | undefined;
|
|
88
|
+
}>;
|
|
89
|
+
type TaskPublic = z.infer<typeof TaskPublicSchema>;
|
|
90
|
+
declare const TaskPrivateSchema: z.ZodObject<{
|
|
91
|
+
id: z.ZodString;
|
|
92
|
+
version: z.ZodString;
|
|
93
|
+
expectedResolution: z.ZodString;
|
|
94
|
+
requiredEvidence: z.ZodArray<z.ZodString, "many">;
|
|
95
|
+
disqualifyingErrors: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
96
|
+
rubric: z.ZodObject<{
|
|
97
|
+
correctness: z.ZodString;
|
|
98
|
+
evidenceGrounding: z.ZodString;
|
|
99
|
+
constraintHandling: z.ZodString;
|
|
100
|
+
completeness: z.ZodString;
|
|
101
|
+
}, "strict", z.ZodTypeAny, {
|
|
102
|
+
correctness: string;
|
|
103
|
+
constraintHandling: string;
|
|
104
|
+
completeness: string;
|
|
105
|
+
evidenceGrounding: string;
|
|
106
|
+
}, {
|
|
107
|
+
correctness: string;
|
|
108
|
+
constraintHandling: string;
|
|
109
|
+
completeness: string;
|
|
110
|
+
evidenceGrounding: string;
|
|
111
|
+
}>;
|
|
112
|
+
}, "strict", z.ZodTypeAny, {
|
|
113
|
+
id: string;
|
|
114
|
+
version: string;
|
|
115
|
+
expectedResolution: string;
|
|
116
|
+
requiredEvidence: string[];
|
|
117
|
+
disqualifyingErrors: string[];
|
|
118
|
+
rubric: {
|
|
119
|
+
correctness: string;
|
|
120
|
+
constraintHandling: string;
|
|
121
|
+
completeness: string;
|
|
122
|
+
evidenceGrounding: string;
|
|
123
|
+
};
|
|
124
|
+
}, {
|
|
125
|
+
id: string;
|
|
126
|
+
version: string;
|
|
127
|
+
expectedResolution: string;
|
|
128
|
+
requiredEvidence: string[];
|
|
129
|
+
rubric: {
|
|
130
|
+
correctness: string;
|
|
131
|
+
constraintHandling: string;
|
|
132
|
+
completeness: string;
|
|
133
|
+
evidenceGrounding: string;
|
|
134
|
+
};
|
|
135
|
+
disqualifyingErrors?: string[] | undefined;
|
|
136
|
+
}>;
|
|
137
|
+
type TaskPrivate = z.infer<typeof TaskPrivateSchema>;
|
|
138
|
+
interface ArenaTask {
|
|
139
|
+
public: TaskPublic;
|
|
140
|
+
/** Null when loaded without a private overlay. */
|
|
141
|
+
private: TaskPrivate | null;
|
|
142
|
+
publicHash: string;
|
|
143
|
+
privateHash: string | null;
|
|
144
|
+
}
|
|
145
|
+
/** A task whose hidden reference is present — required for judged matches. */
|
|
146
|
+
type CompleteArenaTask = ArenaTask & {
|
|
147
|
+
private: TaskPrivate;
|
|
148
|
+
privateHash: string;
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export { type ArenaTask as A, type BenchmarkCategory as B, CATEGORIES as C, METHODOLOGY_VERSION as M, type TaskArtifact as T, BenchmarkCategorySchema as a, CATEGORY_CLUSTERS as b, CATEGORY_META as c, type CompleteArenaTask as d, TaskArtifactSchema as e, type TaskPrivate as f, TaskPrivateSchema as g, type TaskPublic as h, TaskPublicSchema as i };
|
package/dist/tasks.cjs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
var _chunk4TWPCPRPcjs = require('./chunk-4TWPCPRP.cjs');
|
|
11
|
+
require('./chunk-CIXITJW6.cjs');
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
exports.TASKS_PER_CATEGORY = _chunk4TWPCPRPcjs.TASKS_PER_CATEGORY; exports.TASKS_PER_CLUSTER = _chunk4TWPCPRPcjs.TASKS_PER_CLUSTER; exports.TaskLoader = _chunk4TWPCPRPcjs.TaskLoader; exports.buildCompetitorPrompt = _chunk4TWPCPRPcjs.buildCompetitorPrompt; exports.competitorPromptPolicyHash = _chunk4TWPCPRPcjs.competitorPromptPolicyHash; exports.defaultTaskRoot = _chunk4TWPCPRPcjs.defaultTaskRoot; exports.mergePrivateHalves = _chunk4TWPCPRPcjs.mergePrivateHalves; exports.validatePublicTaskFile = _chunk4TWPCPRPcjs.validatePublicTaskFile;
|
|
22
|
+
//# sourceMappingURL=tasks.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/matthewmiller/Desktop/bridgemind/bridgebench/dist/tasks.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,6hBAAC","file":"/Users/matthewmiller/Desktop/bridgemind/bridgebench/dist/tasks.cjs"}
|
package/dist/tasks.d.cts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { f as TaskPrivate, B as BenchmarkCategory, d as CompleteArenaTask, A as ArenaTask } from './tasks-CpaCJ6JE.cjs';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
declare const TASKS_PER_CATEGORY = 12;
|
|
5
|
+
declare const TASKS_PER_CLUSTER = 2;
|
|
6
|
+
declare function defaultTaskRoot(category: BenchmarkCategory): string;
|
|
7
|
+
declare function validatePublicTaskFile(filePath: string): Promise<ArenaTask>;
|
|
8
|
+
declare class TaskLoader {
|
|
9
|
+
readonly category: BenchmarkCategory;
|
|
10
|
+
private readonly root;
|
|
11
|
+
private readonly privateDir;
|
|
12
|
+
constructor(category: BenchmarkCategory, root?: string, privateRoot?: string);
|
|
13
|
+
get hasPrivate(): boolean;
|
|
14
|
+
loadAll(options: {
|
|
15
|
+
requirePrivate: true;
|
|
16
|
+
}): Promise<CompleteArenaTask[]>;
|
|
17
|
+
loadAll(options?: {
|
|
18
|
+
requirePrivate?: boolean;
|
|
19
|
+
}): Promise<ArenaTask[]>;
|
|
20
|
+
}
|
|
21
|
+
interface PrivateHalf {
|
|
22
|
+
value: TaskPrivate;
|
|
23
|
+
/** SHA-256 of the exact private YAML the judges receive — the journal's task identity. */
|
|
24
|
+
hash: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Completes public tasks with private halves supplied by an external store
|
|
28
|
+
* (e.g. the API's rubric table) instead of the on-disk overlay. Pairing
|
|
29
|
+
* rules match the disk loader: matching id/version and every
|
|
30
|
+
* requiredEvidence entry naming a real public artifact.
|
|
31
|
+
*/
|
|
32
|
+
declare function mergePrivateHalves(tasks: readonly ArenaTask[], privateHalves: readonly PrivateHalf[]): CompleteArenaTask[];
|
|
33
|
+
declare function competitorPromptPolicyHash(category: BenchmarkCategory): string;
|
|
34
|
+
declare function buildCompetitorPrompt(task: ArenaTask): {
|
|
35
|
+
system: string;
|
|
36
|
+
user: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { type PrivateHalf, TASKS_PER_CATEGORY, TASKS_PER_CLUSTER, TaskLoader, buildCompetitorPrompt, competitorPromptPolicyHash, defaultTaskRoot, mergePrivateHalves, validatePublicTaskFile };
|
package/dist/tasks.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { f as TaskPrivate, B as BenchmarkCategory, d as CompleteArenaTask, A as ArenaTask } from './tasks-CpaCJ6JE.js';
|
|
2
|
+
import 'zod';
|
|
3
|
+
|
|
4
|
+
declare const TASKS_PER_CATEGORY = 12;
|
|
5
|
+
declare const TASKS_PER_CLUSTER = 2;
|
|
6
|
+
declare function defaultTaskRoot(category: BenchmarkCategory): string;
|
|
7
|
+
declare function validatePublicTaskFile(filePath: string): Promise<ArenaTask>;
|
|
8
|
+
declare class TaskLoader {
|
|
9
|
+
readonly category: BenchmarkCategory;
|
|
10
|
+
private readonly root;
|
|
11
|
+
private readonly privateDir;
|
|
12
|
+
constructor(category: BenchmarkCategory, root?: string, privateRoot?: string);
|
|
13
|
+
get hasPrivate(): boolean;
|
|
14
|
+
loadAll(options: {
|
|
15
|
+
requirePrivate: true;
|
|
16
|
+
}): Promise<CompleteArenaTask[]>;
|
|
17
|
+
loadAll(options?: {
|
|
18
|
+
requirePrivate?: boolean;
|
|
19
|
+
}): Promise<ArenaTask[]>;
|
|
20
|
+
}
|
|
21
|
+
interface PrivateHalf {
|
|
22
|
+
value: TaskPrivate;
|
|
23
|
+
/** SHA-256 of the exact private YAML the judges receive — the journal's task identity. */
|
|
24
|
+
hash: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Completes public tasks with private halves supplied by an external store
|
|
28
|
+
* (e.g. the API's rubric table) instead of the on-disk overlay. Pairing
|
|
29
|
+
* rules match the disk loader: matching id/version and every
|
|
30
|
+
* requiredEvidence entry naming a real public artifact.
|
|
31
|
+
*/
|
|
32
|
+
declare function mergePrivateHalves(tasks: readonly ArenaTask[], privateHalves: readonly PrivateHalf[]): CompleteArenaTask[];
|
|
33
|
+
declare function competitorPromptPolicyHash(category: BenchmarkCategory): string;
|
|
34
|
+
declare function buildCompetitorPrompt(task: ArenaTask): {
|
|
35
|
+
system: string;
|
|
36
|
+
user: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export { type PrivateHalf, TASKS_PER_CATEGORY, TASKS_PER_CLUSTER, TaskLoader, buildCompetitorPrompt, competitorPromptPolicyHash, defaultTaskRoot, mergePrivateHalves, validatePublicTaskFile };
|
package/dist/tasks.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TASKS_PER_CATEGORY,
|
|
3
|
+
TASKS_PER_CLUSTER,
|
|
4
|
+
TaskLoader,
|
|
5
|
+
buildCompetitorPrompt,
|
|
6
|
+
competitorPromptPolicyHash,
|
|
7
|
+
defaultTaskRoot,
|
|
8
|
+
mergePrivateHalves,
|
|
9
|
+
validatePublicTaskFile
|
|
10
|
+
} from "./chunk-JTVNKSMO.js";
|
|
11
|
+
import "./chunk-UECBSKTD.js";
|
|
12
|
+
export {
|
|
13
|
+
TASKS_PER_CATEGORY,
|
|
14
|
+
TASKS_PER_CLUSTER,
|
|
15
|
+
TaskLoader,
|
|
16
|
+
buildCompetitorPrompt,
|
|
17
|
+
competitorPromptPolicyHash,
|
|
18
|
+
defaultTaskRoot,
|
|
19
|
+
mergePrivateHalves,
|
|
20
|
+
validatePublicTaskFile
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# BridgeBench documentation
|
|
2
|
+
|
|
3
|
+
Start with the contract, then follow the workflow you need.
|
|
4
|
+
|
|
5
|
+
## Protocol
|
|
6
|
+
|
|
7
|
+
- [Methodology](methodology.md) — scheduling, blind judging, outcomes, and Elo.
|
|
8
|
+
- [Replay Elo](replay-elo.md) — verify a journal and reproduce its ladder.
|
|
9
|
+
- [Private packs](private-packs.md) — hidden-reference data flow and contamination controls.
|
|
10
|
+
|
|
11
|
+
## Contributing
|
|
12
|
+
|
|
13
|
+
- [Task authoring](task-authoring.md) — public schema, private schema, clusters, and validation.
|
|
14
|
+
- [Glossary](glossary.md) — the terms used by the engine, CLI, and published reports.
|
|
15
|
+
- [Repository contribution guide](../CONTRIBUTING.md) — local checks and pull-request expectations.
|
|
16
|
+
|
|
17
|
+
## Canonical sources
|
|
18
|
+
|
|
19
|
+
- Model roster and request policy: [`src/models.ts`](../src/models.ts)
|
|
20
|
+
- Category and methodology constants: [`src/types.ts`](../src/types.ts)
|
|
21
|
+
- Task-pack invariants: [`src/tasks.ts`](../src/tasks.ts)
|
|
22
|
+
- Journal verification: [`src/verification.ts`](../src/verification.ts)
|
|
23
|
+
- CLI workflows: `npm run arena -- --help` and `npm run tasks -- --help`
|
|
24
|
+
|
|
25
|
+
When prose and executable validation disagree, treat the code as the current behavior and open an issue to repair the documentation.
|
package/docs/glossary.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Glossary
|
|
2
|
+
|
|
3
|
+
## Arena
|
|
4
|
+
|
|
5
|
+
One independent benchmark category with its own task pack, journal, Elo ladder, and leaderboard. Ratings never cross arena boundaries.
|
|
6
|
+
|
|
7
|
+
## Competitor
|
|
8
|
+
|
|
9
|
+
A model answering the public task context. Competitors receive no hidden reference and do not know their opponent.
|
|
10
|
+
|
|
11
|
+
## Judge
|
|
12
|
+
|
|
13
|
+
A model comparing two anonymized competitor responses against the hidden reference. Judges are fixed, independent, and ineligible as competitors.
|
|
14
|
+
|
|
15
|
+
## Public task
|
|
16
|
+
|
|
17
|
+
The prompt and artifacts visible to competitors and committed under `tasks/<category>/public/`.
|
|
18
|
+
|
|
19
|
+
## Hidden reference
|
|
20
|
+
|
|
21
|
+
The expected resolution, required evidence, disqualifying errors, and rubric used by judges. Active references live outside the public repository.
|
|
22
|
+
|
|
23
|
+
## Private overlay
|
|
24
|
+
|
|
25
|
+
The separate checkout containing active hidden references. `BRIDGEBENCH_PRIVATE_DIR` points the engine to it.
|
|
26
|
+
|
|
27
|
+
## Run manifest
|
|
28
|
+
|
|
29
|
+
The canonical inputs that define one deterministic schedule: methodology, engine version, category, seed, match count, model roster and policy, task hashes, and prompt-policy hashes.
|
|
30
|
+
|
|
31
|
+
## Journal
|
|
32
|
+
|
|
33
|
+
The append-only local execution record. Each JSONL line contains one completed match and references its run manifest.
|
|
34
|
+
|
|
35
|
+
## Snapshot
|
|
36
|
+
|
|
37
|
+
A verified report derived from a journal replay. Snapshots are replaceable; journals are not.
|
|
38
|
+
|
|
39
|
+
## Point
|
|
40
|
+
|
|
41
|
+
One win awarded for a judged majority or forfeit. No-contests award no point.
|
|
42
|
+
|
|
43
|
+
## Elo
|
|
44
|
+
|
|
45
|
+
The per-arena rating derived in journal order. Ratings start at 1000 and use K=32.
|
|
46
|
+
|
|
47
|
+
## Published replica
|
|
48
|
+
|
|
49
|
+
The bridgebench.ai API copy of verified engine output. Publishing does not replace the local journal as the execution authority.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Methodology — the arena contract
|
|
2
|
+
|
|
3
|
+
Every ranking BridgeBench publishes is the fold of an append-only match journal. This document specifies the full protocol that produces a journal line, so any published ladder can be audited or reproduced. The engine stamps every line with `methodologyVersion` (currently `arena-v0.3.0`, `src/contracts/categories.ts`); results from different methodology versions never mix silently.
|
|
4
|
+
|
|
5
|
+
## Run identity and scheduling
|
|
6
|
+
|
|
7
|
+
A **run** is deterministic from a versioned manifest:
|
|
8
|
+
|
|
9
|
+
- The manifest binds the category, seed, match count, engine and methodology versions, sorted competitor and judge slugs, request policies, task hashes, and competitor/judge prompt-policy hashes. Runs may select an explicit roster of at least two unique, enabled competitors; omitting one selects every enabled competitor.
|
|
10
|
+
- The run ID is a SHA-256 prefix of the canonical manifest. Every journal line records the full manifest hash.
|
|
11
|
+
- The scheduler builds all `(competitorA, competitorB, task)` combinations and greedily picks the next match by lowest exposure, ordered by: max per-model exposure → summed model exposure → task exposure → pair exposure. Ties break by a seeded mulberry32 PRNG, so balance is reproducible, not incidental (`src/scheduler.ts`).
|
|
12
|
+
- Which competitor sits on side A is randomized per match from the same seeded stream.
|
|
13
|
+
- Match IDs are stable hashes; re-running a schedule with `--resume` skips journaled match IDs exactly. Repeating a completed schedule without `--resume` is rejected.
|
|
14
|
+
|
|
15
|
+
## Competitor execution
|
|
16
|
+
|
|
17
|
+
- Both competitors receive byte-identical context: a category-specific system prompt plus the task title, summary, prompt, and all public artifacts inline (`src/tasks.ts`). They are never told they are in a match, and the system prompt forbids revealing model identity.
|
|
18
|
+
- Requests run concurrently over OpenRouter with pinned slugs (`latest` aliases prohibited). Before any paid run the CLI re-validates the selected competitors and all three judges against the live catalog, and confirms judges still support structured output.
|
|
19
|
+
- Transport is fail-closed: 3 attempts on retryable errors, per-request watchdog timeouts, and a hard prompt-size cap. A competitor that exhausts retries **forfeits** (the survivor wins); two failures make a **no-contest** (no point, no Elo movement).
|
|
20
|
+
|
|
21
|
+
## Blind three-judge panel
|
|
22
|
+
|
|
23
|
+
Judged matches go to a fixed, cross-vendor panel of three model judges. Independence is enforced structurally:
|
|
24
|
+
|
|
25
|
+
1. **Anonymization.** Before an answer crosses into a judge prompt, explicit competitor identity terms (IDs, canonical slugs, display names, vendors) and family names (Claude, GPT, Kimi, Opus, …) are redacted (`src/judges.ts`). Judges see only `Model A` and `Model B`.
|
|
26
|
+
2. **Per-judge order permutation.** Whether A/B are swapped for a given judge is a deterministic hash of `matchId|judgeId`, so position bias can't systematically favor one side and the permutation is replayable.
|
|
27
|
+
3. **Isolation.** A judge receives the task, the hidden reference (expected resolution, required evidence, disqualifying errors, rubric), and the two anonymous answers — never identities, ratings, costs, or the other judges' votes.
|
|
28
|
+
4. **Forced choice, structured output.** Verdicts are JSON-schema enforced (`MODEL_A` or `MODEL_B`, confidence, rationale, four-criteria commentary, violations). A malformed verdict gets one retry, then the judge **abstains**.
|
|
29
|
+
5. **Majority.** Two valid votes for the same side decide the match. Agreement is recorded as `unanimous` (three winner votes), `split` (exactly two winner votes, including a 2–0 panel with one abstention), or `insufficient` (no majority → no-contest).
|
|
30
|
+
|
|
31
|
+
Judge prompts are category-specific: the reasoning panel treats hedging on a determinable deliverable as an error and disqualifying errors as near-decisive; the hallucination panel weighs fabrication heaviest and also penalizes refusing deliverables the artifacts do support.
|
|
32
|
+
|
|
33
|
+
The hidden reference is **judging context, not an oracle** — no deterministic task score picks the winner, and no model-generated code is ever executed.
|
|
34
|
+
|
|
35
|
+
## Scoring
|
|
36
|
+
|
|
37
|
+
- A win awards exactly one point and one Elo update. Elo starts at 1000 with K=32 (`src/elo.ts`). Forfeit wins score identically to judged wins; no-contests change nothing.
|
|
38
|
+
- Each arena keeps its own ladder. Reasoning Elo and hallucination Elo never mix.
|
|
39
|
+
|
|
40
|
+
## The journal is the source of truth
|
|
41
|
+
|
|
42
|
+
- Every completed match is appended to `results/<category>/journal.jsonl` **before** any report is rebuilt. Snapshots and leaderboards are derived atomically and may be deleted and rebuilt at any time.
|
|
43
|
+
- Every line records: methodology version, run ID and manifest hash, seed, schedule index, the task's ID/version/cluster and the SHA-256 of **both** task halves (`publicHash`, `privateHash`), both full competitor responses with token/cost/latency accounting, the panel's votes and rationales, `eloBefore`/`eloAfter` for both models, and the match cost.
|
|
44
|
+
- The task hashes make drift externally detectable: if a task file changes after a match ran, the recorded hash no longer matches the file. When a retired pack's private halves are published, `privateHash` proves they are byte-identical to what the judges actually used.
|
|
45
|
+
- OpenRouter generation IDs are journaled per response; `npm run arena -- generation <id>` fetches the provider's own token/cost record for independent cross-checking.
|
|
46
|
+
|
|
47
|
+
`npm run arena -- verify` schema-validates every line, checks outcome and panel invariants, replays points and Elo, and validates referenced run manifests. Reports and resume state use the same verified fold. See [replay-elo.md](replay-elo.md) for the complete workflow.
|
|
48
|
+
|
|
49
|
+
## Adversarial-input posture
|
|
50
|
+
|
|
51
|
+
Candidate answers are treated as untrusted data end to end: judge prompts explicitly refuse instructions embedded in answers, verdicts are schema-validated, the dashboard renders model output only as escaped text, structured logs redact API keys, and journal/log/snapshot files are written mode 0600.
|
|
52
|
+
|
|
53
|
+
## Operational guards
|
|
54
|
+
|
|
55
|
+
- **Budget stop**: spend is checked before each match against `--max-cost-usd` (default $25); a stopped run resumes deterministically with `--resume`.
|
|
56
|
+
- **Cancellation**: Ctrl-C or the dashboard cancel action aborts active competitor and judge requests, emits `run.cancellation-requested` followed by terminal `run.cancelled`, and stops before the next match. Completed journal lines remain resumable; a partial match is never appended.
|
|
57
|
+
- **Health stop**: once ≥4 matches complete and ≥50% contain a failed competitor response, the run halts instead of journaling a batch of silent no-contests (`--no-health-stop` overrides).
|
|
58
|
+
- **Triage**: every run auto-prints an anomaly report (failed requests, suspiciously fast responses, low output, truncation, unreported reasoning tokens, zero-cost accounting, judge abstentions) — `npm run triage` re-analyzes any journal.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Private packs — the hidden-reference overlay
|
|
2
|
+
|
|
3
|
+
Task prompts are public. Active expected resolutions, trap inventories, disqualifying-error lists, and rubrics are withheld from the public repository to reduce contamination risk. This document defines where those hidden references travel, who stores them, and how they are retired.
|
|
4
|
+
|
|
5
|
+
## Layout
|
|
6
|
+
|
|
7
|
+
The overlay is a separate, private checkout that mirrors this repo's `tasks/` layout:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
<private-checkout>/
|
|
11
|
+
└── tasks/
|
|
12
|
+
├── reasoning/private/<task-id>.yaml # one per public task, same filename
|
|
13
|
+
└── hallucination/private/<task-id>.yaml
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Point the engine at it with:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
export BRIDGEBENCH_PRIVATE_DIR=/path/to/private-checkout
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Resolution order in `src/tasks.ts`: an explicit `privateRoot` constructor argument → the `BRIDGEBENCH_PRIVATE_DIR` overlay → a repo-local `tasks/<category>/private/` directory (maintainer setups only; the public repo never contains one).
|
|
23
|
+
|
|
24
|
+
## What works without the overlay
|
|
25
|
+
|
|
26
|
+
| Works from public halves alone | Needs the overlay |
|
|
27
|
+
| ---------------------------------------------------------------- | --------------------------------------------------------- |
|
|
28
|
+
| `npm run tasks -- validate` (public schema + pack balance) | `npm run arena -- run` (judges need the hidden reference) |
|
|
29
|
+
| `npm run report` (rebuild snapshots/leaderboards from a journal) | Starting a run from the dashboard |
|
|
30
|
+
| `npm run triage`, `arena generation <id>` | Authoring/validating private halves |
|
|
31
|
+
| `npm run arena -- publish` (journal sync; admin key required) | `npm run tasks -- publish` (the API stores both halves) |
|
|
32
|
+
| The dashboard's Leaderboard and Matches views | |
|
|
33
|
+
| `npm test` (offline suites synthesize a stand-in reference) | |
|
|
34
|
+
|
|
35
|
+
When a judged run is attempted without the overlay, the loader fails closed with a pointer to this document.
|
|
36
|
+
|
|
37
|
+
## Data flow and trust boundaries
|
|
38
|
+
|
|
39
|
+
An active hidden reference is not confined to the overlay during a run:
|
|
40
|
+
|
|
41
|
+
1. `TaskLoader` reads it into the local operator process.
|
|
42
|
+
2. `JudgePanel` includes it in requests to the three configured model judges.
|
|
43
|
+
3. The local journal stores its SHA-256 hash, not its contents.
|
|
44
|
+
4. `tasks publish` may send it to the configured BridgeBench API, where it is stored outside public read endpoints.
|
|
45
|
+
|
|
46
|
+
The operator machine, configured model providers, transport provider, and private API store are therefore inside the active-pack trust boundary. Their retention and access policies matter. Withholding references from Git history and public issues reduces exposure; it cannot prove that a third party never retains or trains on transmitted content.
|
|
47
|
+
|
|
48
|
+
If an active reference leaks:
|
|
49
|
+
|
|
50
|
+
1. stop paid runs for that pack;
|
|
51
|
+
2. record the affected task IDs and first-known exposure time;
|
|
52
|
+
3. rotate the compromised tasks and bump their versions;
|
|
53
|
+
4. start a new run manifest and journal;
|
|
54
|
+
5. disclose the incident with the retired references when doing so no longer exposes live tasks.
|
|
55
|
+
|
|
56
|
+
## Contamination guard
|
|
57
|
+
|
|
58
|
+
Three mechanisms keep hidden references out of the public repo:
|
|
59
|
+
|
|
60
|
+
- `.gitignore` ignores `tasks/*/private/`, so a casually dropped-in overlay can't be staged by `git add -A`.
|
|
61
|
+
- CI fails if any tracked path matches `tasks/*/private/`.
|
|
62
|
+
- CI parses tracked task YAML and rejects every private-only top-level field, including `expectedResolution`, `requiredEvidence`, `disqualifyingErrors`, and `rubric`.
|
|
63
|
+
|
|
64
|
+
When both halves load, `tasks validate` also verifies pairing: matching `id`/`version` and that every `requiredEvidence` entry names a real public artifact.
|
|
65
|
+
|
|
66
|
+
## Publish-at-retirement
|
|
67
|
+
|
|
68
|
+
Hidden references are withheld only while their pack is live:
|
|
69
|
+
|
|
70
|
+
1. **While live** — private halves are absent from the public repo. They remain in the overlay and the private systems named in the trust boundary above. Every journal line records `privateHash`, the SHA-256 of the exact private YAML the judges received.
|
|
71
|
+
2. **At retirement** — when a pack rotates out, its private halves are published in full alongside the pack's final journal.
|
|
72
|
+
3. **Verification** — anyone can hash the published private halves and compare them with each journaled `privateHash`. `arena verify` checks the journal's match and Elo invariants; the hash comparison checks task identity.
|
|
73
|
+
|
|
74
|
+
If a published score doesn't reproduce, open an issue.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Replay the Elo yourself
|
|
2
|
+
|
|
3
|
+
A BridgeBench ladder is not a claim — it is the fold of a journal you can re-run. This is the recipe.
|
|
4
|
+
|
|
5
|
+
## What you need
|
|
6
|
+
|
|
7
|
+
- The arena's journal: `results/<category>/journal.jsonl`, one JSON object per completed match, in append order. Published season journals are downloadable from [bridgebench.ai](https://bridgebench.ai).
|
|
8
|
+
- The matching `runs/` directory for journals that reference versioned run manifests.
|
|
9
|
+
- No API key and no private overlay.
|
|
10
|
+
|
|
11
|
+
Verify the included synthetic journal:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm run arena -- verify \
|
|
15
|
+
--category reasoning \
|
|
16
|
+
--journal test/fixtures/journals/valid.jsonl
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For a downloaded journal, place its run manifests in a sibling `runs/` directory or pass `--manifests-dir <path>`.
|
|
20
|
+
|
|
21
|
+
## The journal line, abridged
|
|
22
|
+
|
|
23
|
+
```jsonc
|
|
24
|
+
{
|
|
25
|
+
"methodologyVersion": "arena-v0.3.0",
|
|
26
|
+
"runId": "run-…", "matchId": "…", "scheduleIndex": 3, "seed": "…",
|
|
27
|
+
"task": { "id": "…", "version": "2.0.0", "category": "reasoning",
|
|
28
|
+
"cluster": "…", "publicHash": "sha256…", "privateHash": "sha256…" },
|
|
29
|
+
"competitors": { "modelA": "…", "modelB": "…", "responseA": { /* full text + tokens + cost */ }, "responseB": { … } },
|
|
30
|
+
"outcome": "judged", // judged | forfeit | no-contest
|
|
31
|
+
"winnerModelId": "…", // null on no-contest
|
|
32
|
+
"panel": { "votes": [ /* 3 votes: verdict, rationale, resolved winner */ ], "agreement": "unanimous" },
|
|
33
|
+
"eloBefore": { "modelA-id": 1000, "modelB-id": 1016 },
|
|
34
|
+
"eloAfter": { "modelA-id": 1016.4, "modelB-id": 999.6 },
|
|
35
|
+
"pointAwarded": true,
|
|
36
|
+
"matchCostUsd": 0.42
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Replay algorithm
|
|
41
|
+
|
|
42
|
+
Elo is classic: initial rating **1000**, **K = 32**, one update per decided match, applied in journal order.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
expected(a, b) = 1 / (1 + 10^((b − a) / 400))
|
|
46
|
+
|
|
47
|
+
for each line in journal order:
|
|
48
|
+
if winnerModelId is null: continue # no-contest — nothing moves
|
|
49
|
+
a, b = ratings of modelA, modelB # default 1000 if unseen
|
|
50
|
+
ea = expected(a, b)
|
|
51
|
+
scoreA = 1 if winnerModelId == modelA else 0
|
|
52
|
+
ratings[modelA] = a + 32 * (scoreA − ea)
|
|
53
|
+
ratings[modelB] = b + 32 * ((1 − scoreA) − (1 − ea))
|
|
54
|
+
points[winnerModelId] += 1
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Forfeit wins update Elo exactly like judged wins; `no-contest` lines change nothing. Reasoning and hallucination journals fold separately and never share ratings.
|
|
58
|
+
|
|
59
|
+
The rating formula lives in [`src/elo.ts`](../src/elo.ts). [`src/verification.ts`](../src/verification.ts) owns the validated fold used by reports, resume state, and the CLI verifier.
|
|
60
|
+
|
|
61
|
+
## Verification is per-line, not just end-state
|
|
62
|
+
|
|
63
|
+
Every line records `eloBefore` and `eloAfter` for both models. So you don't just check that your final ladder matches the published one — you can assert, at every single match, that:
|
|
64
|
+
|
|
65
|
+
1. `eloBefore` equals your running ratings at that point;
|
|
66
|
+
2. `eloAfter` equals your computed update;
|
|
67
|
+
3. the winner is consistent with the panel's votes (two valid votes for the same side), or with a forfeit (exactly one failed response).
|
|
68
|
+
|
|
69
|
+
`arena verify` rejects a reordered line, edited verdict, inconsistent outcome, wrong point, altered cost, or nudged rating at the first failing line. New journal lines also bind to a versioned run manifest covering the roster, task hashes, prompt policies, methodology, and engine version.
|
|
70
|
+
|
|
71
|
+
With the repo checked out, `npm run report` verifies the journal before rebuilding `snapshot.json` and `leaderboard.md`; diff them against published snapshots.
|
|
72
|
+
|
|
73
|
+
## Auditing beyond the math
|
|
74
|
+
|
|
75
|
+
- **Task drift**: hash the public task file (`sha256` of the raw YAML) and compare with the journaled `publicHash`. For retired packs, do the same with the published private halves against `privateHash` — see [private-packs.md](private-packs.md).
|
|
76
|
+
- **Judging**: each vote carries the judge's rationale and resolved winner; `agreement` must match the winner-vote count (three `unanimous`, exactly two `split`).
|
|
77
|
+
- **Cost/token accounting**: every response carries its OpenRouter generation ID; `npm run arena -- generation <id>` fetches the provider's own record.
|
|
78
|
+
|
|
79
|
+
If any of it doesn't reproduce, open an issue with the line number.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Task authoring
|
|
2
|
+
|
|
3
|
+
Every task is split into a **public half** (what competitors and everyone else sees, in this repo) and a **private half** (the hidden reference judges use, kept in the private overlay — see [private-packs.md](private-packs.md)). Both halves share a filename, ID, and version; the loader refuses mismatches.
|
|
4
|
+
|
|
5
|
+
## Domain invariant
|
|
6
|
+
|
|
7
|
+
**Every task is a coding / software-engineering scenario.** BridgeBench is a vibe-coding benchmark, so all artifacts are software artifacts — source code, diffs, git history, CI logs and configs, package manifests, API specs, database migrations, deploy records, service telemetry, AI-coding-agent sessions — and every deliverable is a question a coding agent would face. No generic business ops (invoices, staffing, org charts). All content is fictional: invented companies, services, and people only.
|
|
8
|
+
|
|
9
|
+
## Pack invariants (enforced by the loader and `npm run tasks -- validate`)
|
|
10
|
+
|
|
11
|
+
- Exactly **12 tasks per category**, **2 per cluster**, unique IDs.
|
|
12
|
+
- Public and private halves must agree on `id` and `version`.
|
|
13
|
+
- Every `requiredEvidence` entry in the private half must name an existing public artifact ID.
|
|
14
|
+
- Public artifact IDs must be unique and the YAML filename must match the task ID.
|
|
15
|
+
- Rendered competitor and worst-case judge payloads must fit the engine's prompt budget.
|
|
16
|
+
- A task's `category` must match its pack directory and its `cluster` must belong to that category.
|
|
17
|
+
|
|
18
|
+
Use `npm run tasks -- validate --file <path>` to validate one proposed public task without enforcing full-pack balance.
|
|
19
|
+
|
|
20
|
+
## Public half schema (`tasks/<category>/public/<id>.yaml`)
|
|
21
|
+
|
|
22
|
+
| Field | Constraints |
|
|
23
|
+
| ------------------ | ----------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `id` | kebab-case, regex-validated |
|
|
25
|
+
| `version` | semver; bump on any content change (hashes are journaled) |
|
|
26
|
+
| `category` | `reasoning` \| `hallucination` |
|
|
27
|
+
| `cluster` | one of the category's six clusters (below) |
|
|
28
|
+
| `difficulty` | `hard` \| `expert` (current packs are all `expert`) |
|
|
29
|
+
| `title`, `summary` | summary ≤ 500 chars |
|
|
30
|
+
| `prompt` | ≤ 10k chars — the numbered deliverables live here |
|
|
31
|
+
| `artifacts[]` | 1–20 of `{id, type, label, content ≤ 40k}`; `type` ∈ code, log, config, spec, diff, table, note |
|
|
32
|
+
| `tags[]` | optional, ≤ 60 chars each |
|
|
33
|
+
|
|
34
|
+
Tasks are deliberately heavyweight: five to eight interlocking artifacts (~9–18k characters) and four to ten numbered deliverables, so a match exercises real deliberation budget instead of a one-screen skim.
|
|
35
|
+
|
|
36
|
+
## Private half schema (overlay: `tasks/<category>/private/<id>.yaml`)
|
|
37
|
+
|
|
38
|
+
| Field | Purpose |
|
|
39
|
+
| ----------------------- | -------------------------------------------------------------------- |
|
|
40
|
+
| `id`, `version` | must match the public half |
|
|
41
|
+
| `expectedResolution` | ≤ 10k prose — the defensible resolution for every deliverable |
|
|
42
|
+
| `requiredEvidence[]` | public artifact IDs a strong answer must ground itself in |
|
|
43
|
+
| `disqualifyingErrors[]` | the planted decoy conclusions, named explicitly |
|
|
44
|
+
| `rubric` | `{correctness, evidenceGrounding, constraintHandling, completeness}` |
|
|
45
|
+
|
|
46
|
+
## Reasoning clusters
|
|
47
|
+
|
|
48
|
+
Fully determinable; decoy paths planted and listed as disqualifying errors in the hidden reference:
|
|
49
|
+
|
|
50
|
+
- **stateful-execution** — trace state through interleaved operations;
|
|
51
|
+
- **constraint-reconciliation** — many constraints, one consistent assignment;
|
|
52
|
+
- **root-cause-reasoning** — the incident has one defensible root cause and several attractive red herrings;
|
|
53
|
+
- **multi-artifact-synthesis** — the answer only exists across artifacts, never inside one;
|
|
54
|
+
- **formal-counterexample** — find the input/schedule that breaks the claimed property;
|
|
55
|
+
- **uncertainty-adversarial** — noisy signals, but one best-supported conclusion.
|
|
56
|
+
|
|
57
|
+
**Authoring rule:** every decoy you plant must appear in `disqualifyingErrors`, and the true chain must be derivable from `requiredEvidence` alone. If two resolutions survive honest scrutiny, the task is broken — fix the artifacts, not the rubric.
|
|
58
|
+
|
|
59
|
+
## Hallucination clusters
|
|
60
|
+
|
|
61
|
+
Traps are internal to the artifacts, so ground truth stays verifiable; every task mixes supported deliverables with traps so blanket refusal loses as clearly as fabrication:
|
|
62
|
+
|
|
63
|
+
- **false-premise** — deliverables embed claims the artifacts contradict; the premise must be corrected with citations;
|
|
64
|
+
- **missing-evidence** — the key fact is deliberately absent while tempting near-substitutes exist;
|
|
65
|
+
- **entity-fabrication** — plausible endpoints, functions, tools, files, or config keys that are never defined, next to near-miss twins that are;
|
|
66
|
+
- **knowledge-boundary** — audit-style question sets where roughly half the items are determinable and half are not;
|
|
67
|
+
- **conflicting-sources** — artifacts disagree; silent blending or unacknowledged picking is the failure;
|
|
68
|
+
- **citation-fidelity** — exact values, quotes, and attributions under dense near-duplicate detail.
|
|
69
|
+
|
|
70
|
+
**Authoring rule:** the private half classifies every deliverable as _supported_, _false-premise_, or _not-determinable_, with the full trap inventory. Where a task tests absence (entity fabrication, missing evidence), an artifact should self-declare exhaustiveness (e.g. a spec that states it lists the complete API surface), so "doesn't exist" is provable from the material.
|
|
71
|
+
|
|
72
|
+
## Process
|
|
73
|
+
|
|
74
|
+
1. Author both halves locally (public in your fork, private in the overlay checkout).
|
|
75
|
+
2. `npm run tasks -- validate` until clean — with the overlay present it validates pairing and evidence; without it, the public schema and pack balance.
|
|
76
|
+
3. Bump `version` on any edit to either half; the journal hashes both, so silent drift is detectable.
|
|
77
|
+
4. External contributors: validate and propose the public half through the task-proposal issue form. Do not include a hidden reference.
|
|
78
|
+
5. After a public task is accepted, a maintainer starts a private handoff through the GitHub account attached to the issue. The private half never appears in the public issue or pull request.
|
|
79
|
+
6. Replacing a live task requires a pack-rotation plan that preserves the 12-task, two-per-cluster invariant.
|
|
80
|
+
7. Private halves are published when their pack retires (see [private-packs.md](private-packs.md)).
|