Commit Graph

1268 Commits

Author SHA1 Message Date
claude bb6bd8efb9 router/semantic: slice 22 report — linear e5 at parity with the deployed cascade, cross-family transfer absent, 143 illegal actions, levers are deterministic 2026-09-08 01:27:21 +04:00
claude 29f74dd3cc router/semantic: slice 22 residual non-action router — emit step, Go harness (legacy + heads modes), Python experiment 2026-09-08 01:26:56 +04:00
claude bdced83b46 router/semantic: slice 21 execution-frame guard report — capability dangerous pass 0/126, guard→sparse P 96.7% FA 6
Deterministic structural guard blocks every capability-question row (0/126 on
all three stress views), never blocks a true action (0/796), declines 196
malformed action rows as ambiguous, and grows no safety leak under
compose: sparse alone FA 9 (capQ 1) → guard→sparse FA 6 (capQ 0).
Execution eligibility recorded as a deterministic policy boundary, separate
from semantic routing and capability selection; next slice returns to the
coarse non-action router instead of another pragmatics training run.

Task/725.
2026-09-07 23:45:33 +04:00
claude fa98e4722e router/semantic: slice 21 deterministic execution-frame guard engine, fixtures, runner and emit step
The guard answers one question — may this utterance become an executable
action — as a three-way policy gate (permissive / blocked / ambiguous) and
never decides what the utterance is. Rules are the encoding of the measured
slice-20 dev-pool discriminators: 126 capability-question rows are 42/42/42
addressed / bare-ability / bare-future; 127 bare можешь+пожалуйста rows are
100% action; can-you-please is 100% action. Reuses the shipped prohibition
parser, morph finiteness and lexicon fillers; reason vocabulary is closed.

Slice 21 (task/725, brief after the accepted slice 20).
2026-09-07 23:43:47 +04:00
claude de1cb40456 router/semantic: slice 20 pretrained fine-tune report — in-pool best, LOFO 1.000
cointegrated/rubert-tiny fine-tuned end-to-end: pair ordering 0.933-0.970
(+0.56-0.78 margin, in-pool) beats every from-scratch config, but the
held-out capability-question family fires 126/126 as action on all 18
config/seeds (FA_rate 1.000, mean proba 0.86-0.99, family σ 0.0045). tiny2
ceiling (newer, larger vocab) does not move LOFO (1.000) and is worse
in-pool. sparse 0.667 remains the safety floor; supervised encoder scaling
ruled out for the generator boundary.
2026-09-07 21:40:53 +04:00
claude dc73fc4e31 router/semantic: slice 20 pretrained-rubert-tiny pragmatics specialist tooling + tokenizer audit gate
cmd/semantic-router-experiment/slice20_pretrained.py (516 lines, over
300-line hook): tokenize/grouped/lfo/metrics/runtime/onnx/ceiling
subcommands, MAX_LEN=25, lr grid 1e-5/2e-5/5e-5 x seeds 42/17/7, 4-thread
fp32, early stop on val PR-AUC. slice20_audit.py: WordPiece audit gate
(UNK rate 0.0026, seq p99 19, no loss above 96). artifacts under /tmp/mvn-s20/.
2026-09-07 21:40:49 +04:00
claude cf2af6ce1e router/semantic: slice 19 report — correct claim head and prose to the seed-stable fail-rate cut 2026-09-07 17:59:10 +04:00
claude 5397f09785 router/semantic: slice 19 sequence pragmatics specialist report — sequence beats sparse on capability holdout, caps near chance on seed-stable seeds 2026-09-07 17:58:16 +04:00
claude 7d31de5a6b router/semantic: slice 19 from-scratch sequence pragmatics specialist tooling + eval index 2026-09-07 17:58:09 +04:00
claude 20215650f2 router/semantic: slice 18 sparse action-gate report — aggregate boundary solved, capability boundary collapsed 2026-09-07 15:35:48 +04:00
claude f2b65cd5d2 router/semantic: slice 18 sparse lexical action-gate probe tooling + eval index 2026-09-07 15:35:41 +04:00
claude 9a25945567 router/semantic: slice 17 nonlinear e5 MLP probe — action gate experiment report 2026-09-07 15:23:46 +04:00
claude e80d45f4b3 router/semantic: slice 17 nonlinear MLP probe tooling + eval index 2026-09-07 15:23:39 +04:00
claude 4ed0238a25 router/semantic: add slice 16 diagnostic to evals index 2026-09-07 14:02:59 +04:00
claude 774c0660b0 router/semantic: slice 16 diagnostic — action/non-action boundary analysis
Experiments:
- Residual-only OOF safety metrics
- False-action decomposition by semantic family (7 families, 24 split groups)
- Paired e5 geometry (gap=0.010 between action and capability question)
- Binary action probe (PR-AUC=0.707, ROC-AUC=0.863)
- Cost-sensitive linear classification
- Expanded action-threshold sweep (7 thresholds)
- Voice-like punctuation stress evaluation
- e5 + tiny structural features
- Four-hypothesis comparison table

