Commit graph

342 commits

Author SHA1 Message Date
6e42dbf026
docs/diagrams: rename aborist-modules → arborist-modules (post-rename cleanup)
The top-level module diagram still used the old aborist- (one R) prefix
from before the package rename. arborist.unturf.com served from the
symlinked docs/_source/diagrams/, so the live URL
arborist.unturf.com/en/diagrams/arborist-modules.svg 404'd because the
file on disk was aborist-modules.svg.

Other diagram base names (ingest-pipeline, mesh-*, query-pipeline,
verifier-ladder) were never aborist-prefixed; only this one needed it.
2026-05-08 07:50:28 -04:00
ea39455d75
v8: ticket #000012 Phase 1a — ForkScore consumes the new bench substrate
Pure scoring function over (parent, child) BatteryResult bundles. Closes
the scoring half of fox's 2026-05-08 frontier note ("how does an organism
mutation become canonical?") — the canonicalization half (validator
state, acceptance, fork choice) stays under #000012 as the v8 paper.

Formula:

  ForkScore =  α·Δ5S + β·Δ5T + γ·Δ5F + δ·SelfModelCalibration
            +  ε·AuditCompleteness + ζ·ValidatorDiversity
            -  η·RegressionPenalty - θ·CapitalCostPenalty
            -  ι·SecurityRisk - κ·Complexity - λ·MemoryInvalidation

Consumes every metric this session shipped:

- 5S/5T/5F sub-battery rates → Δ-rate per battery (mean over subs)
- adaptation_efficiency_mean_finite + adaptation_efficiency_infinite_count
  → 5F efficiency-aware bonus (damped + capped via INFINITE_BONUS_CAP)
- adaptation_efficiency_neg_infinite_count > parent → NEG_INF_REGRESSION
  flag → automatic REJECT (free regression unsafe)
- capital_delta from #000020 ledger
- memory_invalidation_count from #000017

Verdict thresholds:

- ACCEPT  when score >= SIGNAL_FLOOR (5pp; matches docs/bench-maxing.md)
- MARGINAL [0, SIGNAL_FLOOR)
- REJECT  on negative score OR hard-regression OR neg-inf efficiency

Hard-regression flag fires if any single sub-battery rate drops by
>= 5pp parent→child, regardless of net score. CLI exits 1 on REJECT
so CI gates run `arborist v8 score` directly.

Surface:

- arborist/v8/{fork_score,weights}.py
- WeightSet dataclass with α…λ + DEFAULT_WEIGHTS (single-validator
  tuned: ζ=0, ι=0, κ=0; η=2.0 weighted heavier than improvement
  weights; θ=0.5 modest cost penalty)
- weights_from_dict accepts "lambda" key (Python reserved word)
- bench_result_to_metrics adapter from runner --all JSON
- CLI: arborist v8 score --parent P.json --child C.json [--weights W.json]
  with override flags for SelfModelCalibrationGain, AuditCompleteness,
  capital_delta, memory_invalidation_count, etc.

Reference: docs/v8-fork-score.md (formula + term semantics + verdict
matrix + Phase-1a vs Phase-1b boundary).

Tests: tests/test_v8_fork_score.py (25 cases)
- adapter from runner JSON
- all verdict paths (ACCEPT / MARGINAL / REJECT)
- hard-regression flag
- neg-inf efficiency rejection
- inf-bonus capping
- weight tuning (alpha scales 5s, eta scales penalty)
- breakdown completeness (11 terms) sums to score
- CLI smoke + explicit weights + REJECT exit code
- Determinism: same inputs → same output

Full suite: 1186 passed, 36 skipped.

#000012 status: in progress (Phase 1a landed, consensus paper still open).
2026-05-08 07:18:22 -04:00
3bff55234f
5f: efficiency metrics with explicit zero-cost guards
Per fox's 2026-05-08 review of fbd99a8: implement adaptation_efficiency
and feedback_efficiency in run_finetuning + run_feedback_loop with
explicit sentinels — not Python floating-point accidents.

_efficiency(gain, cost) helper:

- cost > 0:       standard ratio
- cost == 0, gain > 0:  EFFICIENCY_INFINITE  (free improvement)
- cost == 0, gain == 0: EFFICIENCY_UNDEFINED (= 0.0; no signal)
- cost == 0, gain < 0:  -EFFICIENCY_INFINITE (free regression)

Battery-level metrics report mean_finite (computed over finite
values only) + infinite_count + neg_infinite_count so the mean
stays dimensionally truthful and consumers can pivot on the special
buckets separately.

Phase 1a cost proxies:
- run_finetuning: _capital_cost_delta sums resource_budget
  (max_compute_ms_delta * 1e-3 + max_storage_delta_bytes / 1e6).
  Phase 1b.2 will replace with real capital_ledger reads.
- run_feedback_loop: chain length = cost. Phase 1b.2 capital_ledger
  integration replaces it.

Tests added (7):
- _efficiency over four boundary cases
- 5F finetuning + feedback_loop emit the new metrics keys
- Synthetic zero-cost finetuning fixture verifies +inf path

Full suite: 1110 passed, 36 skipped.

Closes the one actionable from the fbd99a8 review.
2026-05-07 20:57:34 -04:00
2af28e66af
bench: land #000023 + #000024 + #000025 (Phase 1a/1b — Dav1DPrometheus suite)
Implements three coupled tickets in one push: complete the 5S battery,
align 5T to Dav1DPrometheus vocabulary + complete it, open 5F battery.
All runners deterministic, no LLM-as-judge anywhere.

#000023 — 5S Phase 1b (closed)
  run_syllogism + run_synthesis + run_semiotics replace stubs.
  30 deterministic fixtures each (90 total, all passing).
  Carrier metadata mandatory; unsupported carriers fail explicitly.
  Syllogism kernel handles categorical_transitivity, chain_3,
  invalid_converse, missing_premise. Order-agnostic over premise
  permutations.
  Synthesis uses content-token subset check (stopwords removed) —
  catches single-token entity swaps that lax overlap missed.
  Semiotics validates synonym-swap invariance via π* canonicalize +
  re-substitution. Hidden-channel work stays defensive only.

#000024 — 5T Phase 1b (closed)
  Vocabulary aligned: Transfer→transfer-learning, Truth→truthtables,
  Timing→time. Legacy transfer-v1.jsonl + run_transfer kept intact.
  run_transfer_learning, run_triangulation, run_truthtables,
  run_transitivity, run_time replace stubs.
  30 fixtures each × 5 = 150 total (155 with legacy transfer).
  Triangulation runs 4 strategies (substring, token_subset,
  token_overlap, entity_match) and gates on agreement threshold.
  Truthtables: deterministic propositional evaluator with
  recursive-descent parser; supports AND/OR/NOT/XOR/IMPL/IFF;
  capped at N=4 variables.
  Transitivity: typed-relation whitelist
  (implies, subset_of, ancestor_of, before, less_than). BFS path
  walk; mixed/unknown relations fail by construction.
  Time: synthetic memory-snapshot chains test preservation,
  stale-marking, current_root tracking. Phase 1b.2 will read real
  memory_records.

#000025 — 5F Phase 1a (in progress; Phase 1b expansion still open)
  New bench/batteries/b_5f.py with five sub-batteries:
  - Function (shape_match / pointer_set_match / threshold_on_metric)
  - Finetuning (parent→child SelfModel improvement check)
  - Falsification (planted-error detection rate, verifier_method_root pinned)
  - Formulate (structural lattice match: claim count + sorted-approx
    text + exact pointer-ID-set; not exact-string)
  - Feedback Loop (operation/observation chain → expected_delta in
    aggregated observation feed)
  10 deterministic seed fixtures per sub-battery (50 total).
  feedback_efficiency / adaptation_efficiency hooks stub the capital-
  ledger integration for v8 fork-choice.

Cross-cutting:
  - bench/batteries/base.py: PHASE_1_CARRIERS whitelist +
    validate_carrier helper. Backward-compatible with Phase 1a
    fixtures that lack carrier field (defaults to "text").
  - runner.py registers all 16 sub-batteries in _DEFAULT_FIXTURES
    so `--all` runs the entire Dav1DPrometheus suite.
  - Makefile: bench-5s / bench-5t / bench-5f / bench-5s5t5f
    targets. bench-5t-legacy preserves Phase 1a access.
  - tests/test_bench_batteries.py: 29 tests (was 17). Phase 1a
    digest stability checks, sub-battery smoke tests, carrier
    rejection tests, transitivity-whitelist test, truthtables
    N>4 cap test.

Bench summary across the full suite:
  5s syntax/semantics/syllogism/synthesis/semiotics  108/108 pass
  5t transfer/transfer-learning/triangulation/truthtables/transitivity/time  154/154 pass
  5f function/finetuning/falsification/formulate/feedback-loop  50/50 pass
  TOTAL: 312 fixtures across 16 sub-batteries — 100% pass.

Full test suite: 1103 passed, 36 skipped.

Source: Legally Unprecedented Dav1DPrometheus (BasementAGI host).
Honoring his framework. The complete state-space synthesis (SQD +
v7 + 5S/5T/5F) is now executable infrastructure, not metaphor.
2026-05-07 20:14:44 -04:00
a66ab10351
docs: add tool-action-dag-design.md research path (pre-ticket)
Captures design for an action-provenance DAG layer downstream of
final_label - five new stages (action_plan -> tool_call ->
tool_output -> postcondition_check -> action_label) - and why this
stays a research doc rather than an open ticket today.

Three options analyzed: Option A in-tree action DAG (identity
drift), Option B sidecar package (recommended; preserves the
verified-answer-cache identity by chaining a separate action_root
that cross-links into run_dag_root), Option C out-of-scope.
Promotion criteria spelled out so the doc graduates to a ticket
when the first agent use case shows up. Cross-links #000001
(upstream provenance gap), #000022 (LossReport, same axiom one
stage upstream), #000012 (v8 selection could later score action
histories), and the 2026-05-07 arborist-vs-donto comparison.

TICKETS.md gains a pointer in "Distinction from other docs" so
future shifts find the doc.
2026-05-07 19:47:50 -04:00
fbd99a8d76
docs/tickets: rewrite #000023/#000024/#000025 with cross-modality discipline
Per the three review responses (~/Downloads/RESPONSE_*) folded in
2026-05-08, the 5S / 5T / 5F tickets are corrected from "text-only
with future hooks" to "carrier-aware design from day one." Phase 1
implementation stays text / claim-lattice / memory-root only, but the
fixture schema MUST accommodate future visual / world / code / audio /
sensor / hidden-channel-detection carriers without re-authoring.

Common corrections across all three tickets:

- Mandatory fixture metadata: carrier, domain, pi_star_ref,
  loss_report_refs, modality_notes.
- Unsupported carriers MUST fail or skip explicitly with
  reason="unsupported_carrier" — never silently accepted.
- No LLM-as-judge in any runner.
- Hidden-channel work is defensive only (detection / flagging),
  never generation or concealment.

Per-ticket headlines:

#000023 — 5S
  Syntax / Semantics / Semiotics defined as carrier-general operations
  over sign-bearing representations. Semiotics gets the biggest
  correction: visual symbols, layout, metadata, encoded sign systems
  are valid carriers (Phase 1 still text-only). Synonym source
  policy: concept_relations.relation_kind='synonym' only for v1
  positives.

