Skip to content

Measure where HermitCrab's time actually goes, across 33 grammars - #488

Closed
johnml1135 wants to merge 15 commits into
integrate-conformance-frameworkfrom
feature/synthesis-fold-probes
Closed

Measure where HermitCrab's time actually goes, across 33 grammars#488
johnml1135 wants to merge 15 commits into
integrate-conformance-frameworkfrom
feature/synthesis-fold-probes

Conversation

@johnml1135

@johnml1135 johnml1135 commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

HermitCrab has been optimised repeatedly without anyone measuring where its time goes. This branch measures it — across 33 grammars rather than three — and the answer redirects what we should build next.

What it adds. A wall-time split of ParseWord into eight exclusive buckets that sum to wall (analysis total, analysis cascade / battery / phonology, lexical lookup, synthesis cascade / battery / forward, ExpandAlternatives), a die-point histogram for rejected synthesis candidates, and a fold-step sharing census. All behind one volatile bool, false in normal operation; every edit is an insertion before an existing return or continue. No behaviour change: 582 passed / 1 skipped / 0 failed, including every conformance fixture gate.

Where the time is. Not synthesis. Synthesis is ~5% of Sena and 0.3% of Amharic. The cost is analysis, and which part differs by grammar: Sena is affix-template-battery-bound (51.4%, still, after the memo that bought 5x) plus ExpandAlternatives at 20.3% — a bucket nothing had ever instrumented. Amharic is cascade-bound (~95%), at ~170 ms per analysis state in a cascade already at its state-count floor.

The finding that closes a family. Forward synthesis is a deterministic trail-driven fold, and the sharing looked large: 3.22x and 8.10x, ~50% wall ceilings on the two fixtures big enough to time reliably, reproduced across two independent runs. It was built (stacked branch, parity clean, 0 divergences on all 33 fixtures) and it does not payhits = 0 on the best fixture, 0.96x, i.e. 4% slower from key construction alone. A sound key must carry the ordered remaining trail, and two candidates then have to agree on their whole future to share a step.

That is the third independent route to the same result. The redundancy is apparent, not real: the trail is what makes each step distinct, and every measurement showing large shareable work is measuring a key that omits it. Packed forests, fold sharing and synthesis-input dedupe all need distinct derivations to converge on a genuinely identical state; in this engine they do not.

What to review. docs/hermitcrab-optimization-ledger.md is the deliverable — 20 rows, tried / closed / open, with the number that settled each. The instrumentation is mechanical; the judgement is in the ledger.

Note on process: the research docs are deliberately kept in-repo, not evicted into accordions. Three of these avenues have already been independently rediscovered and re-retracted — the 9,774x dedupe figure has been re-derived twice by different routes. A closed avenue is only closed if the next person finds out cheaply that it is closed.

Category results — every group at the 2x bar

Ratios are deterministic and reproduce byte-identically across runs. Only wallMs >= 50 rows can carry a timing claim: one 10 ms fixture's share moved 1.3% to 14.5% between two runs of identical code.

group fixtures at >=2x verdict
A. Affix template slots 5 of 6 — 8.10x, 3.22x, 3.00x, 2.81x, 2.15x Clears; both reliable rows live here
B. Disjunctive allomorphs / free fluctuation 2 of 2 — 3.00x, 2.00x Clears on mechanism; sub-4 ms fixtures
C. NaturalClass precision 1 of 1 — 3.94x Clears on mechanism; 10 ms fixture
D. Stem names 1 of 1 — 2.00x Clears on mechanism; 2 ms fixture
E. Subrule gating 2.00x from 2 applications Discarded — one observation
F. Compounding none — 1.48x, 1.00x Fails
G. MPR features/groups none — 1.17x, 1.00x Fails; the order-dependent fixture is exactly 1.00x
H. Metathesis / truncation / in-place modification none — 1.11x, 1.00x, 1.00x Fails, as the mechanism predicts
I. Phonological rewrite direction / iterative none — 1.50x, 0 apps Fails / no signal
J. Loader and character-table edge cases none — mostly 0 apps No signal; no rule application
K. Feature-system breadth none — 1.60x, 1.58x, 1.00x Fails, clustered just under

The categories are real — A and B have a clean mechanistic reason to share, and the fixture built to be order-dependent reports exactly 1.00x, which is the mechanism failing where it should. The 2x was real as available sharing. It is not extractable, because what makes it visible is what makes it unsound.