Verdict: e5 representation is the primary bottleneck. Action seeds and
capability questions are nearly indistinguishable in embedding space.
2026-09-07 14:02:00 +04:00
claude cbac8b9c4f router/semantic: experiment reports (slice 15)
- 2026-09-07-linear-e5-router-experiment: 136-example baseline (superseded)
- 2026-09-07-expanded-corpus-linear-head-experiment: 3025-example expanded (live)
- CLAUDE.md: index updates for both evals
2026-09-07 13:52:54 +04:00
claude ad3f2d6e99 router/semantic: contract tests for expanded corpus (slice 15)
Minimum corpus size check (>=1000), source count validation,
split-group leakage tests for contrast families.
2026-09-07 13:52:30 +04:00
claude 87411e5fb1 router/semantic: expanded v2 corpus (3025 examples, 93 seed families)
Merged corpus: 535 frozen holdout + 2490 development pool.
Route distribution: action=990, knowledge=880, memory_write=705,
system=226, uncertain=121, conversation=103.
Dataset hash: b27fd48f478ca477cab1e59773bb353a
2026-09-07 13:52:29 +04:00
claude 4bb7555459 router/semantic: corpus-factory deterministic surface generation (slice 15)
93 semantic seed families across 6 routes. Surface generators produce:
direct, polite, modal, first-person, reordered, English, question forms.
Each seed specifies verb forms, subjects, objects, values, tags.
2026-09-07 13:52:12 +04:00
claude 9df223907b router/semantic: sklearn grouped CV linear head experiment (slice 15)
Python experiment: 6-class logistic regression over frozen e5 embeddings,
grouped cross-validation, calibration, abstention curves, contrast-family
analysis, action-threshold sweep.
2026-09-07 13:52:12 +04:00
claude f8ec77de8a router/semantic: e5 embedding cache for linear head experiment (slice 15)
Go tool that computes e5-small embeddings for every corpus row,
assigns frozen/dev split and grouped CV folds, outputs JSON.
2026-09-07 13:51:54 +04:00
claude 6397ea1cc9 router/semantic: merge-corpus tool for frozen holdout preservation (slice 15)
Merges frozen holdout from v1 with v2 development pool, deduplicates,
preserves frozen entries, validates, writes merged corpus.
2026-09-07 13:51:53 +04:00
claude 07bfcea8cc router/semantic: semantic seed type and surface generator (slice 15) 2026-09-07 13:51:33 +04:00
claude 59a0a08d32 router/semantic: legacy baseline eval test (slice 13)
TestLegacyBaseline builds a minimal but complete router (stage-0
grammars, hash-embedder classifier seeded from models/seeds, deployed
confidence threshold) and runs it against the full 136-example corpus.

Reports macro F1, false-action rate, fast-path/residual/router-residual
accuracy, per-route P/R/F1, confusion matrix, and contrast family
breakdown (negation, question, reported_speech, quotation, hypothetical,
capability_question). Pre-route consumed cases are tracked separately
from the fast-path bucket.

The hash embedder is deterministic, so this baseline is reproducible.
The ONNX embedder would score higher; measure both before drawing
conclusions.
2026-09-07 02:09:02 +04:00
claude 1b8ae3c3e5 router/semantic: baseline scoring and contrast family analysis (slice 13)
ScoreLegacy runs the actual router cascade against the 136-example
corpus and produces per-route precision/recall/F1, confusion matrix,
false-action breakdown, and fast-path/residual/router-residual/pre-route
consumption counts. Pre-route consumed cases (command-prohibition grammar
matches at stage 0) are tracked separately — these never reach the
general cascade and should not be scored by the learned router.

ContrastFamilies splits the baseline report by transform tag (negation,
question, reported_speech, quotation, hypothetical, capability_question)
and reports per-family accuracy and false-action rate.

LegacyReport.String() renders the full baseline report with confusion
matrix and false-action case listing.
2026-09-07 02:08:51 +04:00
claude 56051e58c0 router/semantic: baseline types, test helpers, leakage test (slice 13)
Baseline types: LegacyRouter interface (satisfied by *router.Router),
LegacyCase with PrerouteConsumed flag for command-prohibition detection,
LegacyReport with fast-path/residual/router-residual/pre-route breakdowns,
ContrastFamilyReport for per-transform-family scoring.

