Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / internal/modules/matching/chainedresolver.go |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | internal/modules/matching/chainedresolver.go |
| Original SHA-256 | f2db6e8d3d2d6022106427d0285dd3e2b6a1d6cf975bba649b5c88e75dd6de5f |
| Git blob SHA | c8a972970c3271b96f687d323bf3b9b6db688501 |
| Reading-copy SHA-256 | f2db6e8d3d2d6022106427d0285dd3e2b6a1d6cf975bba649b5c88e75dd6de5f |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / internal/modules/matching/chainedresolver.go | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / internal/modules/matching/chainedresolver.go | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓65 lines · 2.6 KB
package matching
import (
"context"
"github.com/shopspring/decimal"
"github.com/missionworkforce/missionmatch/internal/modules/matching/engine"
)
// compile-time assertion that ChainedResolver satisfies engine.SkillMatcher.
var _ engine.SkillMatcher = (*ChainedResolver)(nil)
// ChainedResolver runs the deterministic alias and relationship resolver first, then the semantic
// matcher, and satisfies the engine SkillMatcher interface so the engine code is unchanged.
// The resolver is consulted first because curated ontology knowledge (an alias is an exact
// equivalence; a verified substitution has a known strength) is more precise and auditable than a
// cosine similarity. The semantic matcher runs only when the resolver finds no match.
type ChainedResolver struct {
resolver *DeterministicAliasResolver
acronyms *AcronymResolver
semantic engine.SkillMatcher
}
// NewChainedResolver builds a ChainedResolver from a DeterministicAliasResolver and a semantic
// SkillMatcher. Either may be nil: a nil resolver skips the alias step, a nil semantic falls back
// to resolver only (or no match when the resolver also misses).
func NewChainedResolver(resolver *DeterministicAliasResolver, semantic engine.SkillMatcher) *ChainedResolver {
return &ChainedResolver{resolver: resolver, semantic: semantic}
}
// WithAcronyms inserts the acronym and term expansion resolver between the curated alias resolver
// and the semantic matcher: curated knowledge first, deterministic term normalization second,
// cosine similarity last. Returns the resolver for chaining at construction.
func (c *ChainedResolver) WithAcronyms(a *AcronymResolver) *ChainedResolver {
c.acronyms = a
return c
}
// Match satisfies engine.SkillMatcher. It returns the best candidate skill satisfying the required
// skill. The alias resolver runs first; on a hit the result is returned immediately and the semantic
// matcher is never called. On a resolver miss, the semantic matcher runs at the given threshold.
// ctx carries the request deadline and cancellation to both the resolver and any semantic provider call.
func (c *ChainedResolver) Match(
ctx context.Context,
required engine.RequiredSkill,
cands []engine.CandidateSkill,
threshold decimal.Decimal,
) (engine.SkillMatch, bool) {
if c.resolver != nil {
if m, ok := c.resolver.ResolveAlias(ctx, required, cands); ok {
return m, true
}
}
if c.acronyms != nil {
if m, ok := c.acronyms.Match(ctx, required, cands, threshold); ok {
return m, true
}
}
if c.semantic == nil {
return engine.SkillMatch{}, false
}
return c.semantic.Match(ctx, required, cands, threshold)
}