F through K are retained rather than deleted: they are the reference for judging a future grammar, and a category that fails on today's fixtures may pass on a grammar we do not yet have.

Corrections made during this work

Three findings were published inside this branch and then withdrawn on measurement. All three were arithmetic on an unmeasured denominator.

  1. "Synthesis is the bottleneck." Built on candidate counts — 218,847 synthesis inputs on one Sena word returning 0 parses. Those candidates cost ~0.5 us each. Counting volume is not counting time.
  2. "Amharic is synthesis-bound." Inferred as ~160 ms per synthesis run by dividing 30 s by 186 inputs. Its forward synthesis is 14 ms; the 36 s is the analysis cascade.
  3. "Fixtures only look synthesis-heavy because they are small." Cited the largest fixture as having the lowest synthesis share, 6.1%. That was synForward, which is explicitly net of the cascade and battery buckets while the shared work runs inside them. Its real share is 73.9% — the highest of any reliable row. The trend the argument rested on does not exist.

A fourth was caught in the harness rather than published: a first A/B design showed 1.53x purely from JIT warm-up, with the off-arm varying 42.7% between its own first and second sample. The harness now discards warm-up, takes min of N interleaved samples per arm, and prints the off-arm spread beside every speedup.

The wall-time split this branch adds is what makes all of these checkable. It was a required row in a predecessor plan and was skipped.

Durable constraints, and the retained classifier

Two findings are in-repo because the code cannot express them:

  • Word.ReplayOnto does not splice _mrulesUnapplied. Safe only because AnalysisStateKey includes the per-rule count multiset, which guarantees arrival and stored-arrival counts match on a hit. Anyone narrowing that key breaks this silently. Fix if needed: store arrival counts on MemoEntry and compute stored - storedArrival + query.
  • HermitCrab's morphological rules are not order-invariant. Same pending-rule multiset, different application order, different synthesis output. This bounds every packed-readout scheme, and it is the assumption Maxwell and Kaplan (CL 19(4):571-590) rely on and HermitCrab does not satisfy.

RuleLengthClassifier is retained with 12 tests and no callers. It encodes a direction trap that is easy to get backwards: on the analysis side rules are un-applied, so a rule that inserts on synthesis removes on analysis, and one that truncates on synthesis untruncates — an Lhs part with no Rhs copy makes the un-applied word grow. AnalysisMorphologicalTransform.GenerateShape is the authority. Removing it is defensible; keeping it means the next attempt at length-based pruning will not get the sign wrong.

Commit 1a7d484c bundles two concerns — a harness reporting change and a docs analysis — because the change was swept in from an uncommitted state. Noted rather than rewritten.

Next: per-node cost

Every optimization in the ledger that worked reduced how many nodes are visited. None touched what a node costs. Amharic spends ~170 ms per analysis state in a cascade already at its state floor — the state count is a floor, and the cost per state is unexplored. That decomposition (FSA pattern matching vs feature unification vs clone/freeze vs key hashing) is the next probe, and it is in flight.


This change is Reviewable

johnml1135 and others added 15 commits August 26, 2026 18:40
Rebases this line of work onto integrate-conformance-framework rather than
master: it carries 33 committed grammars (8 typologically distinct languages
plus 25 edge cases) with hand-derived expected outputs and a Fixture.DiscoverAll
enumerator. Every prior conclusion here came from three grammars, and the last
one died because a result that looked general was Sena-shaped.

The reframing under test: forward synthesis is not order-sensitive search, it is
a deterministic fold driven by the trail (Word.IsMorphologicalRuleApplicable
admits only _mruleApps[_mruleAppIndex]). The end of the trail is applied FIRST in
synthesis, and ReplayOnto's mruleTrailPrefixLength already marks that boundary --
so the analysis memo has already computed which candidates share a
synthesis-first segment, and that segment is currently re-folded per path, per
root, per alternative. Folds can be shared by identical subsequence and by
computed value, neither of which assumes commutativity, so rule
non-commutativity stops being a blocker and becomes something detected.

