feat(extraction): stage engines resolve the slot chain — engineFor on the pipeline

Chunk B, item 3 of the search port + slots wave (2026-09-20): the flagged
gap closed — ExtractionModels deps were engine VALUES, keeping
extractor/auditor/labeler config-pin-bound while the job runner went
slot-native. The pipeline now takes the runner's exact treatment:

- ExtractionPipelineDeps.engineFor: (role) => PiEngine — resolved FRESH
  per stage call, so a settings PUT between stages lands. Direct test
  values (extractor/auditor/labeler) remain the priority seam, checked
  FIRST; absent values fall to the chain; absent chain → config pins
  (unchanged).
- All six stage call sites (chat + notes extract/audit, the cluster
  namer x2) resolve through stageEngine(role, direct).
- chat-handler's extraction composition injects the full chain —
  piEngineForSpec(resolveRoleSpec(role, readSettings(), MODEL_PINS)) —
  same wiring as the job runner.

Chunk B, item 4 (session-level slot-anchored model picks): VERIFIED
already complete from Platform's model-slots wave — the conversation
engine chain (chat-handler) anchors on effective.models.strong, the
picker's default surface (catalogDefaultsFor) falls back to strong,
both pinned in tests. No phase split (user decision, 2026-09-20).
Capability-filtered pickers live in the settings UI (main 343be10).

Tests: engineFor fills the stages end-to-end (both propositions merged
through the chain, consulted in pipeline order) + the direct-value
priority pin (engineFor that throws when consulted).

Gates: typecheck, 795/795 tests, lint, build — all green.
This commit is contained in:
amosblomqvist
2026-09-22 13:59:25 +03:00
parent ed264c936d
commit 372d7f9975
3 changed files with 85 additions and 7 deletions
+7
View File
@@ -60,6 +60,13 @@ export const extraction = createExtractionPipeline({
// The REAL embedder (local transformer model): post-merge embedding
// batch — semantic clusters are computed and persisted here.
embedder: embedNewNodes,
// Model slots wave (2026-09-20): the extraction stages resolve the FULL
// chain — role override → slot → factory pin — read FRESH per stage call
// (the flagged gap: ExtractionModels deps were engine VALUES, keeping
// extractor/auditor/labeler config-pin-bound while the job runner went
// slot-native). Direct test values still win inside the pipeline.
engineFor: (role) =>
piEngineForSpec(resolveRoleSpec(role, stores.settingsStore.readSettings(), MODEL_PINS)),
});
/** Graph context injection (vision-context-injection.md): the runner's