Status: design record (planning). Author: SPARQ synthesis stage. Do not treat any "sound/proven"
label herein as achieved until the external cryptographer audit (sq-qhy4) clears.
This plan is written for Claude Fable — an expensive, stronger model coming online for sparq — and for the cheap fleet (Opus 4.8 / Sonnet 4.6 / Haiku 4.5) that works under its direction. It is deliberately opinionated about where Fable is NOT allowed to spend tokens.
Opus 4.8 has already shipped the breadth: six reasoners on a CI-enforced zero-overhead substrate, SERVICE federation, an SSRF egress perimeter, four W3C/OGC conformance lanes, SHACL 1.2, a dark-first GUI, and a large ZK/MPC/trust-graph/PKG estate. What remains is a small residue of soundness-critical, novel-design, and model-capability-gated work that a cheaper model would get wrong in ways worse than not doing it at all. That residue — and only that residue — is Fable's job.
CORE DOCTRINE (token-efficiency operating model). Fable is a scarce high-IQ resource whose tokens buy exactly four things: (1) decomposition of hard epics into disjoint, crisply-spec'd child beads with acceptance tests; (2) subtle-correctness and soundness design (crypto circuits, protocol composition, reasoner semantics, estimator/cost-model math, XSD boundary calls); (3) novel research judgment (the revisit-with-Fable model-dependent verdicts); and (4) final verdicts on the escalated subset of PRs. Everything else is delegated — broad recon, disjoint implementation, mechanical verification, doc-sync, benchmarking — to the cheap fleet under Fable's written spec. The operating rule is: Fable writes the spec and the proof; the fleet writes the code and runs the measurement — by default. Fable's default posture is architect/reviewer, but Fable may elect to implement a bead itself when the review/verify signal shows the cheap fleet cannot (repeated mechanical-verify failures on that bead) OR the code is soundness-critical enough to need Fable-grade authorship. That election is Fable's own decision, made from the review — not a fixed prohibition. Crucially, when Fable implements it does so in a scoped, isolated worktree sub-task with a minimal brief — NEVER inline on the orchestration thread — so authorship never bloats the scarce main-thread context (§8). One Fable call per epic amortises across N cheap implementers; one Fable verdict clears a PR that would otherwise wait on the human. If Fable is reading a whole file to answer a fact, or writing a kernel body it did not consciously elect to author from the review signal, or re-running a settled negative — the doctrine is being violated.
HONESTY (binding). This repo mandates empirical honesty and soundness-first. Prior negative
verdicts (terse tokens, neurosymbolic KB) died on proxy-vs-real-token artifacts — every
measurement below specifies real cache-discounted transcript tokens (message.usage,
1.0·input + 0.1·cache_read + 1.25·cache_creation; no count_tokens, no char proxy), N≥30,
deterministic/blinded quality grading, and a pre-registered kill-criterion. Extensions are never
folded into standards totals. Conformance is never faked. A wrong "completeness/sound" claim is worse
than a null.
| Layer | Model | Responsibility | Token posture |
|---|---|---|---|
| Recon | Haiku (sparq-pkg-nl, query-pkg, ast-grep, Explore) |
Ground each spec against current code; enumerate call sites/fields; assemble evidence packs | Cheap, high-volume |
| Bulk impl | Sonnet (sparq-rust-impl*) |
Implement disjoint, de-risked, single-crate beads against a Fable spec + failing test | Cheap bulk |
| Hard impl | Opus (sparq-rust-feature, sparq-site, sparq-ci-infra) |
Genuinely-hard implementation, frontend, CI/supply-chain | Mid |
| Mechanical verify | Haiku (sparq-verify-mechanical*) |
Objective checklist: gates green in both feature states, tests non-vacuous, opt-in respected, README/SKILL synced, no hardcoded perf; arms clean low-risk PRs, escalates the rest | Cheap |
| Architect (front) | Fable (sparq-architect*) |
Decompose epic → design record + N disjoint spec'd child beads {crate, model_tier, invariant, acceptance_test} | Scarce; ~1 call/epic |
| Reviewer (verdict) | Fable (sparq-reviewer*) |
Per-PR verdict {honest, sound_as_scoped, recommend_arm, concerns[]} on the escalated subset only |
Scarce; only escalated diffs |
| Escalate-to-implement | Fable (scoped worktree sub-task) | The rare escalation outcome: when the review signal shows the fleet cannot land a bead (repeated mechanical-verify failures) OR it is soundness-critical, Fable elects (disposition: fable_implements, §6.2) to author the fix itself in an isolated worktree, then re-enters mechanical-verify |
Scarce; rare, review-gated |
* = proposed agent (see §6). Fable appears at exactly two points: the front (decompose) and the
escalation target (verdict — plus the rare fable_implements outcome above). It never does recon
and never re-judges the clean PRs the mechanical tier already armed; it writes kernels only by its
own review-driven fable_implements election (§6.2), in an isolated worktree — never as a default and
never inline on the orchestration thread.
- Every producing stage returns a SCHEMA'd object. The schema-guard trap
(
feedback-workflow-agent-schema-guard): an unschema'd stage returns a string, so a downstreamif (r.pr_url)guard silently evals false and the dependent Fable-verdict stage is skipped with no error.autonomous-scheduler.jsalready does this viaIMPL_SCHEMA/VERDICT_SCHEMA; every new workflow must too. - Stable prefixes for cache reuse. Fable's system prompt + the shared contract are fixed; per-task
payload goes last so
cache_readdominates. Evidence packs are Haiku-assembled and diff-scoped so Fable reads only the changed lines + the relevant test + the one audit doc, never a whole file. - Batching. Verdict fan-outs (
fable-soundness-verdict) run one Fable call per PR over a Haiku-prepared pack — never a single mega-context of all PRs.
Arming iterates verdict objects, never a blanket loop over PR numbers keyed on CI
mergeStateStatus (feedback-arm-gate-on-verdict — a blanket loop once armed an honest=false PR).
A PR arms iff its own verdict has honest=true && recommend_arm=true; anything honest=false stays
held until the fix is confirmed landed on main. Fable holds only the genuinely external-audit-gated
(sq-qhy4) items; it gives the verdict the maintainer currently must give for everything else. The
verdict's disposition (§6.2: arm | request_changes | hold | fable_implements) drives the outcome:
arm on a clean recommend_arm=true; request_changes/hold bounce back to the fleet or the audit
gate; fable_implements is the rare escalation where Fable authors the fix itself in a scoped
isolated worktree, after which the normal mechanical-verify → arm path resumes.
A Fable/Sonnet research fan-out must use Explore/general-purpose or an explicit "findings only, no PR"
instruction — sparq-researcher opens its own research/ PR per fragment
(feedback-workflow-researcher-pr-gotcha). Reserve PR-opening for the single synthesis/architect stage.
The maintainer flagged the neurosymbolic-KB direction (#1111) as model-dependent. The honest finding: the five sub-directions are not equally model-gated. Rank by genuine Fable-leverage; every harness is confirmed present and re-runnable as a MODEL SWAP, not a rebuild.
| # | Experiment | Harness (real telemetry) | Fable role | Kill-criterion |
|---|---|---|---|---|
| A1 | FO-KM: schema.org ≫ gUFO — the flip candidate | bench/fo-km/{analyze.py,tasks.jsonl,overlays/*.ttl} + pkg-query --extra-graph <overlay> --close owl-rl; analyze.py miner over [FOKM arm=<fo> task=<id> model=<tier>] transcripts; paired schema.org−gUFO accuracy delta per model tier, Wilcoxon + bootstrap 95% CI, N≥30 TH/ER/CC |
Cheap fleet fills the Haiku→Sonnet→Opus rungs; Fable only the top arm (~1 arm × ≥30 tasks). Fable's IQ goes to the design judgment the run unlocks | gUFO "wins back" iff at the Fable rung it matches-or-beats schema.org at p<0.05, CI excludes 0, AND rich-FO-only structural queries now resolve. If flat across tiers → fluency-penalty is a law; stop |
| A2 | PKG-dogfood — the cheap NL-tool win (positive, strengthens) | bench/pkg-dogfood/{tokens_real.py,analyze3.py,tasks/abm_tasks.json}; real message.usage; $-weighted with Fable priced as orchestrator; N≥30 stratified + the 10+10 sq-4va4l boundary set as the soundness gate |
(1) cheap re-price to confirm the delegation $-win widens (no Fable reasoning). (2) Fable re-curates the PKG (crates/sparq-kb findings, calibrate pkg:confidence, tighten provenance) → measure whether the abstain set shrinks |
Answerable-set may grow only if off-PKG stratum stays 1.0 abstain-precision (0 hallucinations). Any hallucination on the negative stratum → revert curation |
| A3 | Provenance-driven extraction fidelity | bench/pkg-dogfood token-A/B re-used end-to-end; extraction graded by a deterministic grounding-resolver (citation-grounding rate, justification-entailment rate, sampled audit precision), N≥30 papers, paired Fable-directed vs Haiku-bulk |
Fixture-only A/B (no live access): does Fable-tier extraction earn a higher trust tier than the secx:Conjectured ceiling cheap extraction forces? |
Adopt a higher tier only if grounding+entailment clear a pre-registered bar with 0 mis-cites on audit sample; else keep secx:Conjectured |
| A4 | terse (K:/V()) — token axis DEAD BY ARITHMETIC | — | Do NOT re-measure the token axis. The ~14k session floor dominates for any model; Fable's larger prompt makes the floor more dominant. Bank the negative | N/A — pre-declared dead. Only the URI-hiding accuracy sub-lever (A4′) is re-runnable |
| A4′ | URI-hiding accuracy (opaque-id rescue) | the existing blinded N=35 A/B (opaque-id / informative-slug / null-control strata, deterministic answer-set grading), Fable as the answering model | cheap fleet builds fixtures; Fable only answers | If the hidden−raw delta on the opaque-id stratum regresses toward the informative-slug Δ≈0 → drop URI-hiding for strong models |
| A5 | ast-grep / compacted-AST self-ergonomics | passive: bench/ast-compact/mine.py + the RESULTS-astgrep.md method applied to Fable's own [task/tool-usage]-tagged working sessions |
Passively mine, do not commission a dedicated fan-out. Keep the AGENTS.md rule (scoped lookup→Read; whole-file/codemod→compacted skeleton) until data moves | Act only if the passive signal is large and decision-relevant |
Ordering for Fable time: A1 (FO-KM ladder) → A2 (PKG re-curation + abstain boundary) → A3
(extraction-fidelity fixture A/B) → [maintainer-unblocked live trawl + EC2 KGE] → A4′ (cheap) →
A5 (passive). The compute-gated companions — FO-KM Metric-2 KGE (crates/sparq-vectors/src/eval.rs,
gufo_prior currently a no-op stub asserted at eval.rs:1404) and provenance Phase-4 weighted
KGE — are EC2-gated: Fable directs, the fleet + a self-terminating box executes, adopt only on
pre-registered lift, abandon honestly if null (the literature reports inconsistent KGE lift).
Ordered by Fable-leverage. "Fable does" = the design/proof only; "Fleet does" = everything mechanical.
| Bead / epic | Feature | Fable does | Fleet does | Effort |
|---|---|---|---|---|
sq-rsd3v (+.1,.2) |
ZK inference + credentials: in-circuit derivation_step, single-use nullifier, N3 witnessed-rule-shape, unlinkable presentation. Verified absent by grep — today ships a host-side structural re-check with zero antecedent privacy |
Design the Poseidon2-domain-separated nullifier + the sound in-circuit RDFS derivation relation (variable-sharing equalities + set-membership anchoring); write the soundness argument | bb gates regressions, forge-and-verify tests |
XL |
sq-qhy4 (audit gate) |
Noir circuit under-constraint + commitment domain-separation de-risk (does NOT replace the human audit) | Adversarial constraint-satisfaction: construct a candidate malicious witness / colliding leaf for each zk/compose/*/main.nr; probe flat-Poseidon2 length-IV cross-method / cross-position(S/P/O) / dual-leaf collisions |
Extract every main.nr public-input signature; build the circuit↔reconstruct_public_inputs (verifier.rs:4786) cross-ref table |
XL |
| (none) | ZK verifier bind_* composition — can any single obligation be satisfied while the aggregate statement is false? (attribution-bit off-by-one at verifier.rs:3981, hidden-revocation index binding, holder-PoP field-0 ordering) |
Hold all ~13 bind_* obligations simultaneously; search for a satisfying-but-false manifest |
Enumerate prover-supplied vs external-anchored vs byte-bound manifest fields | L |
sq-tu4e |
Trust-graph conflict semantics — is conflicting-issuer deny-on-disagreement even expressible under input-only stratified NAF? (a silent-security-hole question). NOT credential-gated | Decide which conflict semantics are expressible in the shipped stratified-NAF engine (incremental.rs:2130 rejects NAF over derived predicates) vs need an engine extension; termination analysis over external-graph extents |
Wire whichever admission rules Fable proves reachable | L |
sq-wvne |
Trust-graph unlinkability — ZKAPs-grade 3-part composite (hidden-issuer + ZK holder-PoP + nullifier); clear-WebID binding is in tension with anonymity | Design the composition that replaces clear-WebID holder binding with in-ZK holder-PoP + single-use nullifier while preserving unlinkability | Wire the composite once specified | L |
sq-0jsc (+sq-aaop,sq-wj4k,sq-km34.*,sq-yyro) |
Malicious-MPC — UC/composition proofs, IT-MAC authenticated abort, dealer-less VSS/PRSS | Justify why secure_equal opening a value mid-pipeline composes (naive sequential composition does NOT); reconcile the coZK 2025/1026 inconsistent-extended-witness leak; batched MAC-check RLC soundness + selective-failure/abort leakage |
Transport/instrumentation plumbing; adversarial_tests.rs |
XL |
sq-0dksu (+sq-nrwqs,sq-dz10l) |
Security-properties ontology for ZK/MPC proof-admissibility (5/8 built) | The maintainer-requested critical evaluation of next steps + assurance-tier semantics (#1001) + DPV-alignment depth (#1002); cross-estate coupling to sq-0jsc/sq-1s2.5 |
sq-nrwqs resolve annotation graph from bundled secprop-methods.ttl; sq-dz10l per-method MPC annotations |
M |
| Bead | Feature | Fable does | Fleet does | Effort |
|---|---|---|---|---|
sq-bn2t8 |
OWL 2 QL query-rewriting (PerfectRef/combined) — the last reasoning-profile gap; production tree-witness (treewitness.rs) + NP-complete UCQ-minimisation (minimise.rs) with two silent-answer-loss traps |
Spec the strict CQ-shape gate that REJECTS non-CQ shapes (never silently loses answers) + sound UCQ minimisation + certain-answer proof; hand-check the DL-Lite oracle extension | Build the rewrite plumbing (perfectref.rs) + engine seam + entailment conformance harness |
XL |
| (none) | OWL 2 Direct/DL (hyper)tableau — 66 direct-semantics cases permanently OutOfScope; undecidable in full; no Rust hypertableau exists (research/reasoner-suite-on-substrate.md §2.6) |
Decide whether a scoped, honestly-labelled EL++-toward-DL or a genuine tableau track is worth it; prove the soundness envelope; specify the fragment + external-audit gate | Classifier/normalisation plumbing once semantics pinned | XL |
| (none) | Datalog/existential regime (chase + stratified negation + aggregates — the Nemo/VLog/RDFox tier, research/inference-sota.md §1.3-1.4) |
Prove the hard parts: chase-termination (acyclicity classes), well-founded/stratified-negation soundness, aggregate stratification | Rule engine + expressivity ratchet | XL |
sq-rhspl (steering; linked #1307 — see note) |
beyond-RL sound boundary — 13 OWL-RL divergences are provably outside RL; some (differentFrom contrapositives) are sound RDF-Based entailments RL omits for polynomiality | Per-rule soundness + termination proof; maintainer steer on the polynomiality trade | Small code once each rule is proven | M |
Bead-id note (corrected 2026-07-01). The beyond-RL steering work is already tracked by the OPEN bead
sq-rhspl(P3, DESIGN-FIRST + MAINTAINER-STEER, linked to #1307); the ceiling-hardening beadsq-350msis CLOSED (via #1308). An earlier draft of this note wrongly called these ids "absent" — that was an artifact of grepping the stale committed.beads/issues.jsonlsnapshot (which lags the live Dolt DB by ~1000+ issues) instead ofbd show. Both exist. Do NOT implement the beyond-RL extension without the maintainer's steer.
| Bead | Feature | Split |
|---|---|---|
sq-dnko (epic) + sq-a35t/sq-vf7q/sq-7s4z |
Cost-based source selection, ANAPSID-style non-blocking streaming joins w/ spill, live adaptive re-planning | Fable-gated design cluster (shares the local estimator/cost-model of §5-perf). Two documented service Skips + sq-sjkj brTPF pushdown = mechanical fleet |
The substrate kernels (sparq-substrate, monomorphic, gate-enforced) are near-optimal — do NOT
re-plan them. The wins are the model/estimator/cost-gate layers Opus deliberately deferred.
| Bead | Feature | Fable does | Fleet does | Effort |
|---|---|---|---|---|
sq-hvfe (first block only; no bead for wiring) |
Vector-at-a-time engine (M4) — chunk.rs DataChunk + kernels are BUILT behind opt-in vectorized but unreferenced in exec.rs (still 100% row-materialising) |
Design the morsel-driven scan→filter→merge-join→count pipeline, selection-vector propagation, VOILA order-free operator spec, row/columnar coexistence, and the invariant keeping wasm-simd128 autovectorisation + bit-identical bundle when OFF | Kernel bodies + wiring; EXPLAIN cost categories | XL |
| (none; research §A5) | Cardinality estimation — Index-Based Join Sampling + never-underestimate guard. Current goo_pick/pattern_var_ndv (exec.rs ~4749/4804) is a pure independence product, wrong by orders of magnitude on correlated joins |
Design the fixed-budget index-probe sampler over the six permutations + a SafeBound/LpBound guard (order-only, never changes results) | Fold into GOO scoring; q-error A/B (EC2-gated) | L |
| (none) | DPccp/DPhyp join ordering — there is NO DP enumerator anywhere (greedy GOO only); docs falsely claim "GOO/DPccp" | Design DPccp (connected-subgraph enumeration) with a pattern-count fallback threshold; seed cost from the sampler; fix the doc/comment honesty | Enumerator body | L |
sq-6i40 (redesign, open); sq-p6p6 (closed, superseded); sq-0g6g (EC2 gate) |
Adaptive re-optimization — the divergence-triggered arm-swap failed once (no local win); prior-negative = Fable-worthy | Design a mid-query checkpoint using observed intermediate cardinalities (free, since every intermediate materialises) to re-order / switch strategy / trigger reducers | Wire it; perf validation EC2-gated | L |
sq-0g6g (EC2 gate); features yannakakis,semijoin-bitmap exist |
Adaptive reducer dispatch — two proven-correct reducers sit dormant behind static flags + a constant gate (YANNAKAKIS_MIN_REL=4096) purely because the default-flip needs EC2 sign-off |
Replace the static gate with a runtime adaptive cost model that self-guards against the pure-overhead case → unlocks them without the EC2 default-flip. Keep a native-adaptive / wasm-opt-in split | Wiring; watch wasm_bundle_bytes floor |
M |
| (none) | WCOJ/LFTJ — build_trie (exec.rs ~4850) heap-allocs one Vec<Id> per tuple then re-sorts a already-sorted index; wcoj_global_order (~4978) ignores AGM fractional-edge-cover |
Design the permutation→column-order mapping (non-trivial) + AGM/min-width variable ordering | Make TrieIter navigate the sorted slice directly; branchless intersection |
M each |
| (none; research §A2) | FastLanes/Elias-Fano compressed-column decode (sq-96hp1 impl is mechanical) |
Codec choice (storage-format judgement) | Scalar decode kernel proven to autovectorise x86/ARM/wasm; codec A/B EC2-gated | L |
Delegate entirely unless flagged. JSON-LD result-format wiring (sq-oy1f.15/.20/.3,
sq-oy1f.21/.22, sq-gcs5q), GeoSPARQL geodesic distance + GML tessellation (sq-47vu), RSP
window gaps, full-text analyzers, RDF/XML ratchet (sq-koshe), SHACL long-tail
(sq-11a/sq-uz0/sq-8ro/sq-jvn/sq-4ng/sq-ou3, sq-1jemy), GUI stubs + wasm-portability spike
(sq-zeai, sq-ixc3, sq-tp1m, sq-lyp8, sq-2mke), website content-reduction
(sq-vw3ax.6/.8/.9/.10), and doc-currency reconciliation (sq-6gob stale
"SERVICE not implemented"; sq-oy1f.4 mislabelled blocked) — all fleet. SPARQL 1.1/1.2
conformance is at its honest ceiling (1225 pass + 4 proven expected-file divergences = 100%) — do
NOT re-plan it; just file the 4 upstream rdf-tests issues via the fleet.
A standing, cadenced review with a reusable workflow. Fable reviews only what a cheap model cannot adjudicate; the mechanical enumeration that feeds each review is Haiku/Sonnet work.
| Lens | Real targets (files/crates) | What Fable adjudicates | Cadence |
|---|---|---|---|
| Security — crypto core | crates/sparq-zk-compose/src/verifier.rs, crates/sparq-zk/src/{commit,poseidon2,dual_leaf,encode,sig}.rs, crates/sparq-mpc/src/{authenticated,robust,oblivious_join,hidden_path,hidden_distinct}.rs |
Circuit under-constraint, commitment domain-separation, bind_* composition, MPC abort/leakage (see §4 B-tier 1) |
Per ZK/MPC PR + a monthly deep pass |
| Security — perimeter | crates/sparq-engine/src/service.rs, crates/sparq-fedclient/src/{source,discovery}.rs, crates/sparq-server/src/http.rs |
Fleet, not Fable. env-proxy SSRF bypass (ureq default proxy: try_from_env(), no .proxy(None) at service.rs:1393/source.rs:667/discovery.rs:675), redirect re-vet test, is_forbidden_ip embedded-v4 completeness, forwarded-WebID deployment note. Fable adjudicates only the vetted-proxy-support policy (one line) |
Fleet sweep; Fable one-line policy call |
| Memory-safety | crates/sparq-core/src/{dict,store,lib,dictspill}.rs, compliance/memsafety/unsafe-register.md |
The MappedDict::validate completeness invariant — does every unchecked-trust field have a validated-at-open check? — and the residual UB neither Miri nor ASAN can observe |
Quarterly + on any new unsafe |
| Performance | crates/sparq-engine/src/{exec,chunk,cs,explain_json}.rs, crates/sparq-core/src/{store,compress}.rs, crates/sparq-substrate/src/join.rs, scripts/check-no-dyn-dispatch.py, scripts/perf-gate.py |
Operator-model design, estimator/guard math, cost-gate design (see §4 B-tier 4); extend the no-dyn gate's scanned set the moment vectorized kernels wire in | Per perf PR; design-led not review-led |
| Feature-completeness | crates/sparq-conformance/src/scoreboard.rs, crates/sparq-conformance/tests/scoreboard_floors.rs, the reasoner/QL/geo/rsp READMEs |
Only the reasoning-frontier soundness envelopes (§4 B-tier 2). Everything else is a fleet ratchet grind | Monthly floor-review |
| Result-accuracy | crates/sparq-substrate/src/{numeric,compare,join}.rs, crates/sparq-engine/src/exec.rs, crates/sparq-bench/src/fuzz.rs, crates/sparq-canon/src/rdf12.rs |
The value-level differential oracle spec; the ORDER-BY-vs-relational recheck asymmetry seam; the two-convention XSD-double lexical adjudication; fn:round fp reasoning; which mutation survivors are real bugs vs equivalent |
Bi-weekly accuracy pass |
- Value-level multi-oracle differential (new, XL).
fuzz.rs:307checks cardinality only (sparq_full != oxion solution counts) for non-ORDER-BY queries — blind to wrong bound values that preserve row count;gen_graphemits no dateTime/duration/boolean,gen_queryno aggregate/BIND-arithmetic/string/CONSTRUCT. Fable writes the correctness spec: compare the full canonicalised binding multiset term-by-term against the oracle, add a second independent oracle (Jena CLI / rdflib subprocess) to catch sparq+Oxigraph shared-assumption bugs, and specify the oracle-normalisation rules (legitimate impl-defined divergence: GROUP_CONCAT order, double lexical form). Fleet builds the harness + corpora + subprocess plumbing + graph-isomorphism compare viasparq-canon. - ORDER BY / MIN / MAX numeric precision (M).
compare_terms(compare.rs:160) decides numerics viaas_f64().partial_cmp, with no exact recheck, whereas the relational=/<path (exec.rs cmp_expr:7060/equal_expr:7099) does recheck when f64 collapses distinct values (integers >2^53, hp-decimals).num_compare(exec.rs:6306, MIN/MAX) also rechecks — so the asymmetry is inconsistent even internally. Fable designs a perf-neutralexact_cmphook through theCompareTermtrait (recheck only on f64 tie, no vtable, no hot-loop regression). - XSD double/float lexical (M).
Num::lexical/fmt_xsd_doubleprint integral doubles as plain6(W3C-suite-pragmatic) whilecanonical_lexicalemits6.0E0(XSD-mandatory scientific); which method each surface (STR/EBV/serialize/aggregate/value_key) calls silently decides conformance. Alsoas_num(exec.rs:7314) usesparse::<f64>()which rejects XSDINF/-INF/NaN. Fable adjudicates the per-surface policy (STR/EBV/serialize must be XSD-canonical); the INF/NaN routing fix is mechanical. fn:roundfp boundary (S).Num::roundfloat tier is(f+0.5).floor()(numeric.rs:431) — the classic double-rounding defect (0.49999999999999994→ 1, not 0). Fable confirms the failing inputs + the correct round-half-to-+∞ for float tiers.- Coverage/mutation ratchet gap (fleet, M/L).
sparq-substrate— the correctness core — is in none ofcoverage-floor.json,coverage-presence.json,mutants-baseline.json,scripts/coverage.sh,feature-matrix.yml(its numeric/compare/join are default-OFF features, sollvm-covinstruments an empty crate). Fleet adds the--features numeric,join,compare,rowsmeasure case + seeds floors/baselines (sq-hbg7/sq-8kt3/sq-qcnn/sq-52su); Fable only adjudicates the surviving-mutant lists onnumeric.rs/compare.rs/exec.rs(real bug → write the killing assertion; equivalent → document like thesparq-reason6 defensive-bound survivors), then promote the lane advisory→gating.
Stage 1 (HAIKU recon): enumerate the lens's targets (call sites / field bindings / cast sites /
public-input signatures) into a SCHEMA'd evidence pack. No judgment. [query-pkg + ast-grep]
Stage 2 (SONNET, optional): assemble the cross-reference tables (circuit↔reconstruct, manifest-field
provenance, cast alignment/length) the review needs. SCHEMA'd.
Stage 3 (FABLE / sparq-reviewer): adjudicate ONLY the subtle question for that lens; return
{findings[], soundness_verdict, follow_up_beads[]}. Reads pack + tables, never whole files.
Stage 4 (orchestrator glue): the fleet files follow_up_beads via `bd create`; arm-on-verdict.
Fable touches only Stage 3, on a Haiku/Sonnet-prepared pack. Follow-ups become beads (repo hygiene: TODOs → beads, never markdown checklists).
| Agent | Model | Role |
|---|---|---|
sparq-rust-feature |
opus | Opt-in feature-gated Rust crate impl; gates both feature states |
sparq-site / sparq-ci-infra / sparq-docs |
opus | Frontend / CI-supply-chain / doc-only reconciliation |
sparq-researcher |
opus | Deep research → research/ design record (opens its own PR — see gotcha) |
sparq-merge-fixer |
opus | Unblock a stuck/conflicting PR on its existing branch |
sparq-perf-reviewer |
opus | Narrow perf-discretion verdict hook on gh pr merge --auto |
sparq-pkg-nl |
haiku | The only non-opus agent: NL→SPARQL→run→NL PKG round-trip |
sparq-workload-triage |
opus | Read-only local-vs-EC2 placement (places, never launches) |
compliance-engineer / compliance-auditor |
opus | Certification control impl + adversarial audit loop |
Root gap: model homogeneity. 11/12 dispatchable agents are opus, one is haiku; there is no
sonnet tier and no fable tier. A Fable orchestrator today has no cheaper implementer/verifier below
it and no Fable reviewer to escalate to.
| Agent | Model | Purpose | Why this model |
|---|---|---|---|
sparq-architect |
fable | The missing FRONT stage: epic → design record + N disjoint spec'd child beads {crate, model_tier, invariant, acceptance_test}. Read-only + writes research/ + emits beads; does NOT implement. Supersedes sparq-researcher for the decompose-and-spec job. Inherits proceed-and-document |
Disjoint decomposition + invariant design is Fable's scarce edge; one call/epic amortises across N cheap impls |
sparq-reviewer |
fable | The missing final VERDICT-GIVER, invoked only on the escalated subset (failed mechanical verify, or ZK/MPC/reasoner/engine-correctness/novel-algo/honesty surfaces). Returns per-PR {honest, sound_as_scoped, recommend_arm, disposition: arm|request_changes|hold|fable_implements, concerns[]}. disposition=fable_implements triggers a scoped isolated-worktree implementation task authored by Fable (the fleet couldn't land it, or it is soundness-critical), after which the normal mechanical-verify → arm path resumes. Holds only sq-qhy4-gated items |
Subtle soundness judgment is exactly what the pipeline currently punts to the human; reading only escalated diffs minimises tokens |
sparq-verify-mechanical |
haiku | The cheap mechanical verify pass (today runs at opus): gates green both feature states, tests non-vacuous, opt-in respected, README/SKILL synced, no hardcoded perf. Returns {mechanical_ok, checks[], escalate, escalate_reason}; arms clean low-risk PRs, escalates the rest |
Objective checklist a cheap model does reliably; it is the escalation filter that keeps Fable's input tiny |
sparq-rust-impl |
sonnet | Bulk sibling of sparq-rust-feature for well-spec'd disjoint single-crate beads the architect has de-risked; escalates back up if it discovers the bead is actually hard |
Once the spec + failing test exist, impl is mechanical; this is the missing cheap bulk-impl tier |
sparq-context-monitor |
haiku | Out-of-band context-hygiene observer (§8): reads the session transcript .jsonl and emits {should_compact, confidence, reason, what_to_preserve[], externalize_first[]}. SIGNALS only (cannot force compaction); greenlights only when externalize_first is empty. Its brief is the §8 trigger ruleset (bead sq-sgu1.1) |
Watching a transcript for a clean compaction seam is cheap pattern-work; Haiku makes continuous observation ~free vs one Fable turn |
Provenance-trailer caveat (needs:user). Every agent config and the workflow prompt strings hardcode
[OPUS-4.8]+Co-Authored-By: Claude Opus 4.8. When the fleet is multi-model this mislabels Fable/Sonnet/Haiku diffs as Opus. A model-aware per-stage trailer is required — but.claude/agents/*.mdis a PROTECTED surface (AGENTS.md rule 11: agents may not rewrite their own/sibling configs), so this edit is maintainer-applied, not agent-self-editable.
| Workflow | Shape (model per stage) | When |
|---|---|---|
fable-architect-drain (flagship) |
1 FABLE architect (decompose → design record + N disjoint beads, SCHEMA'd) → 2 HAIKU recon (ground specs, optional) → 3 SONNET fleet fan-out (impl N disjoint beads, isolation:worktree, SCHEMA'd) → 4 HAIKU mechanical-verify (arm clean, escalate rest) → 5 FABLE reviewer (escalated diffs only → verdict → arm-on-verdict); branch: if the reviewer's disposition=fable_implements, Fable authors the fix in an isolated-worktree sub-task, then re-enters Stage 4 mechanical-verify — the deliberately rare path that spends the scarce resource on code, gated on the review signal. Fable touches Stage 1 (1 call) + Stage 5 (only failed-verify diffs, plus the rare self-implement branch) |
Default drain for a hard epic or a batch of underspecified/soundness-sensitive beads |
fable-soundness-verdict |
1 HAIKU enumerate open honesty/soundness PRs + assemble each evidence pack (diff + tests + research/zk-*-audit.md + SECURITY.md lines, SCHEMA'd) → 2 FABLE reviewer fan-out (one call/PR → verdict) → 3 orchestrator glue (arm recommend_arm=true; hold sq-qhy4/honest=false) |
Periodically, to clear the soundness pile the current loop leaves OPEN for @jeswr |
model-tiered-scheduler-v2 |
Evolve autonomous-scheduler.js: keep disk-guard/frontier-read/isolation:worktree/schemas/backoff; make pickAgent return {agentType, model} from the architect-assigned tier; split verify into HAIKU mechanical (arms/escalates) → FABLE reviewer (escalated-only). Frontier + recon run HAIKU; Fable never appears except as the escalation target |
Steady-state autonomous tick once the tiered agents exist |
fable-lens-review (§5.3) |
HAIKU recon → SONNET cross-ref tables → FABLE adjudicate → fleet files follow-up beads | The cadenced review campaign |
All new workflows must: give every producing stage a schema (schema-guard trap); use
Explore/"findings-only" for any research fan-out (researcher-PR gotcha); arm on the verdict object,
never a PR-number loop; and inherit proceed-and-document (never relabel unaudited ZK/MPC "sound").
Pre-req (fleet, day 0, needs:user for the trailer): stand up the four proposed agents
(sparq-architect/sparq-reviewer fable, sparq-verify-mechanical haiku, sparq-rust-impl sonnet)
and the model-aware provenance trailer. Wire fable-architect-drain + fable-soundness-verdict with
schemas on every stage.
| Day | Fable action (scarce) | Fleet action (parallel) | Kill-criterion |
|---|---|---|---|
| 1 | A1 FO-KM top-arm (Fable-as-NL-tool over ≥30 TH/ER/CC tasks); pre-register K1/K2 margins before running | Fill Haiku/Sonnet/Opus rungs; broaden to the sq-givgo ≥30-task floor; add gist + BFO overlays |
Flip only if schema.org−gUFO closes at Fable rung, p<0.05, CI excludes 0; flat → declare fluency-penalty a law, stop |
| 2 | sq-tu4e reachability adjudication (pure reasoning, NOT credential-gated) — is deny-on-disagreement expressible under input-only stratified NAF? |
Enumerate incremental.rs NAF-over-derived rejections + external-graph admission rules |
If provably unreachable without an engine extension, write the extension spec as a child bead; do not ship a silently-unsatisfiable rule |
| 3 | sq-rsd3v.1 nullifier design (Poseidon2 domain-separated, single-use) + soundness sketch |
Extract every zk/compose/*/main.nr public-input signature; build the circuit↔reconstruct table |
Any candidate colliding leaf / free witness found → the design is unsound, iterate before spec'ing impl |
| 4 | A2 PKG re-curation design + sq-bn2t8 OWL 2 QL CQ-shape-gate spec (reject non-CQ, never lose answers) |
Re-price PKG-dogfood with Fable-as-orchestrator; assemble the sq-4va4l boundary set |
Curation ships only if off-PKG stratum stays 1.0 abstain-precision; QL rewriter only if the reject-gate is proven answer-preserving |
| 5 | Perf estimator design — Index-Based Join Sampling + never-underestimate guard spec; run fable-soundness-verdict over the open ZK/MPC pile |
Build the sampler skeleton behind the design; assemble verdict evidence packs | Estimator ships only if the guard provably never under-estimates (order-only, results unchanged) |
Weekly rhythm thereafter: fable-architect-drain on the next B-tier-1/2 epic + fable-lens-review on
the bi-weekly accuracy lens + fable-soundness-verdict sweep. The mechanical frontier
(autonomous-scheduler.js → model-tiered-scheduler-v2) drains the ~281 ready beads without Fable.
Motivation. If Fable runs the main orchestration thread, the context window bloats and every Fable turn re-reads a large window at high cost — the scarce-resource doctrine dies if the THREAD itself is fat. Cheap-fleet delegation saves nothing when the orchestrator carries a bloated transcript into each expensive turn. The fix is a discipline (externalize-then-shed) plus a cheap out-of-band observer.
Principle — externalize-then-shed. Durable outcomes live in commits / beads (bd) /
auto-memory / a research/ doc — never in the live thread and never in a scratch
HANDOVER*.md/SESSION*.md (repo hygiene forbids those; see AGENTS.md). The live thread stays a
thin working set; anything durable is shed to a persistent store the moment it is captured.
The thread is a scratchpad, not a ledger.
The observer — sparq-context-monitor (proposed, model: haiku; §6.2). A NEW out-of-band agent
that reads the session transcript .jsonl and emits a SCHEMA'd signal
{should_compact: bool, confidence, reason, what_to_preserve[], externalize_first[]}. Because it is
Haiku, watching costs ~nothing relative to one Fable turn. It SIGNALS only — it cannot force
compaction; the main thread (or the user via /compact, or the harness auto-summary at window
overflow) acts on the signal. Its value is triggering compaction EARLY at a clean seam, so the
harness never force-summarizes mid-thought at a bad boundary.
Precondition gate. The observer greenlights compaction only when externalize_first is empty;
otherwise it returns that list ("persist these first") and defers. Externalize, then compact —
never the reverse.
Compaction-trigger ruleset — compact WHEN (any of):
| Trigger | What the observer looks for | Action |
|---|---|---|
| 1. Clean seam | A coherent unit of work just completed AND its durable outcome is externalized (PR opened/merged, workflow result acted-on, bead created/closed, memory/doc written) | Compact — the safest, cheapest moment |
| 2. Window pressure | Context exceeds a budget threshold (~50% of window, or the per-turn input-token cost crosses a line) | Compact — OVERRIDE trigger regardless of seam |
| 3. Large-artifact shed | A big tool result (workflow output, file/log/search dump) was ingested, its conclusion extracted and acted on; the raw bytes are now dead weight | Compact — drop the raw bytes, keep the conclusion |
| 4. Topic switch | The conversation pivots to a task largely independent of the prior one's mechanics | Compact — prior mechanics no longer load-bearing |
| 5. Idle-loop repetition | Many near-identical /loop heartbeats have accumulated |
Compact — collapse the repeats |
| 6. Pre-hard-reasoning | Right before a known-expensive Fable reasoning turn | Compact FIRST — so it starts from a minimal, relevant context |
Do NOT compact WHEN (guards):
- (a) Mid-task with unsynthesized working state — a plan half-formed, an edit in flight, a decision pending. Compaction would drop load-bearing memory not yet externalized. Externalize first.
- (b) Immediately after an error/retry where the failure details still drive the next attempt.
- (c) An un-acted user instruction or un-captured decision sits in recent context — externalize it to a bead/memory/doc, THEN compact.
- (d) The unique, hard-won reasoning in the thread is not yet written anywhere durable.
This ruleset is itself the brief for the sparq-context-monitor agent — Amendment-1 bead
sq-sgu1.1 will stand it up. [OPUS-4.8]
Hard-gated (Fable must not auto-start):
sq-qhy4/ #811 — the external accredited-cryptographer audit. Fable de-risks it (pre-finds obvious soundness bugs) but never replaces it; the production "sound/proven" label stays gated.- EC2 / perf-host benchmarks —
sq-0g6g/sq-v8ixk/sq-n7fcanonical gates,sq-5o5/sq-axky/sq-dbdk/sq-pjhc/sq-gafdhgather beads,sq-bj/sq-3l43/sq-hoaj/sq-w0ax/sq-xin1/sq-yc1q/sq-8lgn/sq-uubqheavy tiers, and the FO-KM Metric-2 / provenance Phase-4 KGE runs: design only, no dispatch without a maintainer greenlight. - Dependabot majors (#1278–1283: arrow 55→59, hdt 0.4→0.7.3, n3 1→2) — breaking-API/MSRV = a maintainer decision. Do not migrate major deps.
- cargo-vet auto-certification / supply-chain auto-approval — the advisory pipeline is already gated; keep it fresh, never auto-certify.
- Maintainer-gated PRs — #1155 (ZK VC-cryptosuite bridge, DIRTY, deliberately not auto-armed),
#1260 (GUI stats, DIRTY), #1084 (release v0.1.0 + signing/publish creds
sq-v286.*). Do not rebase or arm these. - Auth model #907 /
sq-70kx2(OIDC/JWT + RBAC + graph-level security) — the one feature deliberately NOT auto-built; needs the maintainer's security-model input first. - Steer/Decision items — #1001/#1002 (assurance-tier + DPV depth, also
sq-qhy4-gated), the beyond-RL bead (sq-rhspl, linked #1307; maintainer-steer required), logos (PR #823/#207/sq-8pbx), #1139 (Semantic Scholar key),sq-vbq9(Pages source), #1135 (Copilot/bundle-budget), and the ~40 post-hocSteer:/Decision:issues (these are maintainer review items, not new work).
Soft-gated (a cheaper model is equal or better — do not burn Fable IQ):
- Implementation, by DEFAULT — the fleet writes the code; delegating implementation is Fable's
default posture, not an absolute prohibition. Fable overrides this only by its own
review-driven
fable_implementsdecision (§6.2/§6.3), and even then authors in a scoped, isolated worktree with a minimal brief, never inline on the orchestration thread (§8). Blanket kernel-authoring on the main thread remains the anti-pattern this charter exists to prevent. - The ~281 ready mechanical beads — the entire fleet drain. All JSON-LD/Geo/RSP/full-text/RDF-XML/
SHACL long-tail, GUI stub-filling + wasm-portability spike (
sq-zeai), website content-reduction, doc-currency reconciliation (sq-6gob). - The SSRF perimeter fixes (env-proxy
.proxy(None), redirect re-vet test,is_forbidden_ipcompleteness, forwarded-WebID deployment note) — a stronger model does not change the outcome; Fable adjudicates only the one-line vetted-proxy policy. - SPARQL 1.1/1.2 conformance — at its honest ceiling (1225 + 4 proven expected-file divergences);
just file the 4 upstream
rdf-testsissues via the fleet. - The terse token axis (A4) — dead by arithmetic; the empirically-honest move is to bank the negative and refuse to re-measure. Re-running a settled token negative on the most expensive model is the exact anti-pattern this charter exists to prevent.
- ast-grep/compacted-AST self-ergonomics (A5) — passively mine Fable's own transcripts; never a dedicated expensive fan-out.