quantum-reasoning-skill 1.0.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.
@@ -0,0 +1,257 @@
1
+ """Evaluate baseline and quantum-reasoning runs from JSONL files.
2
+
3
+ The evaluator uses only the Python standard library. It does not call a model.
4
+ External runners can write one result row per case and this script will validate,
5
+ score, summarize, and compare those runs without inventing missing measurements.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import json
12
+ import math
13
+ import statistics
14
+ from pathlib import Path
15
+ from typing import Any, Iterable
16
+
17
+
18
+ REQUIRED_RESULT_FIELDS = {
19
+ "case_id",
20
+ "answer",
21
+ "tokens",
22
+ "tool_calls",
23
+ "latency_ms",
24
+ }
25
+
26
+ OPTIONAL_TELEMETRY_FIELDS = {
27
+ "branches_total",
28
+ "branches_distinct",
29
+ "revived_branches",
30
+ "recovered_errors",
31
+ "contradictions_found",
32
+ "contradictions_resolved",
33
+ }
34
+
35
+
36
+ def read_jsonl(path: Path) -> list[dict[str, Any]]:
37
+ rows: list[dict[str, Any]] = []
38
+ with path.open("r", encoding="utf-8") as handle:
39
+ for line_number, raw in enumerate(handle, start=1):
40
+ line = raw.strip()
41
+ if not line:
42
+ continue
43
+ try:
44
+ value = json.loads(line)
45
+ except json.JSONDecodeError as exc:
46
+ raise ValueError(f"{path}:{line_number}: invalid JSON: {exc}") from exc
47
+ if not isinstance(value, dict):
48
+ raise ValueError(f"{path}:{line_number}: row must be a JSON object")
49
+ rows.append(value)
50
+ return rows
51
+
52
+
53
+ def normalize_answer(value: Any) -> str:
54
+ return " ".join(str(value).strip().casefold().split())
55
+
56
+
57
+ def validate_case(case: dict[str, Any]) -> None:
58
+ for field in ("id", "domain", "prompt", "accepted_answers"):
59
+ if field not in case:
60
+ raise ValueError(f"case missing required field: {field}")
61
+ if not isinstance(case["accepted_answers"], list) or not case["accepted_answers"]:
62
+ raise ValueError(f"case {case['id']!r}: accepted_answers must be a non-empty list")
63
+
64
+
65
+ def validate_result(result: dict[str, Any]) -> None:
66
+ missing = REQUIRED_RESULT_FIELDS - set(result)
67
+ if missing:
68
+ raise ValueError(
69
+ f"result {result.get('case_id', '<unknown>')!r} missing fields: "
70
+ + ", ".join(sorted(missing))
71
+ )
72
+ for field in ("tokens", "tool_calls", "latency_ms"):
73
+ value = result[field]
74
+ if not isinstance(value, (int, float)) or value < 0:
75
+ raise ValueError(f"result {result['case_id']!r}: {field} must be non-negative")
76
+ for field in OPTIONAL_TELEMETRY_FIELDS:
77
+ if field in result:
78
+ value = result[field]
79
+ if not isinstance(value, (int, float)) or value < 0:
80
+ raise ValueError(
81
+ f"result {result['case_id']!r}: {field} must be non-negative"
82
+ )
83
+ if "branches_distinct" in result and "branches_total" in result:
84
+ if result["branches_distinct"] > result["branches_total"]:
85
+ raise ValueError(
86
+ f"result {result['case_id']!r}: branches_distinct cannot exceed branches_total"
87
+ )
88
+ if "contradictions_resolved" in result and "contradictions_found" in result:
89
+ if result["contradictions_resolved"] > result["contradictions_found"]:
90
+ raise ValueError(
91
+ f"result {result['case_id']!r}: contradictions_resolved cannot exceed contradictions_found"
92
+ )
93
+
94
+
95
+ def answer_is_correct(case: dict[str, Any], answer: Any) -> bool:
96
+ normalized = normalize_answer(answer)
97
+ accepted = {normalize_answer(value) for value in case["accepted_answers"]}
98
+ return normalized in accepted
99
+
100
+
101
+ def safe_mean(values: Iterable[float]) -> float | None:
102
+ materialized = list(values)
103
+ if not materialized:
104
+ return None
105
+ return statistics.fmean(materialized)
106
+
107
+
108
+ def safe_ratio(numerator: float, denominator: float) -> float | None:
109
+ if denominator == 0:
110
+ return None
111
+ return numerator / denominator
112
+
113
+
114
+ def summarize(cases: list[dict[str, Any]], results: list[dict[str, Any]]) -> dict[str, Any]:
115
+ for case in cases:
116
+ validate_case(case)
117
+ for result in results:
118
+ validate_result(result)
119
+
120
+ case_by_id = {str(case["id"]): case for case in cases}
121
+ if len(case_by_id) != len(cases):
122
+ raise ValueError("case ids must be unique")
123
+
124
+ result_by_id: dict[str, dict[str, Any]] = {}
125
+ for result in results:
126
+ case_id = str(result["case_id"])
127
+ if case_id in result_by_id:
128
+ raise ValueError(f"duplicate result for case_id {case_id!r}")
129
+ if case_id not in case_by_id:
130
+ raise ValueError(f"result references unknown case_id {case_id!r}")
131
+ result_by_id[case_id] = result
132
+
133
+ missing_cases = sorted(set(case_by_id) - set(result_by_id))
134
+ evaluated = []
135
+ for case_id, result in result_by_id.items():
136
+ case = case_by_id[case_id]
137
+ evaluated.append((case, result, answer_is_correct(case, result["answer"])))
138
+
139
+ total = len(evaluated)
140
+ correct = sum(int(is_correct) for _, _, is_correct in evaluated)
141
+
142
+ branch_rows = [
143
+ result
144
+ for _, result, _ in evaluated
145
+ if "branches_total" in result and "branches_distinct" in result
146
+ ]
147
+ contradiction_rows = [
148
+ result
149
+ for _, result, _ in evaluated
150
+ if "contradictions_found" in result and "contradictions_resolved" in result
151
+ ]
152
+
153
+ total_branches = sum(row["branches_total"] for row in branch_rows)
154
+ distinct_branches = sum(row["branches_distinct"] for row in branch_rows)
155
+ contradictions_found = sum(row["contradictions_found"] for row in contradiction_rows)
156
+ contradictions_resolved = sum(
157
+ row["contradictions_resolved"] for row in contradiction_rows
158
+ )
159
+
160
+ return {
161
+ "cases_defined": len(cases),
162
+ "cases_evaluated": total,
163
+ "missing_case_ids": missing_cases,
164
+ "accuracy": safe_ratio(correct, total),
165
+ "mean_tokens": safe_mean(float(result["tokens"]) for _, result, _ in evaluated),
166
+ "mean_tool_calls": safe_mean(
167
+ float(result["tool_calls"]) for _, result, _ in evaluated
168
+ ),
169
+ "mean_latency_ms": safe_mean(
170
+ float(result["latency_ms"]) for _, result, _ in evaluated
171
+ ),
172
+ "branch_diversity_ratio": safe_ratio(distinct_branches, total_branches),
173
+ "revival_rate_per_case": safe_mean(
174
+ float(result.get("revived_branches", 0)) for _, result, _ in evaluated
175
+ ),
176
+ "error_recovery_rate_per_case": safe_mean(
177
+ float(result.get("recovered_errors", 0)) for _, result, _ in evaluated
178
+ ),
179
+ "contradiction_resolution_rate": safe_ratio(
180
+ contradictions_resolved, contradictions_found
181
+ ),
182
+ }
183
+
184
+
185
+ def percent_change(new: float | None, old: float | None) -> float | None:
186
+ if new is None or old is None or old == 0:
187
+ return None
188
+ return ((new - old) / old) * 100.0
189
+
190
+
191
+ def absolute_change(new: float | None, old: float | None) -> float | None:
192
+ if new is None or old is None:
193
+ return None
194
+ return new - old
195
+
196
+
197
+ def compare(baseline: dict[str, Any], skill: dict[str, Any]) -> dict[str, Any]:
198
+ return {
199
+ "accuracy_delta": absolute_change(skill["accuracy"], baseline["accuracy"]),
200
+ "tokens_percent_change": percent_change(
201
+ skill["mean_tokens"], baseline["mean_tokens"]
202
+ ),
203
+ "tool_calls_percent_change": percent_change(
204
+ skill["mean_tool_calls"], baseline["mean_tool_calls"]
205
+ ),
206
+ "latency_percent_change": percent_change(
207
+ skill["mean_latency_ms"], baseline["mean_latency_ms"]
208
+ ),
209
+ "branch_diversity_delta": absolute_change(
210
+ skill["branch_diversity_ratio"], baseline["branch_diversity_ratio"]
211
+ ),
212
+ "contradiction_resolution_delta": absolute_change(
213
+ skill["contradiction_resolution_rate"],
214
+ baseline["contradiction_resolution_rate"],
215
+ ),
216
+ }
217
+
218
+
219
+ def ensure_finite(value: Any, label: str) -> None:
220
+ if isinstance(value, float) and not math.isfinite(value):
221
+ raise ValueError(f"{label} is not finite")
222
+
223
+
224
+ def main() -> int:
225
+ parser = argparse.ArgumentParser()
226
+ parser.add_argument("--cases", type=Path, required=True)
227
+ parser.add_argument("--skill", type=Path, required=True)
228
+ parser.add_argument("--baseline", type=Path)
229
+ parser.add_argument("--output", type=Path)
230
+ args = parser.parse_args()
231
+
232
+ cases = read_jsonl(args.cases)
233
+ skill_results = read_jsonl(args.skill)
234
+ skill_summary = summarize(cases, skill_results)
235
+
236
+ payload: dict[str, Any] = {"skill": skill_summary}
237
+ if args.baseline:
238
+ baseline_results = read_jsonl(args.baseline)
239
+ baseline_summary = summarize(cases, baseline_results)
240
+ payload["baseline"] = baseline_summary
241
+ payload["comparison"] = compare(baseline_summary, skill_summary)
242
+
243
+ for section_name, section in payload.items():
244
+ if isinstance(section, dict):
245
+ for key, value in section.items():
246
+ ensure_finite(value, f"{section_name}.{key}")
247
+
248
+ rendered = json.dumps(payload, indent=2, sort_keys=True)
249
+ print(rendered)
250
+ if args.output:
251
+ args.output.parent.mkdir(parents=True, exist_ok=True)
252
+ args.output.write_text(rendered + "\n", encoding="utf-8")
253
+ return 0
254
+
255
+
256
+ if __name__ == "__main__":
257
+ raise SystemExit(main())
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/Furox-Art/quantum-reasoning-skill/blob/main/benchmark/schemas/case.schema.json",
4
+ "title": "Quantum Reasoning benchmark case",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": ["id", "domain", "prompt", "accepted_answers"],
8
+ "properties": {
9
+ "id": {"type": "string", "minLength": 1},
10
+ "domain": {"type": "string", "minLength": 1},
11
+ "prompt": {"type": "string", "minLength": 1},
12
+ "accepted_answers": {
13
+ "type": "array",
14
+ "minItems": 1,
15
+ "items": {}
16
+ },
17
+ "source": {"type": ["string", "null"]},
18
+ "license": {"type": ["string", "null"]}
19
+ }
20
+ }
@@ -0,0 +1,64 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/Furox-Art/quantum-reasoning-skill/blob/main/benchmark/schemas/comparison.schema.json",
4
+ "title": "Quantum Reasoning benchmark comparison output",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": ["baseline", "skill", "comparison"],
8
+ "properties": {
9
+ "baseline": {"$ref": "#/$defs/summary"},
10
+ "skill": {"$ref": "#/$defs/summary"},
11
+ "comparison": {
12
+ "type": "object",
13
+ "additionalProperties": false,
14
+ "required": [
15
+ "accuracy_delta",
16
+ "tokens_percent_change",
17
+ "tool_calls_percent_change",
18
+ "latency_percent_change",
19
+ "branch_diversity_delta",
20
+ "contradiction_resolution_delta"
21
+ ],
22
+ "properties": {
23
+ "accuracy_delta": {"type": ["number", "null"]},
24
+ "tokens_percent_change": {"type": ["number", "null"]},
25
+ "tool_calls_percent_change": {"type": ["number", "null"]},
26
+ "latency_percent_change": {"type": ["number", "null"]},
27
+ "branch_diversity_delta": {"type": ["number", "null"]},
28
+ "contradiction_resolution_delta": {"type": ["number", "null"]}
29
+ }
30
+ }
31
+ },
32
+ "$defs": {
33
+ "summary": {
34
+ "type": "object",
35
+ "additionalProperties": false,
36
+ "required": [
37
+ "cases_defined",
38
+ "cases_evaluated",
39
+ "missing_case_ids",
40
+ "accuracy",
41
+ "mean_tokens",
42
+ "mean_tool_calls",
43
+ "mean_latency_ms",
44
+ "branch_diversity_ratio",
45
+ "revival_rate_per_case",
46
+ "error_recovery_rate_per_case",
47
+ "contradiction_resolution_rate"
48
+ ],
49
+ "properties": {
50
+ "cases_defined": {"type": "integer", "minimum": 0},
51
+ "cases_evaluated": {"type": "integer", "minimum": 0},
52
+ "missing_case_ids": {"type": "array", "items": {"type": "string"}},
53
+ "accuracy": {"type": ["number", "null"]},
54
+ "mean_tokens": {"type": ["number", "null"]},
55
+ "mean_tool_calls": {"type": ["number", "null"]},
56
+ "mean_latency_ms": {"type": ["number", "null"]},
57
+ "branch_diversity_ratio": {"type": ["number", "null"]},
58
+ "revival_rate_per_case": {"type": ["number", "null"]},
59
+ "error_recovery_rate_per_case": {"type": ["number", "null"]},
60
+ "contradiction_resolution_rate": {"type": ["number", "null"]}
61
+ }
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/Furox-Art/quantum-reasoning-skill/blob/main/benchmark/schemas/metadata.schema.json",
4
+ "title": "Quantum Reasoning community benchmark metadata",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": [
8
+ "provider",
9
+ "model",
10
+ "run_date",
11
+ "skill_version",
12
+ "repetitions_per_case",
13
+ "baseline",
14
+ "skill",
15
+ "failures_recorded"
16
+ ],
17
+ "properties": {
18
+ "provider": {"type": "string", "minLength": 1},
19
+ "model": {"type": "string", "minLength": 1},
20
+ "model_version": {"type": ["string", "null"]},
21
+ "run_date": {"type": "string", "format": "date"},
22
+ "skill_version": {"type": "string", "minLength": 1},
23
+ "skill_commit": {"type": ["string", "null"]},
24
+ "cases_source": {"type": ["string", "null"]},
25
+ "repetitions_per_case": {"type": "integer", "minimum": 1},
26
+ "random_seed": {"type": ["integer", "string", "null"]},
27
+ "hardware_runtime": {"type": ["string", "null"]},
28
+ "failures_recorded": {"const": true},
29
+ "baseline": {"$ref": "#/$defs/condition"},
30
+ "skill": {"$ref": "#/$defs/condition"},
31
+ "notes": {"type": ["string", "null"]}
32
+ },
33
+ "$defs": {
34
+ "condition": {
35
+ "type": "object",
36
+ "additionalProperties": true,
37
+ "required": [
38
+ "instruction_config",
39
+ "sampling",
40
+ "tool_availability",
41
+ "context_limit",
42
+ "output_limit"
43
+ ],
44
+ "properties": {
45
+ "instruction_config": {"type": "string", "minLength": 1},
46
+ "sampling": {"type": "object"},
47
+ "tool_availability": {"type": ["array", "object", "string"]},
48
+ "context_limit": {"type": ["integer", "null"], "minimum": 1},
49
+ "output_limit": {"type": ["integer", "null"], "minimum": 1}
50
+ }
51
+ }
52
+ }
53
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/Furox-Art/quantum-reasoning-skill/blob/main/benchmark/schemas/result.schema.json",
4
+ "title": "Quantum Reasoning benchmark result row",
5
+ "type": "object",
6
+ "additionalProperties": true,
7
+ "required": ["case_id", "answer", "tokens", "tool_calls", "latency_ms"],
8
+ "properties": {
9
+ "case_id": {"type": "string", "minLength": 1},
10
+ "answer": {},
11
+ "tokens": {"type": "number", "minimum": 0},
12
+ "tool_calls": {"type": "number", "minimum": 0},
13
+ "latency_ms": {"type": "number", "minimum": 0},
14
+ "status": {
15
+ "type": "string",
16
+ "enum": ["ok", "refusal", "timeout", "error"]
17
+ },
18
+ "branches_total": {"type": "number", "minimum": 0},
19
+ "branches_distinct": {"type": "number", "minimum": 0},
20
+ "revived_branches": {"type": "number", "minimum": 0},
21
+ "recovered_errors": {"type": "number", "minimum": 0},
22
+ "contradictions_found": {"type": "number", "minimum": 0},
23
+ "contradictions_resolved": {"type": "number", "minimum": 0}
24
+ }
25
+ }
@@ -0,0 +1,114 @@
1
+ """Validate reproducible community benchmark result bundles."""
2
+ from __future__ import annotations
3
+ import argparse, json, re
4
+ from datetime import date
5
+ from pathlib import Path
6
+ import evaluate
7
+
8
+ REQUIRED_FILES = {"metadata.json", "cases.jsonl", "baseline.jsonl", "skill.jsonl", "comparison.json", "README.md"}
9
+ COND_FIELDS = {"instruction_config", "sampling", "tool_availability", "context_limit", "output_limit"}
10
+ META_FIELDS = {"provider", "model", "run_date", "skill_version", "repetitions_per_case", "baseline", "skill", "failures_recorded"}
11
+
12
+
13
+ def load_json(path: Path):
14
+ try:
15
+ return json.loads(path.read_text(encoding="utf-8"))
16
+ except (OSError, json.JSONDecodeError) as exc:
17
+ raise ValueError(f"{path}: invalid JSON: {exc}") from exc
18
+
19
+
20
+ def validate_metadata(meta: dict) -> None:
21
+ if not isinstance(meta, dict):
22
+ raise ValueError("metadata.json must contain a JSON object")
23
+ missing = META_FIELDS - set(meta)
24
+ if missing:
25
+ raise ValueError(f"metadata.json missing fields: {sorted(missing)}")
26
+ for key in ("provider", "model", "skill_version"):
27
+ if not isinstance(meta[key], str) or not meta[key].strip():
28
+ raise ValueError(f"metadata.{key} must be a non-empty string")
29
+ try:
30
+ date.fromisoformat(meta["run_date"])
31
+ except Exception as exc:
32
+ raise ValueError("metadata.run_date must be YYYY-MM-DD") from exc
33
+ if not isinstance(meta["repetitions_per_case"], int) or meta["repetitions_per_case"] < 1:
34
+ raise ValueError("metadata.repetitions_per_case must be >= 1")
35
+ if meta["failures_recorded"] is not True:
36
+ raise ValueError("metadata.failures_recorded must be true")
37
+ for name in ("baseline", "skill"):
38
+ value = meta[name]
39
+ if not isinstance(value, dict):
40
+ raise ValueError(f"metadata.{name} must be an object")
41
+ missing_cond = COND_FIELDS - set(value)
42
+ if missing_cond:
43
+ raise ValueError(f"metadata.{name} missing fields: {sorted(missing_cond)}")
44
+ if not isinstance(value["instruction_config"], str) or not value["instruction_config"].strip():
45
+ raise ValueError(f"metadata.{name}.instruction_config must be non-empty")
46
+ if not isinstance(value["sampling"], dict):
47
+ raise ValueError(f"metadata.{name}.sampling must be an object")
48
+ for limit in ("context_limit", "output_limit"):
49
+ v = value[limit]
50
+ if v is not None and (not isinstance(v, int) or v < 1):
51
+ raise ValueError(f"metadata.{name}.{limit} must be null or >= 1")
52
+
53
+
54
+ def _case_map(cases):
55
+ out = {}
56
+ for case in cases:
57
+ evaluate.validate_case(case)
58
+ cid = str(case["id"])
59
+ if cid in out:
60
+ raise ValueError(f"duplicate case id: {cid}")
61
+ out[cid] = case
62
+ return out
63
+
64
+
65
+ def validate_bundle(bundle: Path) -> None:
66
+ missing = REQUIRED_FILES - {p.name for p in bundle.iterdir() if p.is_file()}
67
+ if missing:
68
+ raise ValueError(f"{bundle}: missing files: {sorted(missing)}")
69
+ validate_metadata(load_json(bundle / "metadata.json"))
70
+ cases = evaluate.read_jsonl(bundle / "cases.jsonl")
71
+ case_by_id = _case_map(cases)
72
+ baseline = evaluate.read_jsonl(bundle / "baseline.jsonl")
73
+ skill = evaluate.read_jsonl(bundle / "skill.jsonl")
74
+ for row in baseline + skill:
75
+ evaluate.validate_result(row)
76
+ for label, rows in (("baseline", baseline), ("skill", skill)):
77
+ ids = [str(r["case_id"]) for r in rows]
78
+ if len(ids) != len(set(ids)):
79
+ raise ValueError(f"{bundle}: duplicate {label} case_id")
80
+ if set(ids) != set(case_by_id):
81
+ raise ValueError(f"{bundle}: {label} must contain exactly one row for every case")
82
+ expected = {
83
+ "skill": evaluate.summarize(cases, skill),
84
+ "baseline": evaluate.summarize(cases, baseline),
85
+ }
86
+ expected["comparison"] = evaluate.compare(expected["baseline"], expected["skill"])
87
+ submitted = load_json(bundle / "comparison.json")
88
+ if submitted != expected:
89
+ raise ValueError(f"{bundle}: comparison.json does not match evaluator recomputation")
90
+ if not (bundle / "README.md").read_text(encoding="utf-8").strip():
91
+ raise ValueError(f"{bundle}: README.md must not be empty")
92
+
93
+
94
+ def main() -> int:
95
+ parser = argparse.ArgumentParser()
96
+ parser.add_argument("--root", type=Path, default=Path("benchmark/results/community"))
97
+ parser.add_argument("--allow-empty", action="store_true")
98
+ args = parser.parse_args()
99
+ root = args.root
100
+ if not root.exists():
101
+ if args.allow_empty:
102
+ return 0
103
+ raise SystemExit(f"community benchmark root not found: {root}")
104
+ bundles = sorted(p for p in root.iterdir() if p.is_dir())
105
+ if not bundles and not args.allow_empty:
106
+ raise SystemExit("no community benchmark bundles found")
107
+ for bundle in bundles:
108
+ validate_bundle(bundle)
109
+ print(f"validated {bundle}")
110
+ return 0
111
+
112
+
113
+ if __name__ == "__main__":
114
+ raise SystemExit(main())
@@ -0,0 +1,44 @@
1
+ # Host compatibility
2
+
3
+ Quantum Reasoning is model-agnostic, but not every host exposes the same controls. Compatibility is therefore defined by capabilities rather than by provider branding.
4
+
5
+ ## Compatibility levels
6
+
7
+ | Level | Required capabilities | What works |
8
+ | --- | --- | --- |
9
+ | Protocol-only | Host can persist or inject `SKILL.md` instructions | Multi-branch protocol, falsification rules, stopping/collapse policy |
10
+ | Measurable | Protocol-only plus aggregate run telemetry | Benchmark result schema, diversity/revival/contradiction measurements |
11
+ | Controller-assisted | Measurable plus a host-side loop that can call `reference/branch_controller.py` or equivalent logic | Deterministic scoring, state transitions, uncertainty-based width and collapse checks |
12
+
13
+ A host is incompatible only when it cannot reliably apply the skill instructions, truncates/replaces them in a way that changes the protocol, or prevents the requested task/tool access.
14
+
15
+ ## Required host contract
16
+
17
+ A compatible integration should preserve these invariants:
18
+
19
+ 1. `SKILL.md` is supplied as a persistent system/developer/skill instruction, not as untrusted task content.
20
+ 2. The same task constraints and tool permissions apply to all candidate branches.
21
+ 3. Tool observations are treated as evidence and are not fabricated.
22
+ 4. Private chain-of-thought is not required or stored. Only aggregate control-plane telemetry may be emitted.
23
+ 5. If numeric branch telemetry is unavailable, the host follows the qualitative protocol and omits unavailable measurements rather than inventing them.
24
+ 6. Baseline-vs-skill benchmarks keep the model/version, tools, sampling and budget policy fixed.
25
+
26
+ ## Integration patterns
27
+
28
+ ### 1. Native skill directory
29
+
30
+ If a host supports a skill/plugin directory, install the repository so that `SKILL.md` is the skill entry point and keep its YAML front matter intact.
31
+
32
+ ### 2. Persistent instruction wrapper
33
+
34
+ If the host has no native skill format, load the contents of `SKILL.md` into the persistent system/developer instruction layer before the user task. Do not prepend it to benchmark prompts only in the skill condition unless the baseline wrapper is otherwise identical.
35
+
36
+ ### 3. Controller-assisted agent
37
+
38
+ A host with an explicit agent loop can map observable aggregate branch measurements to `BranchMetrics` and use `reference/branch_controller.py` for ranking, state changes and collapse decisions. The reference controller does not generate hidden reasoning or call an LLM.
39
+
40
+ See [`../examples/host-integration.md`](../examples/host-integration.md) for concrete generic examples.
41
+
42
+ ## Provider/model claims
43
+
44
+ This repository intentionally does not label specific commercial models as "supported" without a reproducible third-party run. Community results may document a provider/model combination under `benchmark/results/community/`, but those results are measurements from the submitter, not a permanent compatibility guarantee.