Carries over the predecessor branch's three evidence docs unchanged and the
RuleLengthClassifier (orphaned there by the Stage-0 stop, reused by probe P2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…t histogram, fold-step fingerprint

Adds SynthesisProbe, a gated (Enabled defaults false, so the ordinary sequential-path test
suite pays nothing) static instrumentation hub for the three P1 measurements in
docs/hermitcrab-synthesis-fold-probes.md section 3:

- P1a wall-time split: cascade/template-battery timers in SynthesisStratumRule, LexicalLookup
  and a derived forward-synthesis residual in Morpher.SynthesizeSequential.
- P1b die-point histogram: unconditional (not IsTracing-gated) counters at each rejection site
  in SynthesisAffixProcessRule, SynthesisRealizationalAffixProcessRule, and Allomorph.IsWordValid,
  reusing FailureReason's vocabulary where it lines up.
- P1c fold-step fingerprint: a dedicated (fingerprint, applied rule) key, deliberately not
  Word.ValueEquals (which omits SyntacticFeatureStruct, MPR features, and disjunctive allomorph
  indices -- see Word.cs:600), plus a determinism check on repeat keys.

Word.cs gains three read-only accessors (AppliedRuleCounts, DisjunctiveAllomorphIndices,
PendingTrailPosition) mirroring the existing UnappliedRuleCounts pattern, needed for the P1c
fingerprint. No behavior change: full non-Explicit HermitCrab suite still green (582 passed).
…eterminism check

SynthesisFoldProbe.cs is the P1 harness: Probe_ConformanceFixtures runs all 33 conformance
fixtures with no env vars (synthetic, committed, safe to print); Probe_RealCorpus is env-var
driven exactly like MemoCorpusVerification (HC_MEMO_GRAMMAR/HC_MEMO_WORDS/HC_MEMO_MAX_WORDS)
plus HC_PROBE_WORDS for an explicit word list. Both report per-word P1a/P1b/P1c lines plus a
per-fixture summary, never pooling a ratio across fixtures.

First run against the 33 fixtures surfaced 130 "determinism violations" -- investigation showed
these were a bug in the check itself, not the fingerprint: SynthesisProbe.RecordApplication was
called once per successful allomorph inside SynthesisAffixProcessRule/SynthesisRealizationalAffixProcessRule's
per-allomorph loop, so ordinary disjunctive fan-out (several allomorphs of the same rule all
matching one input before the environment/free-fluctuation break) looked like the same
(fingerprint, rule) key producing different outcomes on different calls. This is exactly the
set-valued-partial shape the plan doc's second trap already names for realizational rules ("any
stored partial must be a set, like MemoEntry.Results, not a value") -- it just also applies to
ordinary affix rules' allomorph loops. Fixed by recording once per Apply() call with the whole
output list (RecordApplications), comparing outcome SETS via bipartite FingerprintEquals matching
instead of single values. Re-run: 0 violations across all 33 fixtures.

Also broadened SynthesisFoldProbe.ProbeWord's catch to any Exception, not just
InvalidShapeException: some edge-case fixtures have ExpectCrash: true (e.g.
simultaneous-epenthesis-cascade throws InfiniteLoopException by design), and this probe isn't the
self-check for that contract -- it now notes the crash and skips measurement for that word.
…logy-dependent

Zero determinism violations across all 33 fixtures: equal fingerprint plus equal
applied rule never produced a different outcome multiset, across 8 typologies and
25 edge cases. That is the check that would have exposed an incomplete
fingerprint, so the ratios below are real sharing rather than collisions.

P1c ranges from 8.10x (suffixing-evidential-adjacency-chain) and 3.22x
(deep-optional-affix-nesting, the largest sample at 5,556 applications) down to
1.11x (metathesis) and exactly 1.00x (mpr-overwrite-order-dependence). The split
is itself a sanity check: the fixture built to be order-dependent shares nothing,
a suffix chain shares 8x. The measurement discriminates in the direction the
mechanism predicts.

Two cautions recorded on P1b: it counts rejection EVENTS, not candidates, and is
NOT the same denominator as the historical 218,847 figure; and its dominant
bucket is an O(1) trail-position check, so a count histogram overstates its cost
share. Cost-weighting is required before it becomes a build decision.

P1a is unreliable at sub-2ms fixture scale, but the one large fixture puts the
template battery at 67.4% of 2,393ms -- matching the historical Sena finding.

Full HC suite 582 passed / 1 skipped / 0 failed with the probe present.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
P1c on Sena is 265.5x with zero determinism violations -- the >=5x gate cleared
by a wide margin. On Sena that does not convert, because forward synthesis is
0.2% of wall time and all four instrumented buckets total 5.0%.

Separates two tangled findings. (i) A measurement defect: every timer landed on
the synthesis side (SynthesisStratumRule.cs:107/:136); the analysis phase was
never instrumented. That is an ambiguity in the brief -- a cascade and a template
battery exist on both sides. (ii) A real result: even granting the defect, Sena
heavy-word time is overwhelmingly analysis, and cinacemerwa's 218,847 synthesis
inputs cost ~0.5us each. Counting candidates told us where the volume was, never
where the time was -- exactly the row the predecessor plan required and skipped.

Corrects the framing that mattered most: Sena being analysis-bound is a fact
about Sena, not a verdict on the technique. Value per grammar is the PRODUCT of
the sharing ratio and the forward-synthesis share of wall time. We have the first
across 33 fixtures; we have the second only for Sena. No conclusion about any
other grammar is licensed until the second factor is measured per grammar.

Flags Amharic as the priority: 212 states and 186 synthesis inputs costing 30
seconds is ~160ms per synthesis run against Sena's ~0.5us -- five orders of
magnitude apart. If Amharic is synthesis-bound, Sena is the outlier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ts, add unaccounted

The four P1a timers all landed on the synthesis side (synCascade/synBattery, both
renamed from cascade/templateBattery; synForward, renamed from forwardSynthesis) --
95% of Sena heavy-word wall time was unaccounted for because nothing on the
analysis side was ever instrumented.

Adds four new SynthesisProbe buckets, all instrumentation-only and gated on
SynthesisProbe.Enabled (default false):
  - anTotal: outer/nested bucket around Morpher.ParseWord's
    _analysisRule.Apply(input) call -- the whole analysis phase.
  - anCascade: AnalysisStratumRule.ApplyMorphologicalRules' _mrulesRule.Apply
    call (MemoizedCombinationRuleCascade for the memoized Unordered path this
    harness always runs; also covers PermutationRuleCascade for Linear strata
    and ParallelCombinationRuleCascade if ever reached at this same call site).
  - anBattery: AnalysisStratumRule.ApplyTemplates' call to
    ApplyTemplateBattery, covering both the memoized and unmemoized paths.
  - anPhono: AnalysisStratumRule.Apply's _prulesRule.Apply(input) call, the
    analysis phonological-rule cascade.

anCascade/anBattery/anPhono are disjoint exclusive slices (none of their call
sites re-enter each other); anTotal is a nested/inclusive total that contains
all three plus whatever analysis-side orchestration they don't individually
bracket. SynthesisFoldProbe.cs now reports both an exclusive top-level split
(lookup/synCascade/synBattery/synForward/anTotal/unaccounted, summing to wall)
and an anTotal-internal breakdown (anCascade/anBattery/anPhono/anOther), with
the nesting scheme stated in the header. Also adds a per-fixture
forward-synthesis-share x P1c-ratio "value" column to Probe_ConformanceFixtures,
since P1c sharing can only be realized as a speedup on the forward-synthesis
slice of wall time.

Full HermitCrab suite still green: 582 passed / 1 skipped / 0 failed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ong phase

Per-grammar results with trustworthy timers (Amharic unaccounted 0.1%).

Max possible speedup = share x (1 - 1/ratio), NOT ratio x share. Best anywhere is
22.5% (feature-system-breadth, 1.60x on a 60.1% synthesis share); Sena's 265x is
worth 0.2% because 265x of nothing is nothing.

Refutes this document's own earlier claim that Amharic was synthesis-bound: the
'160ms per synthesis run' for the word at 6.3 was arithmetic on an unmeasured
denominator. Its forward synthesis is 14ms; its 36 seconds are in the analysis
morphological-rule cascade at ~170ms per state.

Fixtures show 15-60% synthesis share against 0.1-0.2% for real grammars. Evidence
favours grammar size over typology as the explanation: Sena is agglutinative and
is 0.2%, and synthesis share falls monotonically as fixtures get larger.

Verdict: do not build fold sharing. Redirects to the analysis cascade -- 99.5% of
Amharic, already memoized, already at its state floor, and still ~170ms per state.
Every optimization so far reduced node COUNT; none touched per-node COST.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ar-dependent

Sena pooled: anBattery 51.4%, anCascade 18.4%, synthesis ~5%, unaccounted 20.1%.
Amharic: anCascade ~95% of anTotal, anBattery 4%. So Sena is template-battery-
bound and Amharic is cascade-bound; neither is synthesis-bound. Corrects this
document's own previous claim that the cascade was 'the target', which was drawn
from Amharic alone -- the Sena-shaped error in reverse.

Notes that the template battery is STILL 51.4% of Sena after memoization (Phase
3b measured 93% pre-memo, 5x from its memo): the memo reduced how often the
battery runs, not what a run costs.

The common thread across both grammars is per-node cost, not node count. Every
optimization tried in this area -- memoization, key narrowing, lexical gating,
tandem intersection -- reduced how many nodes are visited. None touched what a
node costs.

Records Sena's 20.1% unaccounted as an open gap with a named hypothesis
(Word.ExpandAlternatives outside every timed region), flagged as hypothesis not
measurement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adversarial review found the ceiling table divided by the wrong share, confirmed
in code. synForward is explicitly net of cascade and battery (Morpher.cs:424),
but every application P1c counts is recorded inside SynthesisAffixProcessRule.
Apply / SynthesisRealizationalAffixProcessRule.Apply, which run INSIDE the
synCascade and synBattery brackets -- template slot rules compile to those same
classes via RuleBatch. Shareable work lives in synCascade+synBattery+synForward;
the table divided by the one bucket that excludes it.

Sena: 0.2% -> ~4.98%. Amharic: 0.07% -> ~0.16%.

Withdraws the fixture ceiling column and the 'best anywhere 22.5%' headline: it
was computed from fixture timings section 6.1 itself declared unreliable, which
made the doc self-contradictory.

Walks back what 0 determinism violations proves. RecordApplications returns early
on empty output, so a (fingerprint, rule) pair that succeeds once and fails once
is never compared; and outcomes are compared with the same FingerprintEquals used
to key them, which covers trail POSITION but not remaining-trail CONTENT. Zero
violations licenses per-step decision determinism only, not soundness of a build.

Walks back the size-vs-typology dismissal: its premise was the wrong Sena number,
the large end of the trend is one fixture whose size is analysis-caused, and
trail-exempt realizational branching is a concrete mechanism for a synthesis-bound
family none of our grammars represent.

Scopes the verdict to parsing: GenerateWords is pure synthesis and unmeasured.
Records trail-position indexing as measured-worthless (0.2%) so it does not become
a default task.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a synExpand tick bucket (SynthesisProbe.AddSynExpandTicks/SynExpandTicks)
around the ExpandAlternatives() call in Morpher.SynthesizeSequential -- the
only call site the probe harness reaches, since guessRoot=false and the
sequential path is the only one this harness exercises. synExpand is a new
exclusive top-level slice, so unaccounted shrinks by exactly what it gains.

Also adds a dedupe census at fold entry: for every alternative about to enter
_synthesisRule.Apply, counts total alternatives, distinct alternatives by the
existing P1c fingerprint (SynthesisProbe.AlternativeKey reuses
FingerprintHash/FingerprintEquals, no second fingerprint), and dupe
provenance -- whether a duplicate's first occurrence traces to the same
analysis word or a different one, via reference-identity against the outer
loop variable already in scope. That split decides interceptability: same-
analysis-word duplication is catchable before ExpandAlternatives'
Clone/Unify/Freeze work; cross-analysis-word duplication only after it.

SynthesisFoldProbe.cs reports all of this per word and cumulatively per
fixture/corpus, alongside the existing P1a/P1b/P1c columns.

Instrumentation only, gated on SynthesisProbe.Enabled (false by default), no
control-flow changes. Full suite reconfirmed green: 582 passed, 1 skipped, 0
failed.
…-sharing verdict stands, new dedupe-at-fold-entry candidate found

Sena unaccounted collapses 20.1% -> 1.5% pooled (24.0% -> 2.01% on
cinacemerwa, 7.6% -> 0.77% on atawirambo) once synExpand is broken out.
Hypothesis confirmed against the <5% gate.

The 6.4 fold-step-sharing verdict for parsing does not flip: ExpandAlternatives
runs outside the fold P1c measures, and synCascade+synBattery+synForward is
still ~5% of wall (ceiling 5.32%, matching 6.4's 4.98%).

The dedupe census at fold entry finds a second, larger, gated-ON opportunity:
395,026 alternatives collapse to 61 distinct pooled (0.02%), and 85.0% of
duplicates (73.0%-100% per word) trace to the same analysis word -- the OFF
condition (predominantly cross-word) never fires. Estimated ceiling ~17.3% of
Sena wall time, an order of magnitude above the fold-step build. Reported as a
measurement and a scoped next candidate, not built.
The hypothesis result stands: unaccounted 20.1% -> 1.5%, synExpand = 20.3% of
Sena wall time, invisible to every prior instrumentation round. Denominators
cross-check exactly against an independent run.

The census conclusion does not. 395,026 -> 61 distinct is measured with the P1c
fingerprint, which carries PendingTrailPosition (an int index) and no
remaining-trail content. Defensible for a fold STEP where the continuation is
re-anchored; not for fold-ENTRY dedupe, where skipping an alternative discards
its distinct continuation -- lost parses.

This measurement already exists: same call sites, same 218,847 denominator, on
parse-forest-tandem. F1 v1 got 9,774x with a naive key and it was proven unsound;
F1 v2 got 28.72x with 2 residual violations; F2 shipped fully order-sound at
15-40%. The 6,476x is the 9,774x again, and the adversarial review named this
exact failure mode one step earlier.

Corrected ceiling: 20.3% x 15-40% = 3-8% of Sena wall. Still the largest
opportunity surfaced so far, on an axis nobody had instrumented, but a fifth of
the claimed figure and it needs a trail-complete key first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ceilings

Re-run with synTotalShare = (synCascade+synBattery+synForward)/wall and a
reliability flag. deep-optional-affix-nesting: 3.22x on a 73.1% share = 50.4%
ceiling, on the largest and most trustworthy timing sample in the set (2.8s).
suffixing-evidential-adjacency-chain: 8.10x on 59.3% = 52.0% ceiling.

REFUTES this document's own size-vs-typology argument. Section 6.4 cited
deep-optional-affix-nesting as the largest fixture with the lowest synthesis
share (6.1%) -- but that 6.1% was forwardShare, the wrong denominator. Its real
synTotalShare is 73.1%, the highest of any reliable row. The largest, most
reliable fixture is the MOST synthesis-bound, not the least. The trend the
argument rested on does not exist.

Also: deep-optional-affix-nesting has altTotal 926 -> altDistinct 3 (0.32%) with
dupeSameWordPct = 100.0%, so every duplicate shares a trail and the
ExpandAlternatives dedupe is fully interceptable pre-expansion there.

Records the category verdicts: A (affix template slots) clears with both reliable
rows; B/C/D clear on mechanism but sit on sub-12ms fixtures; E discarded as one
observation; F-K fail and are retained as evidence for future grammars.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both reliable >=2x fixtures reproduce to within ~1.7 points, both at ~50%
ceiling: deep-optional-affix-nesting 50.41%/50.94%, suffixing-evidential
51.95%/50.23%. That is the result the build rests on and it is stable.

The unreliable rows do not reproduce: strrep-identity's synExpandShare moved
1.3% -> 14.5% on a 10ms fixture. Direct evidence for the wallMs>=50 flag rather
than an assumption behind it, and the reason groups C and D must be read as
'the mechanism engages' and never as speedup estimates.

Deterministic counters were byte-identical across both runs; 0 determinism
violations in both.

Notes that 1a7d484 bundles two concerns, and why.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ot retry

One row per optimization attempted across this whole line of work, with what was
expected, why it failed, and the number that settled it. Deliberately in-repo and
durable rather than evicted into a PR accordion: a closed avenue is only closed if
the next person can find out cheaply that it is closed.

Three of these have already been independently rediscovered and re-retracted --
the order-insensitive dedupe number (9,774x) has now been re-derived twice by
different routes. That is the failure mode this file exists to prevent.

Records the generalising lesson: the redundancy in HermitCrab's synthesis is
apparent, not real. Three measurements at three boundaries all collapsed once the
key carried the trail (9,774x -> 15-40%, 6,476x -> unestablished, 3.22x/8.10x ->
hits=0). That closes packed forests, fold sharing and input dedupe as a family,
not as three candidates.

Records where the time is (Sena: battery 51.4%, ExpandAlternatives 20.3%,
synthesis ~5%; Amharic: analysis cascade ~95%, synthesis 0.3%) and the six method
rules earned here, including the three retracted findings and their common cause.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@johnml1135

Copy link
Copy Markdown
Collaborator Author

Superseded by #490 (docs-only). Instrumentation stays on feature/synthesis-fold-probes and feature/per-node-cost; the ledger names which branch holds what. The probes gate on volatile bool reads inside Matcher.cs, a hot inner loop in SIL.Machine — acceptable for a measurement run, not something to carry in the tree. The five working docs are also not merged: they contain retracted intermediate claims that would sit in the tree next to the corrected numbers.

@johnml1135 johnml1135 closed this Aug 27, 2026
@johnml1135
johnml1135 deleted the feature/synthesis-fold-probes branch August 27, 2026 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant