sillsdev / sillsdev/interlinearizer-extension
Wire a model project into the suggestion engine (surface-form tier)
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2
- Forks
- 0
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 55
Description
Follow-up to #94 — resolving the first model gap (the model text) the way the follow-up comment points to: extend the suggestion engine (#131), not bake a mode picker into project creation.
Split (2026-08-12). This issue originally covered both kinds of model source. It has been narrowed to the surface-form tier, which is ready to build. The alignment-based major-language model — the part required for full PT9 parity, and the part gated on an unanswered design question — moved to #218. The two share the
modelProjectIdfield and the model tier inderiveTokenSuggestion, both of which this issue adds, so #218 is blocked by this one.
Design principles this follows
- Simplify project creation — attaching a model text is deferred, never a creation-time commitment.
- Generalize the interlinearizer — a project isn't locked to one kind of suggestion source. The model can be attached, changed, or dropped whenever the analyst wants.
- First-contact discoverable — the model surfaces intuitively at the point suggestions matter, and isn't worried about before then.
Scope: the surface-form tier
A sibling interlinear project whose approved TokenAnalysis glosses merge into the suggestion pool and match the source by surface form. Produces hits when it shares vocabulary with the source — the same source text, a prior edition, or a shared "master gloss" project. A direct extension of #131.
This is also the natural landing spot for imported PT9 glosses (import shipped in #150): repeat occurrences of an already-glossed source word get suggestions from #131's existing mechanism, no alignment needed for that vocabulary. It reaches only the glosses import marked 'approved', though — the pool admits an analysis only once it holds an approved link (selectApprovedIdByTokenRef, src/store/analysisSlice.ts:986), and PT9 writes VerseData.Hash only for an approved verse, so a typical imported project is mostly 'suggested' and stays out of the pool. How much this tier picks up therefore depends on #310, which makes those imported records visible and approvable in the first place. #218 covers the rest.
Model additions
InterlinearProject.modelProjectId?: string— the Platform.Bible project used as the suggestion source. May reference either a sibling interlinear project (→ surface-form reuse, this issue) or a plain major-language Scripture project (→ alignment, #218). The engine chooses the resolution strategy by whether an interlinear analysis exists for the referenced project; until #218 lands, a reference to a non-interlinear project resolves to no suggestions rather than an error.DraftProject.modelProjectId?: string— mirror it on the draft (exactly astargetProjectIdis mirrored) so the model is live while editing, before Save As persists it.- On Save As, copy
modelProjectIdfrom draft → newInterlinearProject. On Open, seed it from the project → draft.
Engine / store additions
- Load the model's
TextAnalysisonce (viainterlinearizer.getProject), build its pool withbuildPoolIndex(src/utils/suggestion-engine.ts), and seed it as a staticmodelPoolIndexthat does not recompute on the draft's own edits. deriveTokenSuggestiongains a model tier: the draft's approved bucket owns thesuggestedslot; model entries the draft lacks become additionalcandidates.- Model-derived payloads carry a distinct
producer(e.g."model:{id}") soSuggestionDropdowncan badge "from model" and they're never confused with local suggestions. #218 reuses this. AnalysisStoreProvidergains amodelPoolIndex(ormodelAnalysis) prop, threaded from the loader.
Settings additions
- Add
interlinearizer.useModelSuggestions: booleantoProjectSettingTypes— a per-project view toggle to include/suppress model suggestions, so a user can mute the model without detaching it. The which-project pointer stays on the model (above); only the on/off toggle is a setting.
Key technical wrinkle
buildPoolIndex documents that keying on surface form alone (ignoring writing system) is "correct for v1: the pool is a single source project whose word tokens share one writing system." That assumption holds for a sibling interlinear model only when its writing system matches the source; otherwise the key must extend to (writingSystem, surfaceForm). Either way the model's gloss language must overlap the project's analysisLanguages for gloss?.[analysisLanguage] to resolve.
(The assumption is moot for a major-language model — cross-language surface forms never match, which is exactly why that path uses alignment. See #218.)
Out of scope
- The alignment-based major-language model — #218.
interlinearMode('back-translation' | 'adaptation') — the #94 gap #2 output discriminator; tracked in #149.- The PT9 import pipeline — shipped in #150; attaching an imported project's model is #215.
- Any project-creation UI changes.
Open questions
- One field or two: a single
modelProjectIdfor both model kinds (resolved by inspection), or separatemodelInterlinearProjectId/modelTextProjectId? Decide here, since this issue introduces the field and #218 inherits it. Note the first real writer is #215, populating it from PT9'sPt9InterlinearSetup.modelScrTextId: a PT9 model text can be a resource project (modelIsResource), which is never a sibling interlinear project, so an imported pointer usually resolves to #218's path rather than this tier's. - Explicit pointer vs. implicit shared pool — should the pool implicitly widen to include all of the user's approved glosses on the same source instead of an explicit pointer? Explicit is recommended (matches PT9's mental model, gives control).
- Should this go to
user-questions.mdfor review outside the dev team, given it decides suggestion UX? (per AGENTS.md UX-decisions guidance)
Size: M
Priority: P2 — a real suggestion improvement on its own; PT9 parity additionally needs #218.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with #131 and src/utils/suggestion-engine.ts, then trace interlinearizer.getProject, AnalysisStoreProvider, SuggestionDropdown, ProjectSettingTypes, and the DraftProject/InterlinearProject save and open paths. Check src/store/analysisSlice.ts around selectApprovedIdByTokenRef for the model pool’s approved entries. Done means the surface-form model is persisted and loaded, contributes distinct candidates behind the project toggle, and does not recompute from draft edits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100