#000024 — 5T
  Vocabulary alignment with Dav1DPrometheus authoritative wording
  (Transfer→Transfer Learning, Truth→Truthtables, Timing→Time).
  Transitivity gets a typed-relation whitelist (implies, subset_of,
  ancestor_of, before, less_than) — not all edges transitive.
  Truthtables capped at N=2..4 to avoid combinatorial blowup. Time
  is the first sub-battery where v8 substrate (memory_root #000017
  + selfmodel #000014) becomes a measurable bench target.

#000025 — 5F
  New axis. Function/Finetuning/Falsification/Formulate/Feedback
  Loop. Folds in the state-space synthesis: SQD + v7 + 5S/5T/5F +
  arborist together instantiate a discrete state-space/time
  Ω_t = (W, I, C, L, MRoot, SMRoot, PRoot, BRoot, ARoot) with
  Ω_{t+1} = T(Ω_t, Δ_t). Counting / mathematics / logic / time
  emerge as auditable operations over committed state, not text from
  a latent model. adaptation_efficiency and feedback_efficiency
  metrics hook into the capital ledger (#000020) so v8 fork choice
  has cost-aware fitness signals. Falsification fixtures tagged
  with verifier_method_root so verifier shape changes warn rather
  than false-fail.

All three tickets remain "open · awaiting go/no-go" — design-only.
Implementation tickets land in follow-up commits when fox approves
the corrected scope.

Source: Legally Unprecedented Dav1DPrometheus (BasementAGI host,
Where The mAGIc Happens). Honoring his framework.
2026-05-07 19:47:05 -04:00
02c7e41ef8
loss_report: land ticket #000022 (adapter LossReport sidecar)
Typed loss ledger for adapter / canonicalizer drops, transforms, and
normalizations. Sidecar — never enters cache_key, document_root,
run_dag_root, or audit_events. Loss policy lives in its own
loss_report_policy_hash so toggling reporting does NOT invalidate
prior QA cache entries (corrected pre-land per GPT-5.5 review).

- adapter_loss_reports table: PK (chunk_id, stage, canonicalization_version,
  loss_kind); columns include loss_mode {pure_drop|transform|quarantine|
  normalize}, bytes_dropped, occurrence_count, input/output_length_bytes,
  sample_excerpt, sample_hash, adapter_name/version, loss_report_policy_hash
- arborist/sources/loss_report.py: LossEvent, LossCollector with
  add()/record_delta()/set_lengths()/events(), record_losses() batched
  idempotent insert, compute_loss_report_policy_hash() pure function
- wikitext.to_base() emits ref_tag, self_closing_ref_tag, file_link,
  image_link, category_link, strip_code_transform, whitespace_run.
  loss_collector=None default keeps verifier/runner/query path unchanged
- html_page parse_html / _normalize_text emit script_block, style_block,
  html_chrome, whitespace_run; HtmlPageSource gains loss_report_*
  __init__ flags. Document-scope events anchor to first chunk_id at
  ingest via Document.extra['loss_events']
- ingest.ingest_source: per-chunk to_base() with collector for
  wikipedia_* sources; persisted via record_losses inside the same
  transaction as chunk inserts. Default loss_report_enabled=True
- arborist losses CLI subcommand: --document-root / --chunk-id /
  --kind / --stage / --summary / --json. arborist ingest gains
  --no-loss-report / --no-loss-excerpts / --loss-excerpt-bytes
- tests/test_loss_report.py: 15 tests covering bit-identical
  regression, loss-kind taxonomy, byte-conservation property test
  (loss-mode-aware), idempotent persistence, document_root invariant
  under toggle, policy hash purity

1091 tests pass, 0 audit-chain breaks across all 7 shards.
2026-05-07 17:58:50 -04:00
10d2db621c
docs/tickets: open #000023-#000025 — Dav1DPrometheus 5S/5T/5F coverage
Three new design-only tickets surfacing the gaps between arborist's
current bench harness (ticket #000021 Phase 1a, landed) and
Dav1DPrometheus's authoritative 5S/5F/5T evaluation framework.

- #000023 — 5S Phase 1b: real implementations + fixtures for
  Syllogism, Synthesis, Semiotics (currently stubbed).
- #000024 — 5T Phase 1b: rename Transfer→Transfer Learning,
  Truth→Truthtables, Timing→Time to honor Dav1DPrometheus's
  vocabulary; ship real Triangulation, Truthtables, Transitivity,
  Time runners (currently stubbed). Time integrates with
  memory_root (#000017) for the first measurable use of v8
  substrate as fitness target.
- #000025 — 5F battery: entirely new — Function, Finetuning,
  Falsification, Formulate, Feedback Loop. arborist had no 5F
  coverage before this ticket; the SQD whitepaper omitted the
  axis. Each sub-battery integrates with surfaces already shipped
  (selfmodel_records, providence_cache.falsification_state,
  memory_branch_summaries).

Source attribution: Legally Unprecedented Dav1DPrometheus
(BasementAGI host). Honoring his framework as the authoritative
taxonomy for non-embodied AGI evaluation.

Next ID bumped 000023 → 000026.
2026-05-07 17:29:40 -04:00
a64d941528
bench: ticket #000021 Phase 1a — 5S/5T harness skeleton + seed fixtures
Per fox's "partial punt on larger ones" — ships the bench/ skeleton +
small seed fixture sets so future v8/v7-W/SelfModel work can cite a
real fitness target. Full Phase 1 (50-200 fixtures per sub-battery)
and Phases 2-3 stay open in the ticket.

Phase 1a delivers:

- bench/batteries/{base,b_5s,b_5t,runner}.py — Battery protocol,
  BatteryResult, fixture-digest helpers, CLI runner.
- Seed fixtures:
  - bench/fixtures/5s/syntax-v1.jsonl — 10 tasks against
    wikitext-base@v1 and claim-lattice@v1
  - bench/fixtures/5s/semantics-v1.jsonl — 8 equivalence tasks
  - bench/fixtures/5t/transfer-v1.jsonl — 4 paraphrase-invariance
    tasks
- Runners for 5S Syntax, 5S Semantics, 5T Transfer. Other 5S/5T
  sub-batteries are stubs returning zero-task results.
- Makefile targets: bench-5s, bench-5t, bench-5s5t.
- runtime_digest field captures the active π* registry fingerprint
  so a registry change surfaces in bench results.

Tests: tests/test_bench_batteries.py (17 cases). Full suite:
1076 passed, 36 skipped. `make bench-5s5t` runs end-to-end and
emits JSON results.

Ticket #000021 status: in progress · Phase 1a landed; Phase 1b/2/3
remain open.
2026-05-07 16:57:45 -04:00
5cbcda41b9
docs: land ticket #000019 (spec methodology for π*, V, policy fields)
Doc-only landing. docs/spec-methodology.md codifies the discipline
arborist already practices — versioning rule, round-trip discipline,
soundness/completeness honesty, default-value greenfield rule,
sidecar separation — so new π*, V, and policy-field authors don't
re-derive it from audit-chain failures.

Three author-class sections each ship with:

- Five questions the author must answer before landing.
- Worked example drawn from arborist's existing surface.
- One-page checklist.

Worked examples cited:
- π* — wikitext-base@v1
- V — paraphrase strategy
- policy field — quantifier_guard_apply_caps

Cross-references to bench-maxing, seven-point-program, pi-star-
composition, concept-relations-design, and CLAUDE.md.
2026-05-07 16:53:28 -04:00
40d106fb2f
pi_star: land ticket #000015 (π* domain library + composition algebra)
New arborist.pi_star/ namespace centralizes canonical projections
under a name@version registry. Two existing canonicalizers re-homed
as registered π*'s:

- wikitext-base@v1 wraps arborist.wikitext.to_base
- claim-lattice@v1 wraps arborist.qa.parse_claims.parse_pointer_claims

Four stubs registered for follow-up modality tickets:
code-py-ast@v1, logic-kernel@v1, time-series-quantized@v1,
tabular-pinned@v1 — each raises NotImplementedError with a pointer
to ticket #000015.

Composition algebra in compose.py: PiStarComposition exposes
outer ∘ inner as a first-class π* with its own registry key
(default "<inner-name>-then-<outer-name>@v1"). canonical_composition_id
returns a SHA-256 fingerprint suitable for governance hash inclusion.
Order-sensitive: a∘b ≠ b∘a → different fingerprints.

Documentation: docs/pi-star-composition.md covers the rule (type-
compatible, deterministic, equivalence-class preserving), lossy vs
invertible compositions, worked text→claim-lattice example,
cross-domain anchor projections (future), authoring checklist.

Re-home is non-breaking: arborist.wikitext.to_base remains importable.
Tests: tests/test_pi_star.py (19 cases). Full suite: 1059 passed,
36 skipped.
2026-05-07 16:51:33 -04:00
3d8f8fbd47
memory: land ticket #000017 (memory-root lifelong learning summary)
Periodic, deterministic projection over audit_events that summarizes
recurring failure motifs, audit-mode distribution, and falsification
state. Sibling layer to providence_cache (per-cache_key answers) and
audit_events (per-event chain) — memory_root is the cross-query
behavior history a SelfModel optionally cites.

Surface:

- arborist.memory.{canonical,projections,snapshot,store,falsify}
- Three default branch projections at v1 (PROJECTION_VERSION pin):
  - failure-motif:violations (counts violation tags from
    providence_write events)
  - audit-mode-distribution (STRICT/HYBRID/UNGROUNDED counts)
  - falsification-state (current cache state distribution)
- memory_root = SHA-256 over canonical body bytes; sort-invariant
  on branches.
- CLI: arborist memory snapshot|show|branches|falsify
- Audit events: memory_snapshot_landed, memory_falsified,
  memory_marked_stale.

SelfModel integration: arborist.selfmodel.snapshot reads latest live
memory_root and folds into SelfModel body. Already shipped in #000014;
this ticket completes the round-trip (memory shifts → SelfModel root
shifts).

Tests: tests/test_memory_root.py (15 cases). Full suite: 1040 passed,
36 skipped.
2026-05-07 16:46:41 -04:00
69f91d39a6
capital: land ticket #000020 (8-capital-form cost ledger)
CapitalProfile (8 forms: living, material, financial, intellectual,
experiential, social, cultural, spiritual) attached per state-changing
op as a sibling-table row in capital_ledger. Sibling semantics: ledger
rows reference an audit_event_hash but do NOT enter the audit-event
preimage, so retroactive cost re-estimation cannot break the chain.

Surface:

- arborist.capital.{profile,store}
- profile_for_op dispatch with per-op estimators (ingest/qa/distill)
- record/summary/op_cost/top_by_form
- CLI: arborist capital summary|op-cost|top

Wire-up at three op sites:

- ingest.py — one row per batch (doc_count + total_bytes)
- qa/runner.py — one row per cache-miss (answer_chars + llm_seconds)
- distill/runner.py — one row per derivation (positive intellectual)

Estimator constants are heuristic v1 (ESTIMATOR_VERSION pin in the
schema). Re-estimation is supported by re-running estimators against
the recorded inputs_blob and writing a new row with a bumped version
pin; old rows stay queryable.

Tests: tests/test_capital.py (13 cases). Sibling-table invariant
verified: audit chain stays intact across capital writes.
Full suite: 1025 passed, 36 skipped.
2026-05-07 16:41:48 -04:00
a9fdcf41d5
selfmodel: land ticket #000014 (identity record + falsification)
SelfModel binds an arborist agent's identity to bytes a verifier can
recompute: model_profile_hash, verifier_method_root, governance hash,
canonicalization/chunking versions, optional patch + memory roots,
sorted capability-claim hashes. Hard-hash committed; no soft state in
preimage. State transitions live on the row, not the body, so the
selfmodel_root stays stable across live → stale → falsified.

Surface:

- arborist.selfmodel.{canonical,snapshot,store,falsify}
- CLI: arborist selfmodel snapshot|show|falsify|list
- Schema: selfmodel_records + selfmodel_capability_claims (additive)
- Audit events: selfmodel_snapshot_landed,
  selfmodel_capability_claim_added, selfmodel_falsified,
  selfmodel_marked_stale (all chain via existing append_audit)

Also folds in:
- CLAUDE.md operational rule: arborist stays Python-only; non-Python
  toolchains live in sibling repos. Forks/clients/servers in any
  language follow our schemas + canonical encodings.
- Ticket #000016 update: ZK lives in sibling repo arborist-zk-bench;
  arborist gains at most a wire-format consumer, never a Rust dep.
- Schema migrations also stub capital_ledger and memory_records
  tables for tickets #000020 and #000017 respectively (additive,
  empty until those modules land).

Tests: tests/test_selfmodel.py (14 cases; canonical-JSON stability,
root order-invariance, snapshot determinism, store idempotency,
audit events, falsify/mark_stale semantics, audit-chain integrity).
Full suite: 1012 passed, 36 skipped.
2026-05-07 16:36:34 -04:00
a9ee859657
docs: open ticket #000022 (adapter LossReport) + federation doc-discoverability fix
Both items surfaced by the 2026-05-07 arborist-vs-donto comparison
report (/home/fox/Downloads/arborist_vs_donto.pdf).

Ticket #000022 — adapter LossReport (PRD I9 analogue). Today wikitext
to_base() and html_page _normalize_text drop <ref> tags, image/category
wikilinks, HTML chrome, whitespace runs without recording any of it;
only the canonicalization-version pin survives. Ticket proposes a
sidecar adapter_loss_reports table (Option A) over Merkle-bound
loss_root (B) or audit-chain entries (C), preserving arborist's
"soft signals are sidecars" discipline. ~1.6% storage tax expected,
matching concept_relations. Doc-only; no code in this commit.

Federation doc-discoverability: PDF author concluded "federation
exists in code but the public docs page returned 404" because the
mesh page lives at /api/mesh.html and the concepts orientation
never surfaces the topic. Adds a "Federation across peers" section
to concepts.rst pointing at api/mesh, a :ref:\`federation\` anchor
+ context lead on api/mesh.rst, and a footer link in concepts.rst's
"Where to go next." Sphinx build passes; api/mesh.html#federation
deep link resolves.
2026-05-07 16:36:13 -04:00
8fe0144d81
docs/tickets: open #000012-#000021 design batch (v7/v9.8 gap coverage)
Ten design-only tickets covering the architectural gaps surfaced in the
DNA↔Merkle-DAG / Merkle-AGI v7 / SQD whitepaper review:

- #000012 Selection & consensus protocol (Merkle-AGI v8)
- #000013 Spatial-temporal substrate (Merkle-AGI v7-W)
- #000014 SelfModel: schema, falsification, integration
- #000015 π* domain library + cross-domain composition
- #000016 ZK Phase-2 frontier proof (concretize the hand-wave)
- #000017 Memory-root: lifelong learning audit chain
- #000018 Adversarial soft-hash covert-channel analysis
- #000019 Specification methodology for π* and V
- #000020 Capital-cost ledger (8-capital queues)
- #000021 5S/5T/5R benchmark fixtures + harness

All open · awaiting go/no-go. Next ID bumped 000012 → 000022.

No code in this commit. Implementation per ticket lands in follow-ups
once fox picks priority.
2026-05-07 16:25:00 -04:00
b9eb0fc176
docs: footer attribution → russell@unturf./foxhop/TimeHexOn/legallydav1dpro unturf permacomputers 2026 2026-05-07 14:53:33 -04:00
8d6961fcc1
aborist/arborist
modified:   .gitlab-ci.yml
	modified:   bench/qa_questions.txt
	modified:   bench/qa_sweep.py
	modified:   bench/run.sh
	modified:   docs/TICKETS.md
	modified:   docs/_source/README.md
	modified:   docs/_source/_ext/makefile_targets.py
	modified:   docs/_source/api/cli.rst
	modified:   docs/_source/api/distill.rst
	modified:   docs/_source/api/mesh.rst
	modified:   docs/_source/api/qa.rst
	modified:   docs/_source/api/retrieval.rst
	modified:   docs/_source/api/storage.rst
	modified:   docs/_source/api/substrate.rst
	modified:   docs/_source/concepts.rst
	modified:   docs/_source/conf.py
	modified:   docs/_source/cookbook.rst
	modified:   docs/_source/index.rst
	modified:   docs/_source/license.rst
	modified:   docs/_source/quickstart.rst
	modified:   docs/bench-maxing.md
	modified:   docs/benchmarks.md
	modified:   docs/cti-architecture.md
	modified:   docs/diagrams/aborist-modules.dot
	modified:   docs/diagrams/aborist-modules.svg
	modified:   docs/diagrams/mesh-data-flow.dot
	modified:   docs/diagrams/mesh-epoch-lifecycle.dot
	modified:   docs/diagrams/mesh-epoch-lifecycle.svg
	modified:   docs/diagrams/mesh-group-decisions.dot
	modified:   docs/diagrams/mesh-group-decisions.svg
	modified:   docs/diagrams/mesh-identity-stack.dot
	modified:   docs/diagrams/mesh-secret-envelope.dot
	modified:   docs/mesh.md
	modified:   docs/qa-modes-bench.md
	modified:   docs/seven-point-program.md
	modified:   docs/tickets/ticket-000001-retrieval-keywords-audit-gap.md
	modified:   docs/tickets/ticket-000002-reference-frame-polarity-contract.md
	modified:   docs/tickets/ticket-000003-anchor-class-warrant.md
	modified:   docs/tickets/ticket-000005-label-ladder-migration.md
	modified:   docs/tickets/ticket-000006-bench-emergent-findings.md
	modified:   docs/tickets/ticket-000007-query-layer-hyphen-fold.md
	modified:   docs/tickets/ticket-000008-broad-quantifier-preflight-guard.md
	modified:   docs/tickets/ticket-000009-quantifier-preflight-dag-binding.md
	modified:   docs/tickets/ticket-000010-metacognition-preflight-guard.md
	modified:   docs/tickets/ticket-000011-soft-preflight-hint-sidecar.md
	modified:   scripts/backfill_concepts.py
	modified:   scripts/bench_emergent.py
	modified:   tests/crawler/test_async_web_fetcher.py
	modified:   tests/crawler/test_bridge.py
	modified:   tests/crawler/test_web_fetch.py
	modified:   tests/test_bench_qa_sweep.py
	modified:   tests/test_burn.py
	modified:   tests/test_burn_doc.py
	modified:   tests/test_claim_lattice.py
	modified:   tests/test_cli_render.py
	modified:   tests/test_compress.py
	modified:   tests/test_concepts.py
	modified:   tests/test_dag.py
	modified:   tests/test_directives.py
	modified:   tests/test_distill.py
	modified:   tests/test_distill_recursive.py
	modified:   tests/test_evict.py
	modified:   tests/test_frame.py
	modified:   tests/test_grok_source.py
	modified:   tests/test_html_source.py
	modified:   tests/test_ingest.py
	modified:   tests/test_inspect.py
	modified:   tests/test_journal.py
	modified:   tests/test_keys.py
	modified:   tests/test_llm_context_base.py
	modified:   tests/test_merkle.py
	modified:   tests/test_mesh.py
	modified:   tests/test_mesh_aead.py
	modified:   tests/test_mesh_chain.py
	modified:   tests/test_mesh_cli.py
	modified:   tests/test_mesh_cli_pull.py
	modified:   tests/test_mesh_wire.py
	modified:   tests/test_mesh_wire_e2e.py
	modified:   tests/test_metacognition.py
	modified:   tests/test_migration_audit_mode.py
	modified:   tests/test_providence_source.py
	modified:   tests/test_qa.py
	modified:   tests/test_qa_quality_live.py
	modified:   tests/test_quantifier_caps.py
	modified:   tests/test_quantifier_classifier.py
	modified:   tests/test_quantifier_phase4.py
	modified:   tests/test_quantifier_reminder.py
	modified:   tests/test_query.py
	modified:   tests/test_reclassify.py
	modified:   tests/test_repair.py
	modified:   tests/test_resume.py
	modified:   tests/test_snapshot.py
	modified:   tests/test_soft_preflight.py
	modified:   tests/test_tfidf.py
	modified:   tests/test_vcs_source.py
	modified:   tests/test_verify.py
	modified:   tests/test_verify_json.py
	modified:   tests/test_versioned_ingest.py
	modified:   tests/test_warrant.py
	modified:   tests/test_wikipedia_old.py
	modified:   tests/test_wikipedia_xml.py
	modified:   tests/test_wikitext.py
2026-05-07 09:31:49 -04:00
549f491218
docs: 'The permacomputer' → 'Our permacomputer' (CLAUDE.md style rule)
Per shared-things convention: prefer 'our' for community-owned things;
'the' implies fixed singular ownership. The permacomputer is collective
infrastructure, so 'our' fits better than 'the'.

Updated three places (single canonical preamble text):
- LICENSE (Permacomputer Preamble section, our text — not the AGPL)
- README.md License section
- docs/_source/conf.py rst_epilog (per-page footer on RTD)
2026-05-04 09:23:06 -04:00
13ada91997
docs: restore default sphinx-book-theme layout (project TOC on left)
Previous attempt to move the full project TOC to the right via
html_sidebars={'**': []} stripped the theme's left sidebar — the right
sidebar in sphinx-book-theme renders only page-local TOC, not the
project tree, so the project structure disappeared and the page
looked unthemed.

Restore the default layout:
- Left: full project toctree (themed sphinx-book-theme sidebar)
- Right: 'On this page' (current page sections), expanded to depth 3

If we want a unified right-side project TOC later, that needs
pydata-sphinx-theme + secondary_sidebar_items override, not just
hiding the left.
2026-05-04 09:20:25 -04:00
6ad0c9d8e3
docs: switch to sphinx-book-theme for unified right-side project TOC
sphinx_rtd_theme only renders left-side navigation. Switch to
sphinx-book-theme which puts the full project TOC on the right and
leaves the reading area centered.

conf.py:
- html_theme = 'sphinx_book_theme'
- html_sidebars = {'**': []} hides the left sidebar so the right TOC
  is the single navigation surface
- show_toc_level=3 expands subpages; show_navbar_depth=2 controls top nav

requirements.txt: sphinx-rtd-theme → sphinx-book-theme>=1.1
2026-05-04 09:13:14 -04:00
850e59d16e
trim Makefile (-6 redundant targets) + better RTD docs
Makefile cuts (64 → 58 documented targets):
- ingest-cur-parallel, ingest-old-parallel: parallel-shared mode
  superseded by attached (no WAL contention)
- distill-shards: sequential never preferred over parallel variant
- bench-qa-quick: bench-qa-smoke covers same use case (~30s vs ~10s)
- ingest-grok, ingest-grok-media: single-DB grok rare; -attached is
  canonical path

All cuts land in code that the underlying CLI still exposes — operators
who need the dropped variant call '.venv/bin/aborist ingest --shard ...'
directly. No behavior loss, just shortcut removal.

Docs improvements:
- New Concepts page (docs/_source/concepts.rst): orientation on what
  aborist is, three layers (surface/core/providence), Merkle commitment,
  8-dim cache key, audit chain, trichotomy + four-rung ladder, layered
  verifier, falsification state, sidecars. Embeds module-graph and
  verifier-ladder SVG diagrams.
- New Cookbook page (docs/_source/cookbook.rst): 8 recipes — recrawl,
  falsify, ingest-self-providence, mixed-corpus query, LLM endpoint
  override, integrity after bulk ops, bench, retrieval tuning.
- Quickstart embeds query-pipeline SVG diagram.
- docs/_source/diagrams symlinks to docs/diagrams so Sphinx can include
  the SVGs (was orphaned, only README referenced them).

Better Makefile RTD page (docs/_source/_ext/makefile_targets.py):
- Group by workflow phase (Setup → Fetch → Ingest → Distill → Query →
  Verify → Operations → Tests → Docs → Clean) instead of alphabetical
  prefix. Tells a new operator the order they'd actually run things.
- Phase descriptions added; targets prefixed with 'make ' for copy-paste.
- Uncategorized leftover surfaces missing entries in PHASES list.
2026-05-04 09:03:03 -04:00
09fb5e4f2d
docs: add Quickstart page to RTD
New docs/_source/quickstart.rst — install, two end-to-end paths
(Wikipedia 2003 + crawler), after-the-answer commands, query pipeline
overview, and links to deeper reference pages. Mirrors the README's
quickstart but adapts cross-references to the Sphinx structure.

Added to index.rst as a 'Getting started' toctree section above the
API modules — RTD users land on it first.
2026-05-04 08:50:31 -04:00
83197a6247
docs: switch Sphinx theme from furo to sphinx_rtd_theme
Use the canonical Read the Docs theme. Build dropped from 33 warnings
to 3 (most furo warnings were sidebar template lookups in the dark/light
mode switcher).

requirements.txt updated to pull sphinx-rtd-theme instead of furo.
2026-05-04 08:41:37 -04:00
744a8b19c7
docs: add license page + per-page Permacomputer Preamble footer
- docs/_source/license.rst — new RTD page that literalincludes the
  repo's LICENSE file (single source of truth, no duplication)
- conf.py rst_epilog — appended to every RST source so every doc page
  carries the Permacomputer Preamble + AGPL-3.0-only notice + link to
  the full license
- index.rst — adds 'Project / License' section to the toctree

The LICENSE file already had the full Permacomputer Preamble + complete
GNU Affero GPL v3 text (matches the whitepaper version).
2026-05-04 08:38:24 -04:00
546fa6d690
docs: auto-generate Makefile reference page for RTD
Adds a Sphinx extension at docs/_source/_ext/makefile_targets.py that
parses the project Makefile's '## description' annotations and writes
docs/_source/api/makefile.rst at build time. Same convention 'make help'
uses, so the reference stays in sync with the source.

Generated page is grouped by target prefix (fetch-, ingest-, distill-,
docs-, etc.) and rendered as a list-table. Shows on RTD alongside the
autodoc API modules.

Generated file is gitignored — RTD regenerates on every build.
2026-05-04 08:26:27 -04:00
8e9e993571
docs: add Read the Docs configuration
Add .readthedocs.yaml at project root so docs.aborist (or
aborist.readthedocs.io) can build the Sphinx API reference on push.

Configuration:
- Ubuntu 24.04, Python 3.13
- Sphinx config: docs/_source/conf.py
- Build deps: docs/_source/requirements.txt (sphinx, furo)
- Install package with [html, wikitext] extras so autodoc imports succeed

Cleanup:
- Untrack docs/_source/_build/ (generated artifact, RTD builds on push)
- Add _build/ to .gitignore
- Create docs/_source/_static/ placeholder (Sphinx convention)
- Remove non-functional html_sidebars override from conf.py
  (furo defaults are better; build now produces 0 warnings vs 29)
2026-05-04 08:17:24 -04:00
f5a216a335
docs: fix inaccurate docstrings caught in contextual review
Initial docstring pass focused on syntax/style; this pass verified each
docstring against actual function behavior. Found and corrected:

WRONG (claimed behavior didn't match):
- _cmd_verify: claimed Q&A/audit verification — actually round-trips
  Merkle proofs on N random documents
- _cmd_snapshot_verify: claimed Merkle proof round-trip — actually
  re-derives snapshot root and checks for drift
- _cmd_evict: claimed 'archive unused content' — actually NULLs content
  and removes FTS row; cores never evict
- _cmd_stats: listed 'index size' which is not in stats() output

OVERSTATEMENT (claim stronger than contract):
- _cmd_ask: 'grounded answer' — verifier may return UNGROUNDED
- _cmd_snapshot_list: 'named' — snapshots have hash roots, not names

MISSING IMPORTANT BEHAVIOR:
- _cmd_rehydrate: didn't mention drift-detection exit code
- _cmd_mesh_status: didn't mention 'enabled' flag (most important field)
- _cmd_distill: didn't mention recursive core→core distillation
- MerkleTree.proof(): didn't mention IndexError on out-of-range

VAGUE:
- _cmd_search: 'Search the corpus with FTS5' → mention output formats

Sphinx rebuild successful (29 warnings, down from 31).
2026-05-04 08:13:13 -04:00
49607a5997
docs: add Sphinx API reference generation from docstrings
Implements Read the Docs infrastructure to generate API documentation
directly from code docstrings. Replaces static modules.md (1200+ lines).

New structure:
- docs/_source/conf.py — Sphinx configuration (furo theme)
- docs/_source/index.rst — Main TOC
- docs/_source/api/*.rst — Module groups (substrate, storage, retrieval,
  qa, distill, mesh, cli)
- docs/_source/Makefile — Local build targets
- docs/_source/README.md — Documentation on building and extending

Makefile integration:
- make docs-api — generate HTML (output: docs/_source/_build/html/)
- make docs-api-clean — remove build artifacts

Build output (40 HTML files):
- API module reference with docstrings
- Source code links (:viewcode: extension)
- Full-text search index
- Module index (genindex, py-modindex)

Sphinx installed in venv as dev dependency. HTML is browseable at
docs/_source/_build/html/index.html (open in browser after build).

This justifies the deletion of modules.md: code docstrings + Sphinx
autodoc = automatically-generated, always-current API reference.
2026-05-04 07:55:34 -04:00
bb6a89c7d4
docs: remove 7 non-load-bearing docs (30% reduction)
Delete redundant, superseded, or design-log docs:
- qa-modes-bench-2026-04-30: prior snapshot (rolling journal is current)
- verifier-semantic-gap-design: unimplemented future proposal
- bench-emergent-design: stress-test design (script self-documents)
- modules.md: API reference (code + docstrings are source of truth)
- self-reference-design: v1 shipped, v2 scoped to future; history in git
- concept-relations-design: live system documented in code
- mesh-deploy: runbook for off-by-default system; mesh wire future work

Reduces docs/ from 23 files to 16, keeping north-star (seven-point-program),
architecture (cti, mesh.md), and operational docs (benchmarks, qa-modes-bench,
bench-maxing). All deleted docs recoverable from git history.
2026-05-04 07:43:10 -04:00
17d637e99f
docs: add docs/benchmarks.md — orientation doc for bench harnesses
Single canonical entry point that ties together the four existing
bench-related docs (qa-modes-bench.md / bench-maxing.md /
bench-emergent-design.md / qa-modes-bench-2026-04-30.md) plus the
make targets, fixtures, and bench-row schema.

Sections:

  1. Two harnesses, two purposes
     bench/qa_sweep.py — curated regression bench
     scripts/bench_emergent.py — random-word stress test

  2. Four question fixtures (75 / 28 / 9 / 1 / smoke) with cell
     sizes + use cases per fixture

  3. Signal floor (5pp / n=3 × 9 = 27 / vLLM c=3-4 saturation)

  4. Make targets cheat sheet (bench-qa, bench-emergent,
     --policy KEY=VALUE A/B pattern, --resume)

  5. Bench-row schema — every field a row carries
     (identity / verdict / diagnostics / preflight projection /
     quantifier classifier / capacity / directive compliance / time)

  6. Where headlines live (qa-modes-bench.md addenda, per-ticket
     §12/§13 bench sections)

  7. bench-emergent log shape + #000006 rolling-amend pattern

  8. How to run a focused A/B (the four-cell pattern from #000008)

  9. How to interpret results (STRICT-rate, mean-ratio,
     UNGROUNDED-rate, FORMAT_COLLAPSED rate, violation kind
     distribution, audit-line tails)

  10. Operator commands cheat sheet (--show-preflight,
      --apply-quantifier-caps, --reject-broad, --soft-preflight,
      Makefile shortcuts)

CLAUDE.md docs index updated to point to benchmarks.md as the
"read first" entry for bench work, and to add bench-emergent-design.md
to the index (was missing).
2026-05-04 07:05:46 -04:00
453e340e08
ticket(#000006): 300-cycle update — zero false-positive STRICT post-hardening
Bench-emergent stress test ran another 100 cycles under the
post-#000008/9/10/11 substrate. Total accumulated: 300 cycles.

Verdict distribution shift on last 100 vs 134-cycle baseline:

  STRICT      5% (7/134)  →  0% (0/100)   -5pp
  HYBRID      22% (29/134) →  16% (16/100) -6pp
  UNGROUNDED  73% (98/134) →  84% (84/100) +11pp

Zero false-positive STRICTs across 100 random-word triplets.

The 5pp drop in STRICT-rate isn't a regression — it's the
verifier ladder + new preflight contracts doing their job.
Random-word triplets are genuinely ungrounded for the most
part; the prior 5% STRICT rate included false-positives that
the post-hardening verifier now catches.

Violation profile (last 100 cycles, claim_lattice JSON):
  CITATION_MISMATCH:      86  dominant gate
  TOO_MANY_EVIDENCE_IDS:  24
  SUBJECT_TOKENS_ABSENT:  12  Rule 9 firing on parroting
  DEFLECTION_DETECTED:    12
  TITLE_MISMATCH:         10
  ...

metaphor_deflection fires 6/100 — still rare. Item 3
(calibration) is now closer to sample-size threshold (~30
signals across 300 cycles; needs ~50-100 to calibrate).

No new tuning candidates surface. Original three remain at
their resolution states.
2026-05-03 23:16:45 -04:00
a94d6a3244
qa(#000011 + 4 more): SOFT_PREFLIGHT_HINT impl + 5-task fan-out
Big batch — closes 4 of the 5 deferred items from the prior status
report plus opens & implements a previously-deferred design ticket
(#000011) zero-shot.

#000025 — Metacog test fixture expansion:
  bench/qa_questions_metacog_subset.txt grows from 6 → 28 questions
  covering edge cases per detector kind: temporal (4 cases),
  contradiction (4), false-premise (5), out-of-corpus (3), multi-
  trigger (2), well-formed controls (5). Documents two known
  detector ceilings: Q11 over-fires on past-tense factoid
  ("who was the first president"); Q16/Q17/Q19 (Edison/Australia/
  NASA-fake) miss false premises that lack a presupposition
  pattern match. Fixture now serves as long-term regression suite.

#000026 — --show-preflight full clause render:
  build_run_dag() and build_reject_run_dag() gain optional
  preflight_payload kwarg. When supplied, the canonical 5-clause
  CTI payload (classifier / answer_contract / prompt_contract /
  evidence_contract / policy_refs + question_state + node_version)
  persists alongside the leaf hash in run_dag_blob.
  aborist providence --show-preflight CACHE_KEY now renders the
  full payload + verifies the persisted hash matches the
  recomputed canonical hash (audit-replay tamper detection).
  Legacy rows fall through cleanly: payload_hash_check reports
  "unavailable: legacy row predates preflight_payload persistence".

#000027 — Latency profile:
  Microbenched preflight: 0.46ms/question (negligible). Single
  fresh call breakdown: search 2.4s, llm 2.8s, total 5.4s — the
  33-35s in Addendum 3 was vLLM concurrency contention at c=4
  (per qa-modes-bench.md saturation note), not substrate
  overhead. Added preflight_ms + soft_preflight_ms to timings
  dict for explicit confirmation in future cycles.

#000028 — Auto-quality-check sweep revival:
  scripts/bench_emergent.py running with EMERGENT_N=100 in
  background (PID 125680). Will accumulate cycles into
  bench/emergent_log.jsonl for #000006 rolling log re-aggregation.
  Async — not blocking on completion.

#000029#000011 SOFT_PREFLIGHT_HINT implementation:
  aborist/qa/soft_preflight.py — new module. SoftPreflightHint
  dataclass + soft_preflight_question() pure function. 9
  canonical labels mapping to soft analogues of #000010 hard
  detectors plus 2 stub states (SOFT_DISABLED, SOFT_PARSE_FAIL).
  Constrained-generation prompt (max_tokens=128, temp=0.0) asks
  the model to pick ONE label + one-line rationale.
  Fail-closed across every parse path:
    - chat_client raises → SOFT_PARSE_FAIL
    - response unparseable → SOFT_PARSE_FAIL
    - label outside enum → SOFT_PARSE_FAIL
  Sidecar enforces SOFT_ prefix at the normalize step so a
  model that drops the prefix still gets caught.

  Wired into query() between preflight & retrieval. Default
  OFF (`soft_preflight_enabled: False`). NOT folded into
  _VERIFIER_POLICY_FIELDS — soft hints don't gate cache
  identity (#000011 §4). Audit-line tail renders as
  "· soft: <label>" (e.g. "· soft: time sensitive") so the
  signal is visually distinct from hard tails.

  --soft-preflight CLI flag opts in per-call. End-to-end
  live-verified on "When did Mr. Burns become Homer's biological
  father?" — produces:

    EVIDENCE-WARRANTED · via claim_lattice
        · false premise · soft: time sensitive
        1/1  16.4s

  Hard `· false premise` (from #000010 deterministic detector)
  composed with soft `· soft: time sensitive` (from #000011
  sidecar). The model classified a different shape than the hard
  detector — by design; soft hints are independent advisory
  signals, not redundant with the hard layer.

  25 new tests pin: default-OFF behavior, parse-failure modes,
  label normalization (SOFT_ prefix enforced), all 8 actionable
  labels round-trip, fail-closed on client exceptions, dataclass
  JSON round-trip, rationale-length cap.

Other:
  - #000010 §13.3 documents 2/5 metacog-trigger questions return
    STRICT despite hard-detector warning — direct empirical
    motivation for #000011 design.
  - tests/test_dag.py extends with 3 _extract_preflight_hash_*
    helper tests (cleaning #000009 §7.2 unfinished state).
  - bench/emergent_log.jsonl adds new cycles from background run.

#000011 status: closed. Hard rule (D1) preserved across all
1021 tests (up from 996, +25 new). Soft preflight is purely
advisory; the verifier proof path is unchanged.
2026-05-03 23:00:56 -04:00
621f0b2cda
docs+code: 5-task fan-out — preflight_hash field, --show-preflight CLI, frame plumbing, metacog bench, #000011
Fan-out execution of the deferred-but-not-blocking pile from
prior status reports.

#000009 §7.2 — bench harness preflight_hash field:
  - aborist/qa/query.py surfaces `preflight_hash` on result dict
    (miss path, reject path, and cache-hit path via new helper
    `_extract_preflight_hash_from_blob` that pulls the stage hash
    out of persisted run_dag_blob).
  - bench/qa_sweep.py adds 12-char preflight_hash prefix to bench
    rows. Mirrors cache_key truncation pattern. Operators can
    grep / SQL-filter bench JSONL by preflight policy state.
  - 3 new tests in tests/test_dag.py for the extract helper.

#000009 §7.2 — `aborist providence --show-preflight CACHE_KEY_PREFIX`:
  - New CLI flag pulls the preflight stage payload from a row's
    run_dag_blob. Match by 12-char prefix. Renders preflight stage
    hash + run-DAG stage list. Operator tool for inspecting which
    policy state governed a cached row.
  - Live verified on a real cache row (8a212fecb2a9 — current CEO
    of OpenAI question, 10-stage CTI shape with preflight at idx 1).
  - Legacy rows (predating #000009) report a clean fall-through
    message: "run_dag has no preflight stage (predates #000009)".

#000010 §12.6 — reference-frame plumbing into QuestionState:
  - Pre-retrieval preflight runs with reference_frames=()
    (frame_detection needs source titles, not available yet).
    Post-retrieval, query.py re-runs preflight_question() with
    the detected frames so the result-dict + run-DAG QuestionState
    carry frame-aware logical_statuses (specifically
    `reference_frame_ambiguous` when 2+ frames match).
  - Live verified on Orwell-style question; logical_statuses now
    correctly includes `reference_frame_ambiguous` in the result.

Metacog-trigger bench fixture (#000010 §13.3):
  - bench/qa_questions_metacog_subset.txt — 6 questions, one per
    detector kind plus a well-formed control.
  - Bench artifact 2026-05-04T02-18-42Z. Detector accuracy 6/6
    on fixture; 2 of 5 trigger questions return STRICT on lattice
    mode despite metacog warning (JSON STRICT on
    George-Washington-stop-being-president-of-France false-premise
    + uploaded-contract out-of-corpus questions). Audit-line tails
    correctly surface the warnings.
  - qa-modes-bench.md Addendum 4 captures the per-question matrix
    + interpretation. #000010 §13.3 cross-references with bench
    artifact stamp.

#000011 SOFT_PREFLIGHT_HINT design ticket opened:
  - docs/tickets/ticket-000011-soft-preflight-hint-sidecar.md
    captures the design proposal per #000010 §18 / source doc.
    Implementation deferred — design only.
  - Sidecar would add model-assisted preflight as a soft signal
    (`SOFT_FALSE_PREMISE_SUSPECTED` etc.) that NEVER enters the
    verifier hard path. Strict guardrail: cannot create
    PREFLIGHT_OK or PREFLIGHT_BLOCKED without deterministic
    support.
  - Validated by §13.3 finding: deterministic detectors flag
    correctly; corpus-accidental grounding produces 2/5 STRICT
    on trigger questions; soft sidecar would add independent
    semantic skepticism.
  - TICKETS.md index row added; Next ID bumped to 000012.

996 tests passing (3 new for the extract helper).

Cross-doc consistency:
  - qa-modes-bench.md Addenda 1+2+3+4 chronological
  - #000010 §13.1 (broad subset) + §13.2 (full bench) + §13.3
    (metacog trigger subset)
  - #000011 design captured but not implemented
2026-05-03 22:28:18 -04:00
4c38bdebc1
docs: full-bench validation in #000010 §13.2 + seven-point-program
Cross-references the 2026-05-03T23-30-12Z full 75-question
regression bench (Addendum 3 in qa-modes-bench.md) into:

  - #000010 §13.2 — full-bench validation alongside the §13.1
    broad-subset validation. Same verdict: defaults stay on.
    Substrate-level wins beyond noise-bounded SR deltas:
      pointer FORMAT_COLLAPSED: 0/225 (eliminated globally)
      pointer NO_EVIDENCE_POINTER: 13% (down from 33% broad-only)
      JSON mean ratio: +3pp

  - seven-point-program.md addendum — bench-validation paragraph
    after the test-count line. Names the SR deltas + the
    substrate-level wins; concrete evidence the post-landing
    directive coverage claim survives full-corpus measurement.

No code changes; 993 tests still passing.
2026-05-03 21:50:33 -04:00
3bd36f36c8
bench: full 75-question regression check — no regression from #000010
Addendum 3 to qa-modes-bench.md. Validates that flipping
quantifier_reminder_enabled=True for lattice modes (per #000010
§12.10 / §13.1) doesn't regress narrow-question performance.

Prior validation (Addendum 2) covered the 9-question broad subset
only. This run sweeps the full 75-question bench/qa_questions.txt
(~10% broad, ~89% narrow), 225 runs per mode, comparing against
the frozen 2026-05-02T15-07Z baseline.

Findings:

  Mode      | Pre-flip SR | Post-flip SR | Δ
  ----------+-------------+--------------+--------
  quote     | 0.54        | 0.52         | -2pp (within 5pp floor)
  pointer   | 0.20        | 0.21         | +1pp
  JSON      | 0.42        | 0.44         | +2pp

  Mean ratio: -1/+2/+3pp — all within noise band.

Substrate-level wins beyond the headline metrics:
  - pointer FORMAT_COLLAPSED: 0/225 across the full sweep.
    Reminder eliminates collapse mode globally, not just on broad.
  - pointer NO_EVIDENCE_POINTER: 13% (vs 33% on broad-only when
    reminder was off). Citation discipline propagates beyond the
    rows where the reminder text actually fires — the model's
    session attention reinforces.
  - JSON mean ratio +3pp consistent with broad-subset finding.

Quote-mode is essentially unchanged because it's mode-gated off
the guard by default.

Latency 33-35s/call this evening (vs 17-19s in prior runs) is
endpoint contention, not a substrate regression — preflight adds
zero LLM calls.

Verdict: no regression. The default flip ships clean across the
full corpus. Defaults stay on. The substrate is strictly more
honest (FORMAT_COLLAPSED → 0, NO_EVIDENCE_POINTER ↓) without
sacrificing throughput on non-broad questions.

Bench artifact: bench/qa_results/2026-05-03T23-30-12Z.{jsonl,md}.
2026-05-03 21:07:56 -04:00
cd0e8ef64f
bench(#000010): preflight on-vs-off validation — defaults stay on
Post-landing validation cell. Same 9-question broad subset as
§12.6 reminder-only baseline; this run flips both
metacognition_enabled and quantifier_reminder_enabled to False so
we can isolate the preflight contribution.

  Metric                    | OFF       | ON       | Δ
  --------------------------+-----------+----------+----------
  pointer mean ratio        | 0.483     | 0.643    | +16pp
  JSON mean ratio           | 0.570     | 0.735    | +17pp
  JSON UNGROUNDED rate      | 7/27      | 1/27     | -22pp
  pointer FORMAT_COLLAPSED  | 2/27      | 0/27     | -100%
  any-mode STRICT-rate      | within ±11pp noise (27-sample n=3 floor)

Mean-ratio + UNGROUNDED + FORMAT_COLLAPSED metrics all clear the
5pp signal floor on lattice modes. STRICT-rate moves are within
Hermes nondeterminism. The #000010 default flip is doing what
was claimed.

On this subset none of the metacognition detectors fire (no
temporal / contradiction / false-premise / out-of-corpus shapes),
so the delta effectively isolates the reminder contribution from
#000008. A metacog-trigger subset bench is deferred.

Documentation:
  - docs/qa-modes-bench.md Addendum 2 captures the comparison
    table + interpretation + verdict.
  - docs/tickets/ticket-000010-... §13.1 cross-references with
    bench artifact stamp.

Bench artifact: bench/qa_results/2026-05-03T23-06-21Z.{jsonl,md}.
2026-05-03 19:26:33 -04:00
de07ad9392
docs: distill #000008+#000009+#000010 into core docs + diagrams
Three Explore agents fanned out in parallel for a docs/ + diagrams/
+ code-comment audit against the shipped state of the three
preflight tickets. This commit lands all the alignment fixes.

Core docs updates:

  CLAUDE.md
    - dag.py module description: stage counts now read
      "7/8 quote · 9/10 CTI · 3 reject" reflecting #000009 preflight
      stage + reject-broad early-return shape.

  docs/cti-architecture.md §2.2 + §2.3
    - §2.3 Merkle-AGI-DAG section rewritten: documents all five DAG
      shapes (legacy 7/9, post-#000009 8/10, reject-broad 3),
      describes the preflight stage's 5 nested CTI clauses
      (classifier / answer_contract / prompt_contract /
      evidence_contract / policy_refs), pins
      PREFLIGHT_NODE_VERSION = "preflight-node-v1", states the
      audit-replay payoff.
    - §2.2 CTI section: adds the four new modules
      (quantifier, model_profiles, quantifier_reminder,
      metacognition) as code anchors. Notes that pre-answer
      preflight contract extends CTI upstream of retrieval.

  docs/seven-point-program.md
    - D3 status ½ → ¾ — pre-answer preflight contract landed via
      #000008 + #000010. Code anchors + pinning tests updated.
    - D4 status ½ → ¾ — preflight stage adds upstream control
      commitment to the run-DAG. Code anchors include
      build_reject_run_dag + preflight_node_hash.
    - Status snapshot table: tickets column now references
      #000008/#000009/#000010 against D1/D3/D4 directives.
    - "Post-landing addendum (2026-05-03 / 2026-05-04)" subsection
      summarises all three tickets + their commit shas + final
      test count (993 passing, up from 734).

  docs/modules.md
    - Q&A pipeline table: added 4 new modules (quantifier.py,
      model_profiles.py, quantifier_reminder.py, metacognition.py).
      dag.py row updated to "7/8 quote · 9/10 CTI · 3 reject".
    - dag.py subsection rewritten: documents all 5 DAG shapes,
      describes the preflight payload's 5 clauses + question_state.
    - 4 new module subsections (quantifier / model_profiles /
      quantifier_reminder / metacognition) explaining each
      module's purpose, signature, and how it feeds the run-DAG
      preflight clause.

Diagram updates:

  docs/diagrams/query-pipeline.dot + .svg
    - New "PREFLIGHT (#000008 + #000010)" node inserted between
      cache_check and concepts_lookup.
    - New "REJECT-BROAD" node showing the 3-stage minimal DAG
      escape path.
    - render node label extended with the audit-line tail token
      catalog.

  docs/diagrams/aborist-modules.dot + .svg
    - 4 new qa_* nodes in the retrieval & verifier cluster.
    - 8 new edges: qa_query/qa_runner each call into all 4
      preflight modules; qa_dag has dotted edges to qa_quantifier
      + qa_metacognition (preflight clause sources).
    - qa_dag label updated to mention preflight_node_hash + 5 clauses.

  docs/diagrams/verifier-ladder.dot + .svg
    - Soft-demote violations list extended: BROAD_QUANTIFIER_RUNAWAY
      / CAP_APPLIED / SCOPE_UNBOUND, FORMAT_COLLAPSED, BARE_NAME_CLAIM.
    - New "AUDIT-LINE TAILS" annotation node listing all 11 tail
      tokens (#000008 broad-* + #000010 metacog + classic verifier).
    - Dashed edges from each rung to tails note showing tails
      compose onto labels.

Code-side stale-comment fixes (caught by 3rd Explore agent):

  aborist/qa/keys.py:218
    - "The four fields" → "The seven fields"; mention #000010 adds
      six more for metacognition.
  aborist/qa/query.py:2644
    - 7-stage / 9-stage comment expanded to enumerate all four
      base+preflight shapes plus the 3-stage reject path.
  aborist/qa/runner.py:835
    - same expansion as query.py for runner.ask() callsite.

mesh-*.dot, ingest-pipeline.dot, qa-modes-bench.md, bench-maxing.md,
bench-emergent-design.md, verifier-semantic-gap-design.md,
self-reference-design.md, concept-relations-design.md confirmed
orthogonal — no edits needed.

993 tests still passing (no behavior change). 7 files modified
across docs/ + 3 dot diagrams + 3 SVGs + 4 code-comment fixes.
2026-05-03 19:18:22 -04:00
111dda6160
qa(#000009): §8 corrections — reject-path DAG + nested CTI clauses
Architectural feedback at ~/Downloads/RESPONSE-ticket-000009-... .txt
(2026-05-04) flagged five gaps in the c36e85c landing. Most
critical: reject-broad early-return path emitted no run_dag_blob,
so audit replay couldn't see that a rejection happened (let alone
under what policy state).

A — reject-path DAG (the critical gap):

  aborist/qa/dag.py: build_reject_run_dag() — 3-stage minimal DAG
  question → preflight → final_label. final_label payload carries
  rejection_reason + answer_text_hash so two rejections under
  different policy state produce different roots.

  query.py reject path now wires it: returns run_dag_root +
  run_dag_blob on the rejection result dict. Live-verified end-
  to-end on `make query Q="winners of all major sports?"
  REJECT_BROAD=1 BURN=1`.

  Audit replay rule: 3 stages always means reject path. Operators
  can read the stage list and tell instantly without parsing the
  payload.

B — nested CTI clauses:

  preflight_node_hash() payload restructured from flat 3-key to
  nested 5-clause:

    classifier        — quantifier classifier output (#000008)
    answer_contract   — guard / cap / reject / metacog state (per-run)
    prompt_contract   — reminder enabled / injected / template_id
    evidence_contract — exposure budget, line discipline
    policy_refs       — governance_policy_hash, model_profile_hash,
                        answer_mode (reference, not raw policy)

  Plus question_state (metacog) as its own clause and top-level
  stage + node_version. Single DAG stage; nested clauses inside
  for diff legibility (feedback §3).

C — node_version field:

  PREFLIGHT_NODE_VERSION = "preflight-node-v1" pinned in the
  payload so legacy runs without the node can be unambiguously
  labeled `unavailable_legacy_run` by audit tools (feedback §9).

D — reference hashes only:

  policy_refs uses governance_policy_hash + model_profile_hash
  rather than bundling raw policy booleans. Avoids
  double-committing already-hashed state (feedback §4).

E — reminder_template_id:

  prompt_contract.reminder_template_id = "broad-quantifier-bounded-v1"
  or "broad-quantifier-unbounded-v1" depending on scope_bound_hint,
  populated only when reminder actually fires.

F — stage name kept as `preflight` (not `quantifier_preflight`):

  Node carries both #000008 quantifier AND #000010 metacognition
  payloads. node_version disambiguates schema for audit tools.

G — docs/cti-architecture.md update deferred to a small follow-up.

Bug fixes:
  - free-variable shadowing on verifier_policy_hash /
    model_profile_hash / question_hash — local re-imports inside
    the reject branch shadowed module-top imports used elsewhere
    in query() / runner(); now use the module-top names.
  - reject path question_hash signature: takes `mode=` not
    `dedup_mode=` — fixed in the reject DAG builder caller.

Hash compatibility:
  Rows written between c36e85c and this commit have hash payloads
  matching the OLD flat 3-key shape. The persisted run_dag_blob
  captures the actual payload that was hashed, so those rows
  still verify via verify_run_dag(). New rows use the nested
  5-clause shape.

7 new tests in tests/test_dag.py:
  - hash sensitivity to answer_contract / prompt_contract /
    policy_refs flips (audit-replay payoff demonstrations)
  - PREFLIGHT_NODE_VERSION pinning
  - reject DAG: 3-stage shape, root changes with preflight hash,
    round-trips through verify_run_dag

993 tests passing (6 net new); 36 skipped.

Live verification:
  make query Q="winners of all major sports?" REJECT_BROAD=1 BURN=1
  → status=broad_quantifier_rejected, run_dag_root populated,
    blob carries 3-stage shape.

  make query Q="winners of all major sports?" BURN=1
  → 10-stage shape preserved (question → preflight → retrieval
    → ... → final_label).

Ticket #000009 status: closed · re-landed 2026-05-04 with §8
corrections.
2026-05-03 18:49:56 -04:00
c36e85c86c
qa(#000009): preflight stage binds into run_dag_root
Closes ticket #000009 zero-shot. Scope expanded to cover BOTH
ticket #000008 (broad-quantifier) AND ticket #000010
(meta-cognition) preflight contracts in a single combined node —
both share the same audit-replay gap and inserting two separate
nodes between question and retrieval was operationally awkward.

aborist/qa/dag.py:
  + preflight_node_hash() — combines QuestionState +
    quantifier classifier output + behavioral policy_state into
    one canonical SHA-256 hex.
  + build_run_dag() gains optional preflight_hash parameter.
    When supplied, inserts {"stage": "preflight", "hash": ...}
    at position 1 (between question and retrieval).
    Backward-compat: None → original 7/9-stage shapes preserved
    for legacy run_dag_root re-validation.

  Quote-mode: 7 → 8 stages with preflight.
  Pointer-mode CTI: 9 → 10 stages with preflight.

aborist/qa/query.py + runner.py:
  Both build the preflight payload from question_state +
  quantifier dict + 10-field policy_state (guard_enabled,
  guard_apply_caps, guard_apply_caps_mode_gated,
  claim_cap_resolved, claim_cap_actually_applied,
  reminder_enabled, reminder_eligible, reject_broad_active,
  metacognition_enabled, block_on_contradiction).

  This means two cache rows that share the same question + same
  model output + same verifier verdict but DIFFERENT preflight
  policy state now produce different run_dag_root values. Audit
  replay can pin the policy decision per row.

9 new tests in tests/test_dag.py:
  - preflight_node_hash determinism
  - hash bumps on question_state change
  - hash bumps on policy_state change (the audit-replay payoff)
  - all-None defensive shape
  - 7→8 stage transition (quote mode)
  - 9→10 stage transition (pointer mode), preflight at index 1
  - run_dag_root bumps when preflight_hash bumps
  - verify_run_dag round-trips through preflight stage

Live verification: latest providence_cache row carries
['question', 'preflight', 'retrieval', 'evidence_map', 'prompt',
'raw_answer', 'parsed_claim_lattice', 'verify', 'render',
'final_label'] — preflight stage living in the persisted DAG.

987 tests passing (9 new); 36 skipped.

Tickets:
  #000009 status: closed · landed 2026-05-03 (zero-shot)
  #000010 cross-ref updated: "DAG binding shipped via #000009"

What's NOT in this ticket (logged in §7.2):
  - CLI flag for inspecting preflight node from cache_key
  - Bench harness preflight_hash field for cross-row comparison
  - SOFT_PREFLIGHT_HINT (model-assisted preflight sidecar)
2026-05-03 18:34:16 -04:00
f2bbe512db
qa(#000010): Phases 2-4 land — wired, governed, labeled, benched
Closes ticket #000010 (Meta-Cognition Preflight Guard). Mechanism
complete; defaults preserve the dry-run discipline pattern from
#000008.

Phase 2 — wire preflight into query() and runner.ask():
  - preflight_question() runs after policy resolution + quantifier
    classification, before retrieval.
  - QuestionState surfaces on miss path, cache-hit path, AND
    reject-broad early-return path of query() — schema column-
    aligned across all four returns.
  - runner.ask() carries the same fields for `aborist ask` parity.

Phase 3 — policy fields + governance hash + CLI flags:
  - 6 new policy fields, all default-on except
    metacognition_block_on_contradiction (default False — label-
    only by default; opt-in via --block-on-contradiction).
  - All 6 folded into _VERIFIER_POLICY_FIELDS so flipping any
    invalidates prior cache records on lookup.
  - 2 new CLI flags on `aborist query`:
      --no-preflight             Level 2 master kill
      --block-on-contradiction   strict mode (hard-block on
                                 lexical contradictions)

Phase 4 — audit-line labels + bench fields + tests:
  - _render_warrant_tail extended with 5 metacog tail tokens:
      · false premise
      · contradictory
      · stale risk
      · out of corpus
      · frame ambiguous
  - Bench rows in qa_sweep.py gain 7 new bounded-size projection
    fields (logical_statuses, question_shape, preflight_result,
    temporal_sensitivity, has_false_premise, has_contradiction,
    corpus_requirement). Full QuestionState stays on result dict
    for CLI render only.
  - tests/test_metacognition.py grew from 42 → 68 tests
    (16 new: 6 governance + 6 audit-line tail + 4 default-policy
    pinning).

Live verified end-to-end:

  $ make query-dry Q="Who is the current CEO of OpenAI?" BURN=1
    UNGROUNDED · via claim_lattice · stale risk
  $ make query-dry Q="When did Mr. Burns become Homer's biological
                      father?" BURN=1
    UNGROUNDED · via claim_lattice · false premise

978 tests passing; 36 skipped.

What's NOT shipped (deferred):
  - Run-DAG node binding for metacognition_preflight stage —
    joins ticket #000009 Phase 5 (same audit-replay gap; both
    nodes can land together).
  - Reference-frame plumbing — frame_detection runs post-retrieval,
    preflight here is pre-retrieval; deferred until two-pass
    or post-classification update lands.
  - SOFT_PREFLIGHT_HINT (model-assisted sidecar) — source doc §18
    reserves this label; hard rule preserved (no LLM in preflight
    hard path).
  - Bench A/B measuring preflight on vs off — quick to run once
    stack settles.

Ticket #000010 status: closed · landed 2026-05-03.
2026-05-03 18:22:18 -04:00
55efb04a58
qa(#000010): Phase 1 — metacognition.py module + 42 tests
Implements the Meta-Cognition Preflight Guard (M0 / MCTL) per
fox's directive at ~/Downloads/meta-cognition_for_hermes(1).txt
(2026-05-03).

aborist/qa/metacognition.py:
  - QuestionState dataclass (frozen, JSON-serializable via to_dict)
  - preflight_question() pure function: classifies a question
    deterministically into a QuestionState before generation
  - 4 new detectors:
      detect_temporal_sensitivity() — current/latest/today/CEO/etc.
      detect_contradiction()        — lexical pairs (unmarried+spouse,
                                      always+never, alive+dead, etc.)
      detect_false_premise()        — presupposition patterns:
                                      when did X stop/become Y,
                                      why did X cause Y,
                                      how did X become Y
      detect_out_of_corpus()        — my-uploaded-X / file-I-sent shapes
  - Reuses #000008 quantifier classifier (no duplication)
  - Composes 8 LogicalStatus values:
      well_formed, under_specified, false_premise_suspected,
      contradictory_question, out_of_corpus_risk, stale_risk,
      reference_frame_ambiguous, broad_quantifier_unbounded
  - Three preflight results: PREFLIGHT_OK / _PARTIAL / _BLOCKED
  - Per-detector enable switches in policy:
      metacognition_enabled (master kill)
      metacognition_temporal_check
      metacognition_contradiction_check
      metacognition_false_premise_check
      metacognition_out_of_corpus_check
      metacognition_block_on_contradiction (default False — label
                                            only by default; opt-in
                                            to hard-block)
  - preflight_policy_hash for governance binding (Phase 3)
  - PREFLIGHT_VERSION = "metacognition-v0.1"

Hard rule (D1): no LLM in this hard path. Pure regex + lexical
matching. Model-assisted preflight, if added later, labels itself
SOFT_PREFLIGHT_HINT (not implemented in this phase).

42 new tests cover the seven test cases from source doc §14
(false-premise, contradictory, broad-quantifier, reference-frame,
time-sensitive, out-of-corpus, model-cutoff) plus per-detector
unit tests, gating (master kill, per-detector disable,
block-on-contradiction opt-in), determinism (question_hash
stable, policy_hash bumps on flip), and serialization.

Ticket #000010 opened with status `open · in progress
(zero-shot 2026-05-03)`. TICKETS.md index updated; Next ID bumped
to 000011.

Phases 2-4 still queued (wire into query/runner, policy fields +
governance, audit-line labels + bench fields).

962 tests passing (42 new); 36 skipped.
2026-05-03 18:10:50 -04:00
08678173e1
ticket(#000008,#000009): close #8; open #9 for DAG binding; Makefile shortcuts
Closes #000008 with status `closed · landed in 4f2b5a6` per the
docs/TICKETS.md convention. The preflight guard mechanism + bench
cycle + default flip all shipped 2026-05-03; the design log stays
in place.

Opens #000009 — Quantifier preflight run-DAG node binding. Splits
the Phase 5 follow-up out of #000008 §11.11 into its own ticket.
Scope: bind the classifier output + policy decision into
`run_dag_root` so audit replay can distinguish guard-on vs guard-off,
cap-applied vs not, reminder-injected vs skipped. Currently those
appear on the result dict but are NOT in the run-DAG hash. Required
to close the audit-replay gap that blocks the §9.5 Merkle-AGI-DAG
framing from fully holding. Estimated 3-4h. Awaiting go/no-go.

Makefile shortcuts for the #000008 CLI flags (operator ergonomics):

  BROAD=1         → --apply-quantifier-caps  (flip cap apply-gate)
  REJECT_BROAD=1  → --reject-broad           (preflight rejection)
  ALLOW_BROAD=1   → --allow-broad            (emergent search)

Available on both `make query` and `make query-dry`. Default
behavior unchanged: ANSWER_MODE=claim_lattice (JSON), reminder ON
for lattice modes, cap operator-opt-in.

Smoke-tested:

  $ make query-dry Q="winners of all major sports?" BROAD=1
      → cap applies on JSON; classifier reports ALL/unbounded
  $ make query-dry Q="winners of all major sports?" REJECT_BROAD=1
      → preflight rejection, exit-1 (consistent with UNGROUNDED)

TICKETS.md index:
  #000008  closed · landed in `4f2b5a6`
  #000009  open · awaiting go/no-go (D3, D4)
  Next ID  bumped 000009 → 000010
2026-05-03 17:57:56 -04:00
4f2b5a6685
qa(#000008): §12.10 n=5 verification + §12.11 defaults flipped (Option A)
n=5 verification of cap+reminder cell (135 runs):

  Metric              | n=3       | n=5
  --------------------+-----------+------------
  JSON SR             | 0.30      | 0.33     ← matches cap-only
  JSON UNGROUNDED rate| 1/27 (4%) | 2/45 (4%) ← matches reminder-only
  pointer SR          | 0/27      | 0/45     ← unchanged across all cells

The §12.8 0.30 was Hermes nondeterminism. n=5 confirms cap+reminder
delivers cap-only's STRICT-rate AND reminder-only's UNGROUNDED-rescue.

§10.8 strict gate met at n=5:
  vs reminder-only on JSON SR:    +11pp (clears floor)
  vs cap-only on JSON UNGROUNDED: -18pp (clears floor)
  vs cap-only on ptr mean ratio:  +12pp (clears floor)

Defaults flipped — Option A landing (per-mode tailored):

  quantifier_reminder_enabled  False → True
                              (load-bearing on both lattice modes)

  NEW field: quantifier_apply_caps_modes = ["claim_lattice"]
                              (allowlist for which modes apply caps
                               when apply_caps=True; JSON-only since
                               cap-on-pointer is wasted noise per
                               §12.10 0/45 STRICT data)

  quantifier_guard_apply_caps  False → False (UNCHANGED)
                              (operator opts in via
                               --apply-quantifier-caps; preserves
                               §10.11.3 dry-run discipline)

Cap-application gate now reads:
  if apply_caps AND mode in apply_caps_modes AND cap is not None:
      effective_max_claims = looked_up_cap

quantifier_apply_caps_modes folded into _VERIFIER_POLICY_FIELDS so
flipping the allowlist invalidates prior cache records.

5 new tests pin: reminder default ON for both runner.DEFAULT_POLICY
and query.DEFAULT_QUERY_POLICY; apply_caps_modes default
["claim_lattice"]; governance-hash invalidation on allowlist flip;
apply_caps default still False (dry-run preserved).

920 tests passing (5 new); 36 skipped.

Operator behavior:
  $ aborist query "winners of all major sports?"
      → reminder ON, cap OFF (default after this commit)
  $ aborist query --apply-quantifier-caps "..."
      → cap applies on claim_lattice (JSON) only
  $ aborist query --apply-quantifier-caps \
        --policy quantifier_apply_caps_modes='["claim_lattice","claim_lattice_pointer"]' "..."
      → Option D for one call

Phase 5 (run-DAG node binding for quantifier_preflight) and
cross-model Qwen/GPT-4 verification remain as follow-ups per §11.11.
2026-05-03 17:25:38 -04:00
9780cca4d3
docs: §12.8/§12.9 cap+reminder verdict + cross-doc updates
#000008 §12.8 — Cap+reminder A/B (2026-05-03T12-54-11Z, 81 runs):

  Metric              | Base | Rem  | Cap  | Cap+Rem
  --------------------+------+------+------+--------
  JSON SR             | 0.19 | 0.22 | 0.33 | 0.30   ← cap-only wins SR
  JSON UNGROUNDED     |  7   |  1   |  6   |  1     ← rem dominates U-rescue
  pointer mean ratio  | 0.473| 0.643| 0.516| 0.684  ← cap+rem best
  pointer FORMAT_COLL |  2   |  0   |  2   |  0     ← rem-driven

§10.8 strict gate "compound beats either alone by ≥5pp on every metric"
NOT cleanly met. Cap+reminder beats reminder-only by +8pp on JSON SR
(clears floor) and beats cap-only by +17pp on pointer mean ratio
(clears floor), but is -3pp vs cap-only on JSON SR (regression,
within noise).

#000008 §12.9 — Final verdict + recommendation:

  Mechanism asymmetry (clean signal):
    Reminder rescues UNGROUNDED → HYBRID
    Cap rescues HYBRID → STRICT

  Recommendation: Option A — single-knob defaults, per-mode tailored:
    claim_lattice (JSON):   apply_caps=True + reminder=True
    claim_lattice_pointer:  apply_caps=False + reminder=True
                            (cap can't rescue pointer-tag discipline
                             upstream of cap; cap fires 20× without
                             verdict gain)
    quote:                  guard mode-gated off (already default)

  Caveat: n=3 × 9 = 27/cell variance is ~3-4pp; recommend n=5
  verification on cap+reminder before flipping defaults.

Cross-doc updates:

- CLAUDE.md: architecture diagram now lists the three new Phase 1-3
  modules (quantifier.py, model_profiles.py, quantifier_reminder.py).
  New "Broad-quantifier preflight guard" conventions entry covers
  the 7 policy fields, six-level disable hierarchy, dry-run
  defaults, CLI flags, and §12 bench summary.

- docs/qa-modes-bench.md: addendum at end pointing at #000008 §12
  four-cell A/B + 4 bench artifact stamps. Original 2026-05-02
  journal frozen; 2026-05-03 broad-subset findings flagged as
  question-mix-dependent narrative on top of the global
  per-mode recommendation.
2026-05-03 15:45:06 -04:00
17c1cde16d
ticket(#000008): §12.7 cap-only A/B — cap and reminder help differently
§12.7 captures the 2026-05-03T12-47-23Z cap-only A/B (apply_caps=
True, reminder=False) on the 9-question broad subset.

  Mode      | Baseline | Reminder | Cap-only
  ----------+----------+----------+----------
  JSON SR   |  0.19    |  0.22    |  0.33    ← +14pp
  JSON U    |   7      |   1      |   6      ← reminder dominates
  JSON S    |   5      |   6      |   9      ← cap dominates
  ptr ratio |  0.473   |  0.643   |  0.516
  JSON ratio|  0.524   |  0.735   |  0.643

§10.8 gate MET on JSON mode (+14pp STRICT-rate).

Headline insight: cap and reminder help in DIFFERENT ways.
- Reminder rescues UNGROUNDED → HYBRID (restates citation rule).
- Cap rescues HYBRID → STRICT (forces fewer-but-better claims).

The two are complementary, not redundant. If §12.8 (cap+reminder)
confirms the compound effect, that's the §10.8 trigger to land
Option D as default. Predicted JSON SR ~0.40 if effects compound.

Pointer mode still 0/27 STRICT under cap-only — TOO_MANY_CLAIMS
fires 20× (vs 7× baseline) but pointer-tag failures upstream of
the cap still gate the verdict.
2026-05-03 08:54:58 -04:00
fa8d93c8ef
ticket(#000008,#000006,index): §12.6 reminder A/B verdict + cross-refs
§12.6 in #000008 captures the 2026-05-03T12-38-53Z reminder-only
A/B (apply_caps=False, reminder=True) on the same 9-question
broad subset:

  Mode      | Strict-rate    | Mean ratio        | UNGROUNDED
  ----------+----------------+-------------------+-----------
  quote     | 0.56 → 0.52    | 0.900 → 0.845     |  0 → 0
  pointer   | 0.00 → 0.00    | 0.473 → 0.643     |  9 → 6
  JSON      | 0.19 → 0.22    | 0.524 → 0.735     |  7 → 1

Pointer-mode violation deltas:
  FORMAT_COLLAPSED      2 →  0  (-100%)
  NO_EVIDENCE_POINTER   9 →  6  ( -33%)
  TITLE_MISMATCH       10 → 15  ( +50%)  ← side effect
  TOO_MANY_CLAIMS       7 →  8  ( +14%)

§10.8 gate verdict: MET. Both FORMAT_COLLAPSED and NO_EVIDENCE_
POINTER cleared the 5pp floor (−7pp absolute / −11pp absolute
respectively). Strongest signals are mean-ratio improvements
(+17pp pointer, +21pp JSON) — grounded rows ground BETTER under
reminder. JSON-mode UNGROUNDED dropped 7 → 1, a 22pp redistribution
from "didn't ground" to "partially grounded".

Caveat: TITLE_MISMATCH increased (+50%). Reminder may pressure
Hermes to cite *something* rather than say "no evidence", picking
up wrong-source citations as a side effect.

Recommendation: §10.8 gate met but hold default flip until §12.7
(cap-only) and §12.8 (cap+reminder) cells run, per §10.8 "if A+B
together outperform either alone by ≥5pp: land Option D".

Cross-references:

- TICKETS.md index: #000008 status flipped to "open · phases 0–4
  landed; bench A/B in progress".
- #000006 rolling log: cross-reference to #000008's bench cycles
  + the d24291b classifier-defect fix surfaced from the
  distribution scan.
2026-05-03 08:48:19 -04:00
002f84c5a4
ticket(#000008): §12 dry-run bench findings + --policy harness flag
§12 captures the 2026-05-03 post-implementation bench cycle:

  §12.1 — pre-bench classifier scan (free, no LLM). Distribution
          across the 73-question bench: 65 SINGULAR, 5 OPEN_REQUEST,
          1 ALL, 1 COMPREHENSIVE, 1 SMALL_NUM_EXPLICIT, 0 MANY.
          Documents the `how many X` defect caught + fixed in
          d24291b.
  §12.2 — live bench on 9-question broad subset (3 modes × n=3 = 81
          runs). Per-mode summary, per-question table, pointer-mode
          violation distribution.
  §12.3 — telemetry verification end-to-end. Sampled per-question
          classifier output showing intensity / scope_bound_hint /
          claim_cap_applied populated as designed.
  §12.4 — §10.8 decision-tree implications. Cap-only unlikely to
          clear 5pp gate (pointer is already 0 STRICT); NO_EVIDENCE_
          POINTER (9/27) is the load-bearing failure → Phase 3
          reminder is the strongest single-knob candidate.
  §12.5 — next bench cycles checklist (reminder-only, cap-only,
          cap+reminder).

Headline findings:
  - JSON mode hits 3/3 STRICT on bounded universal `name all members
    of the beatles`. Same model, same verifier — bounded vs unbounded
    is empirically real (validates §10.1 split).
  - Pointer mode 0/27 STRICT on broad subset. CITATION_MISMATCH(14),
    TITLE_MISMATCH(10), NO_EVIDENCE_POINTER(9), TOO_MANY_CLAIMS(7)
    dominate.
  - Quote mode 0.56 strict-rate validates keeping it out of
    quantifier_guard_modes default.

Bench harness extension:
  bench/qa_sweep.py gains --policy KEY=VALUE flag (repeatable).
  Values are json.loads-decoded so booleans/ints/lists/strings work.
  Enables §10.8 A/B cycles without monkey-patching defaults.
  Plumbed through _run_one via new policy_overrides kwarg.

bench/qa_questions_quantifier_subset.txt landed as the 9-question
A/B fixture for ticket #000008.
2026-05-03 08:39:20 -04:00
041e865132
ticket(#000008): add §11 implementation inventory
Single-source-of-truth section for what was actually built in the
2026-05-03 implementation pass. Complements §8 (commit table) and
§9.6 (per-phase notes) with a full inventory:

- §11.1 New modules: aborist/qa/{quantifier,model_profiles,quantifier_reminder}.py
- §11.2 Modified modules: query.py, runner.py, keys.py, cli.py, qa_sweep.py
- §11.3 New test files: 4 new + 1 extended; 120 new tests total
- §11.4 Seven new policy fields in _VERIFIER_POLICY_FIELDS
- §11.5 Four new CLI flags on `aborist query`
- §11.6 Four new violation kinds (3 soft + 1 hard) with audit tails
- §11.7 New result-dict fields on miss + cache-hit paths
- §11.8 Eight new bench-row fields
- §11.9 Implementation-time decisions not in §9/§10:
  RUNG_PRIORITY ordering, bounded-domain anchors, reminder templates,
  reject answer_text format, render branch, EXPLICIT_COUNT fallback,
  quote-mode opt-out
- §11.10 Live verification artifacts (Winners-of-all-major-sports
  rejected; Beatles-bounded NOT rejected)
- §11.11 What was NOT shipped: quantifier_preflight run-DAG node,
  three-clause CTI contract DAG binding, A/B/D bench measurements,
  cross-model verification — all queued as Phase 5 / bench follow-up

Implementation-time decisions section is the most operationally
useful — captures judgment calls made during coding that aren't in
the design docs but are now binding via tests.
2026-05-03 08:16:06 -04:00
c684dc17e1
ticket(#000008): mark Phases 0.x-4 landed; commit chain pinned
Updates §8 Status, §9.6 Phase details, §9.8 Test surface, §9.11
commit sequence to reflect actual implementation state:

§8 Status — Phase 0 through Phase 4 all landed 2026-05-03 across
six commits (2ffed005a60e85). 906 tests passing (120 new).
Defaults preserve §10.11.3 dry-run discipline:
  quantifier_guard_apply_caps=False, reminder=False, reject=False.
Six-level disable hierarchy fully wired. Live verification recorded
for both reject-broad-fires (Winners of all major sports?) and
reject-broad-skips (name all members of the Beatles → bounded
universal, NOT rejected).

§9.6 Phase details — each phase tagged LANDED <sha>; description
trimmed to what actually shipped vs the original proposal.

§9.8 Test surface — every check box flipped to [x] with the
matching test file path and test count. The two reject-broad
integration tests remain skipped (exercised by live bench).

§9.11 Implementation commit sequence — actual SHAs replace planned
commit numbers. Notes that DAG/audit binding for quantifier_preflight
node ("commit 7" in plan) is NOT shipped — tracked as Phase 5
follow-up. Optional now; required for §9.5 Merkle-AGI-DAG framing
to fully hold.

Next steps are bench measurement, not code: full bench under dry-run,
classifier review, then flip apply_caps and measure §10.8 deltas.
2026-05-03 08:08:03 -04:00