Test helpers: buildSeededClassifier (hash embedder seeded from
models/seeds/*.txt), actVerbList, seed file loading.

TestContrastFamiliesShareSplitGroup verifies that all contrastive
variants of one base seed share exactly one SplitGroup, preventing
train/eval leakage across the contrast family split.
2026-09-07 02:08:40 +04:00
claude d63619bd0e router/semantic: frozen holdout split and grouped CV (slice 13)
Add FrozenHoldoutSplit with deterministic 15% ratio using dedicated hash
seed. Produces frozen/dev partition with SplitGroup-aware leakage
prevention — all contrastive variants of one seed stay in the same split.

Add GroupedCVFolds for k-fold grouped cross-validation on the development
pool. Each fold preserves split_group boundaries; every example appears
in exactly one eval set across all folds.

Tests verify determinism (same split → same hash), no split_group leakage
across frozen/dev, route coverage in both pools, fold completeness, and
grouped CV coverage.
2026-09-07 02:08:30 +04:00
claude fb9b719f0b router/semantic: corpus validation infrastructure (slice 13)
Add ValidateCorpus and CorpusStatsFrom for structural integrity checks
on the semantic route corpus. Validates total counts, route/source sums,
fast-path+residual partition, empty SourceID/SplitGroup, invalid routes,
duplicate identity, and conflicting labels on identical text.

CorpusStats provides deterministic dataset hash (SHA-256 of sorted texts,
first 16 bytes). ReproducibilityMeta in CorpusEnvelope records source
fixture hashes, generator version, split algorithm, and dataset hash.

TestCorpusValidation exercises the full validation pipeline.
2026-09-07 02:06:58 +04:00
claude 2b38390c87 router/semantic: tests for eval scoring and shadow harness (slice 12) 2026-09-07 01:43:30 +04:00
claude 0ff4562e60 router/semantic: tests for contrastive safety transforms (slice 12) 2026-09-07 01:43:26 +04:00
claude bb7c460d12 router/semantic: tests for contract, mapping, corpus, and split (slice 12) 2026-09-07 01:43:23 +04:00
claude dd98da5c42 router/semantic: shadow harness for experiment observation (slice 12)
ShadowHarness records turns where both the legacy router and the
experiment model produce a decision. Reports agreement/disagreement
split by fast-path vs residual. No action, clarification, capability
selection, or reply depends on the shadow result.
2026-09-07 01:42:39 +04:00
claude 9e2abea16b router/semantic: eval metrics for frozen evaluation set (slice 12)
EvalReport with macro F1, per-route precision/recall/F1, confusion
matrix, false-action rate, and fast-path vs residual breakdown.
ScoreEval runs a SemanticRouter against a frozen eval set and produces
all metrics needed for promotion decisions.
2026-09-07 01:42:36 +04:00
claude b481792c02 router/semantic: contrastive safety transforms and split-by-family (slice 12)
Six deterministic transforms (negation, question, reported speech,
quotation, hypothetical, capability question) applied to action-route
seeds. Each transform determines the expected class explicitly — no
model guessing labels. SplitByFamily uses hash-based bucketing to keep
paraphrases in the same split.
2026-09-07 01:42:27 +04:00
claude 5865699a5a router/semantic: corpus format and v1 dataset (slice 12)
136 examples with provenance from ru_routing_v1.json, tagged
fast_path_resolved vs residual. RouteExample carries source, source_id,
split_group for traceability. Split-by-family prevents paraphrase
leakage across train/eval.
2026-09-07 01:42:22 +04:00
claude b6a21c17eb router/semantic: coarse-route contract, interface, and legacy mapping (slice 12)
Defines the six-class SemanticRoute type (conversation, knowledge,
action, memory_write, system, uncertain), the SemanticRouteDecision
output, the SemanticRouter interface, and the deterministic
Intent→SemanticRoute mapping from the current seven-intent cascade.
2026-09-07 01:42:17 +04:00
claude 494c719a5d router: update all Route callers for NormalizedInput + add invariant tests (slice 11)
Migrate 54 test call sites to construct NormalizedInput{Text: ...}.
Add invariant tests:
- TestNormalizedInputReachesRouteIntact: ingress NormalizedInput reaches Route
- TestTryFastPathReceivesMatchText: TryFastPath gets the same input
- TestMatchTextDoesNotChangeRouting: same Text + different MatchText → same Decision
- TestDecisionUtteranceEqualsInputText: Decision.Utterance == input.Text
2026-09-07 01:32:49 +04:00
claude dad3cd0738 router: Router.Route consumes NormalizedInput directly (slice 11)
Change Route from (ctx, utterance string, now) to (ctx, input NormalizedInput, now).
The ingress-constructed NormalizedInput now reaches the cascade intact — no
reconstruction downstream. TryFastPath receives the same input, not a rebuilt one.
All callers (production, eval framework, tests) updated to construct NormalizedInput.
2026-09-07 01:32:45 +04:00
claude a1e4743492 router: add TryFastPath tests and Route identity invariant (slice 10) 2026-09-07 01:24:28 +04:00
claude 2ef470c2ba router: add TryFastPath with stage-0 grammar evaluation (slice 10) 2026-09-07 01:24:25 +04:00
claude 80f807d2ad router: extract stage-0 grammars into TryFastPath (slice 10) 2026-09-07 01:24:19 +04:00
claude e9049ad27e router: add NormalizeMatchText tests and property invariants (slice 9b)
17 tests covering: whitespace collapse, case folding, NFKC normalization,
punctuation preservation, mixed-script identifiers, ё passthrough, and
property invariants (idempotent, deterministic, never removes punctuation/
wake words/numbers, never mutates original).

Test-only foldYo helper proves ё→е is lossy (всё → все) without
exposing an unused production function.

Vikunja: #725
2026-09-06 22:33:27 +04:00
claude 431e052e6f router: add MatchText to NormalizedInput and NormalizeMatchText function (slice 9a)
Add MatchText field to NormalizedInput — a lossy lexical matching view
derived from ingress text: TrimSpace → NFKC → lowercase → collapse
Unicode whitespace. Does NOT fold ё→е, strip punctuation, strip wake
words, rewrite numbers, or invoke morphology.

Both ingress sites (voice + text) construct MatchText at entry. No
existing consumer reads MatchText yet — it is dark data for future
opt-in migration.

Vikunja: #725
2026-09-06 22:32:51 +04:00
claude 0a2e194e76 router: migrate refusesCommand and ActHasEntityTarget to CapabilitySelection (slice 6c)
Migrate the two remaining action-routing consumers from compatibility
Decision.Slings fields to authoritative Decision.CapabilitySelection:

- refusesCommand: reads CapabilitySelection.Fn instead of Slots.Fn
- ActHasEntityTarget: reads CapabilitySelection.Resolved and
  CapabilitySelection.Args instead of Slots.HasFn and Slots.Args

Slots.Text remains the source for entity text when positional args do
not contain the target (unchanged).

Regression tests prove:
- prohibited sentinel preserved byte-for-byte through SelectCapability
- blanked Slots.Fn/Args/HasFn do not affect migrated consumers
- Praxis/Hexis entity-target routing unchanged
- stage-0 deterministic act unchanged
- classifier/extractor act unchanged

do not remove the compatibility mirrors yet.
2026-09-06 21:43:14 +04:00
claude 18900dd613 docs: add slice 6b capability selection boundary report 2026-09-06 21:02:21 +04:00
claude 2d42e98871 router: update ActionCandidate tests for CapabilitySelection (slice 6b)
Set CapabilitySelection on decisions that have Slots.HasFn=true, so
ResolveActionCandidate reads from the authoritative record. Backward
compatibility tests verify that decisions without CapabilitySelection
still resolve via Slots.HasFn.
2026-09-06 21:02:17 +04:00
claude 4a17821b06 router: ResolveActionCandidate reads CapabilitySelection first (slice 6b)
The candidate now receives Fn/Args from CapabilitySelection (the
authoritative record) rather than from Decision.Slots.HasFn. Backward
compatibility: decisions with Slots.HasFn but no CapabilitySelection
(tests, rebuilt decisions) still resolve via the compatibility path.
2026-09-06 21:02:13 +04:00
claude 4b24fbad98 router: add CapabilitySelection field to Decision (slice 6b)
Authoritative record of which executable capability matched, separate
from Decision.Intent (what kind of turn) and ActionCandidate (downstream
action artifact). Decision.Slots.Fn/Args/HasFn remain as compatibility
representations populated from this selection.
2026-09-06 21:02:09 +04:00
claude 8d83c66d11 router: wire SelectCapability into Router.Route pipeline (slice 6b)
Call SelectCapability after each cascade path (grammar, heads, LLM,
classifier) and propagate the result via applyCapabilityToSlots.

Remove LLM text capability backfill from fillSlots — SelectCapability
now owns that path. fillMatchedSlots retains raw extractor capability
extraction for backward compatibility with stage-0 grammars.

gateLLMDecision now reads CapabilitySelection.Resolved instead of
Slots.HasFn for the act-intent confidence thinning check.
2026-09-06 21:02:05 +04:00
claude a6a62a2d56 router: introduce CapabilitySelection type and SelectCapability stage (slice 6b)
Add the explicit capability-selection boundary between route resolution
and action candidate production. SelectCapability is the single entry
point for selecting which executable capability matched an IntentAct turn.

Three input kinds: raw, llm_text, deterministic. Decision.CapabilitySelection
is the authoritative record; Decision.Slots.Fn/Args/HasFn remain as
compatibility representations populated from the selection.
2026-09-06 21:01:59 +04:00