ADR 0002: Semantic pilot before shared-history v2 sizing¶
Status: Proposed — 2026-10-28. Documentation-only decision; no new run or result. Exploratory-pilot protocol drafted in Addendum AB (2026-11-12); acceptance is a separate owner decision.
Context¶
External feedback questions using hash-embedder discordance to size shared-history v2. Hash collisions may contribute to disagreements; their share has not been established by this ADR. Repeating a result across hash variants does not establish semantic retrieval quality, and variants on the same queries are not independent samples.
Near-neutral gated routing calls the same retrieval path as the cosine arm
with weights [1,0,0,0,0,0] (engine_shared.semantic_only_weights,
engine_shared.is_query_affect_neutral; retrieval.retrieval_breakdown
and retrieval.build_retrieval_plan then score only query–memory cosine
via retrieval._component_values). Write-back
(EmotionalMemory._apply_retrieval_updates) updates memory tags only
(counters, reconsolidated affect, predictions, resonance links); it never
changes content, embeddings, IDs or store membership.
InMemoryStore.update reassigns an existing key, so
InMemoryStore.list_all and InMemoryStore.search_by_embedding keep
candidate order. In the in-memory replay with a deterministic embedder,
near-neutral gated therefore ranks identically to cosine even after the
two arms' write-back histories diverge, because both stores keep the
same content, embeddings, IDs and candidate order. The reported 8/8
near-neutral agreement across hash-embedder variants is a wiring check,
not evidence of benefit. Re-verify if write-back starts changing
content, embeddings or membership, the embedder becomes
non-deterministic, or a store backend other than InMemoryStore is
used (SQLiteStore.update re-inserts the vector row, so tie order is
not shown to be preserved there; approximate-index backends may also
reorder).
Non-neutral gains and near-neutral always-on losses remain empirical
observations conditional on the dataset, embedder and write-back policy.
The existing 36-query, 12-scenario shared_history_recall_v1 is a development
pilot, with oracle affect and author-constructed scenarios. It cannot become an
independent confirmatory set by changing its embedder.
Decision¶
Complete semantic-embedder support, rerun the unchanged v1 pilot, inspect paired discordance, and only then size and preregister v2. Preserve the hash runner as a mechanism/regression control. Do not freeze N from hash-only discordance or treat the previously discussed 54/70 query counts as a powered semantic study.
Use the merged runner from PR #186
(b209397816936e90dec6dbe435f145866ab03e84, 2026-11-12) rather than duplicate
its implementation. As inspected on 2026-10-28 this ADR recorded that PR as
open draft at b50e57cb6506a4f5eb9613d43a7476b050da4667; that snapshot is
historical. Merge of #186 does not by itself attest that every acceptance
criterion below is satisfied at execution time (in particular the immutable
model revision= pin and receipt fields in Addendum AB §1–§2).
The exploratory pilot protocol is
benchmarks/preregistration_addendum_ab_semantic_pilot.md
(issue #193).
That protocol must be merged before any scored or smoke run. The MiniLM
default on the configurable runner is not this pilot’s model; Addendum AB
records Hub id BAAI/bge-small-en-v1.5 and a looked-up revision SHA
(re-verify at execution; not an in-tree receipt). ADR acceptance remains a
separate owner decision.
Implementation audit and acceptance criteria¶
At main f833450ae9c7f50f73d77cbbe291dcddf249070b:
benchmarks/realistic/shared_history.py::SharedHistoryAdapter.resetconstructsTokenHashEmbedder()inline;adapters/base.pygives it a default dimension of 64.interfaces.py::Embedderreturnslist[float];models.py::Memory.embeddinghas no fixed dimension.stores/in_memory.pybuilds its matrix from stored vectors._math.py::cosine_similaritychecks equal lengths, not length 64.- The inspected in-memory retrieval path therefore has no explicit 64-dimensional contract. A literal constructor swap is still insufficient for a reproducible benchmark: configuration, lifecycle, provenance and regression coverage matter.
Before running the pilot, require:
- Embedder injection through runner, adapter construction and reset; fresh stores per scenario/arm; identical model configuration for all arms. Re-encode all memories when changing models; never reuse hash-vector snapshots.
- Explicit CPU execution and lazy optional dependencies, with a clear failure when semantic support is unavailable; no silent fallback to hash.
- Deterministic synthetic tests with non-64 dimensions, reset and snapshot round trips, mixed-dimension rejection, same-checkpoint neutral ranking equivalence, and neutral ranking equivalence after divergent write-back histories (tags differ, embeddings equal). Preserve unsalted hash behavior and read-only restoration checks.
- A separately identified real-model integration test. Synthetic vector tests establish plumbing only; neither is a retrieval-quality result.
- Receipts with runner commit, dataset SHA256, model id and immutable model
revision (or verified snapshot digest), observed dimension, preprocessing,
normalization, device, dependency versions, seed, top-k, gate threshold,
bootstrap settings, and explicit
read_only_retrievestrue/false. Model name alone is insufficient. Archive commands, result files and checksums under the existing shared-history receipt policy, including the reproducing CI run URL.
Pilot protocol¶
Before any scored or smoke execution, commit and merge a separate exploratory
pilot protocol following the repository research lifecycle. Pin
BAAI/bge-small-en-v1.5 to an immutable revision before execution; this choice
aligns with the existing benchmark embedder factory and is not selected by pilot
scores. Freeze preprocessing and all analysis choices there. The configurable
runner's MiniLM default is not an implicit model choice for this pilot.
Run all 36 queries unchanged with cosine, gated and always-on, both with normal
write-backs and read-only retrieval. Keep event order, IDs, top-k, gate threshold,
seed and all non-embedder settings matched. Report near-neutral (abs(v) < tau)
and non-neutral (abs(v) >= tau) strata; identify boundary cases explicitly.
Use normal write-backs as the primary pilot condition and read-only as a
mechanism diagnostic, not additional independent observations.
Dipankar Sarkar observed that gated-versus-cosine top-1 discordant pairs
on shared_history_recall_v1 (hash embedder, commit
441207d13f83b3dbefe4f17039ff68707072085f) differ by write-back mode.
Write-back: b=1, c=0 on bakery bk_q_inspection_not_gasket.
Read-only: b=1, c=0 on ferry fs_q_no_sailing. Both are query 3 of 3.
Our follow-up ablation, swapping one tag field at a time before query 3,
attributed both to carry-over: the reconsolidated core_affect for the
ferry, and core_affect together with retrieval_count for the bakery.
Freeze this labelled sensitivity rule as part of the pilot protocol.
Pairs discordant under write-back only are labelled
carry-over-dependent. Pairs discordant under read-only only are
labelled carry-over-suppressed. Report primary b, c and ICC both
with and without carry-over-dependent pairs. This is a sensitivity
analysis, not an exclusion. Dropping only write-back-only pairs would
bias the result toward read-only.
For each comparison against cosine and each stratum, retain aligned query IDs
and top-1 correctness, and report both-correct, both-wrong, method-only-correct
(b) and cosine-only-correct (c). Report b+c, (b+c)/N and (b-c)/N.
Ranking disagreement is a separate diagnostic: different retrieved IDs can both
be wrong and do not constitute discordant correctness pairs. Inspect ties and
candidate sets. Report zero discordance as an observation, not equivalence.
Preserve scenario membership. Queries within a shared history are dependent; uncertainty and planning must respect scenario clusters. With only 12 scenarios, report sensitivity to assumptions rather than a precise sample-size promise. Any query-level exact paired test is descriptive and must disclose its independence assumption. Do not pool write-back modes or hash variants into N.
Within-scenario discordance and planning sensitivity¶
The semantic pilot must report within-scenario dependence, not assume it away.
For each method-versus-cosine comparison, write-back condition and affect
stratum, define correctness discordance as
D_i = 1[top1_correct_method != top1_correct_cosine]. Retain the signed paired
outcome Z_i = top1_correct_method - top1_correct_cosine separately: correlation
of discordance incidence does not by itself specify variance of the paired
effect. Ranking disagreement is not the definition of either variable.
Publish a scenario table with query counts, stratum counts, b, c, discordance
rates and signed effects. Include a column that marks each discordant pair
as write-back only, read-only only, or both. Report that column per arm
and stratum, listing the discordant query IDs per mode. Predeclare in the
separate pilot protocol the observed-scale ICC estimator for D_i, its
uncertainty procedure, and handling of sparse strata, unequal cluster sizes
and boundary/degenerate estimates.
Report the exploratory ICC and uncertainty when estimable. If outcomes are
constant, the fit is unidentified, or a stratum has insufficient informative
clusters, report it as not estimable with the reason; never substitute zero.
Near-neutral gated-versus-cosine discordance is identically zero by
mechanism, so its ICC is not estimable there.
Do not pool arms, strata or write-back conditions to manufacture replication.
Twelve author-constructed histories may permit a descriptive estimate; they do not justify treating it as a precise population ICC for v2. Publish the number of informative clusters and limitations alongside any estimate. Freeze these rules before execution, and do not choose a sizing assumption from whichever pilot ICC gives the smallest N.
As a transparent sensitivity illustration, for equal cluster size m and
exchangeable observed-scale correlation rho, the usual mean-variance design
effect is DE = 1 + (m - 1) * rho
(Campbell et al., 2012, CONSORT cluster extension).
With three queries per history, DE = 1 + 2 * rho; rho = 0.25 gives DE = 1.5
and nominal N_eff = 36 / 1.5 = 24. These are illustrative assumptions, not
measured pilot results or a validated power calculation for paired correctness.
Stratum-specific cluster sizes can differ from three. In
shared_history_recall_v1 they are 1–2 per scenario (near-neutral:
10 scenarios with 1 query and 2 with 2; non-neutral: 10 with 2 and
2 with 1), so most near-neutral clusters carry no within-scenario
information.
For planning, show at least rho = 0, 0.10, 0.25, 0.50, 1.0 as declared
sensitivity cases, not confidence bounds. Model the joint paired outcomes and
scenario dependence of the signed effect for the intended primary analysis;
do not inflate a query-level exact test using the ICC of D_i alone. Report
required independent histories and total queries, including cluster-size
assumptions. Additional queries in an existing history do not create additional
independent histories.
Gate to v2¶
After publishing the pilot receipt, write a separate v2 preregistration before authoring or scoring its confirmatory set. Fix the target population, independent scenario sampling, primary contrast/stratum, smallest useful effect, alpha, power, multiplicity policy, stopping rule and resource limit. Estimate sample size using semantic paired outcomes and their cluster structure, with sensitivity to uncertainty in discordance and effect size; discordance alone is insufficient. Report required independent scenarios as well as queries. Keep pilot histories out of confirmation and freeze model/configuration before confirmation.
If the pilot is too sparse, the projected budget is infeasible, or no useful effect is supported, publish an inconclusive/negative pilot and either stop or preregister additional development data. Do not assume all future discordant pairs will favor gated, switch models after seeing scores without labeling the new analysis exploratory, or reduce N after looking at confirmatory outcomes.
Consequences¶
This separates gate wiring, embedder sensitivity and evidence of retrieval benefit. It delays v2 sizing until a relevant pilot exists and adds model-download and receipt costs. Semantic embeddings still do not remove oracle affect, author-construction bias or establish production/human utility. Existing results, receipts and public claims remain unchanged. ADR 0001's human-grounded study is a separate evidence track and is not replaced by this pilot.
Alternatives¶
- Size v2 immediately from hash discordance: rejected because the effect and discordance may not transfer to semantic embeddings.
- Add more hash salts first: useful regression diagnostics, insufficient for semantic power planning.
- Replace only the inline constructor: insufficient provenance and lifecycle coverage, despite dimension-generic in-memory interfaces.
- Treat the 36-query rerun as confirmation: rejected because it is already inspected development data.