Module: Parse::Embeddings::BindingAudit
- Defined in:
- lib/parse/embeddings/binding_audit.rb
Overview
Checks that a :vector property's declared provider binding
still matches the provider actually registered under that name.
A :vector property may declare provider:, model:, and
dimensions:. Only provider: was ever enforced. dimensions:
is verified — but only against the vector a provider already
returned, i.e. after the call has been made and paid for. And
model: was never checked at all, which is the dangerous one: two
generations of the same model family usually share a width
(voyage-3 and voyage-3.5 are both 1024), so swapping the
registered provider's model silently mixes incompatible
embeddings into one index. Nothing raises, recall just quietly
degrades, and the damage is only repairable by re-embedding.
This module closes both gaps by comparing the declaration against the live provider BEFORE any request is issued.
Auditing cannot happen at class-definition time: providers are registered by name and, as Core::EmbedManaged documents, registration may legitimately happen any time before the first save. So the audit runs lazily on each use and is also exposed as BindingAudit.audit_all! for an explicit boot-time or CI check.
Defined Under Namespace
Classes: BindingMismatch, DiscoveryFailed
Class Method Summary collapse
-
.audit_all!(classes: nil, strict: false) ⇒ Array<String>
Audit every declared binding whose provider is registered.
-
.audit_all_or_raise!(classes: nil, strict: false) ⇒ void
BindingAudit.audit_all! that raises instead of returning problems.
-
.reset! ⇒ void
Retained as a no-op for callers that invoked it when this module memoized verdicts.
-
.verify!(klass, field, provider) ⇒ void
Verify one property binding against a resolved provider.
Class Method Details
.audit_all!(classes: nil, strict: false) ⇒ Array<String>
Audit every declared binding whose provider is registered. Intended for boot or CI: it surfaces a drifted declaration before a single embedding is written, rather than on the first save that happens to touch it.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/parse/embeddings/binding_audit.rb', line 74 def audit_all!(classes: nil, strict: false) problems = [] begin bindings = collect_bindings(classes) rescue DiscoveryFailed => e return [e.] end bindings.each do |klass, field, declared| provider_name = declared[:provider] next if provider_name.nil? begin provider = Parse::Embeddings.provider(provider_name) rescue Parse::Embeddings::ProviderNotRegistered => e problems << "#{klass}##{field}: #{e.}" if strict next end begin check!(klass, field, provider, declared) rescue BindingMismatch => e problems << e. end end problems end |
.audit_all_or_raise!(classes: nil, strict: false) ⇒ void
This method returns an undefined value.
audit_all! that raises instead of returning problems.
106 107 108 109 110 111 112 |
# File 'lib/parse/embeddings/binding_audit.rb', line 106 def audit_all_or_raise!(classes: nil, strict: false) problems = audit_all!(classes: classes, strict: strict) return if problems.empty? raise BindingMismatch, "Parse::Embeddings binding audit failed:\n - #{problems.join("\n - ")}" end |
.reset! ⇒ void
This method returns an undefined value.
Retained as a no-op for callers that invoked it when this module memoized verdicts.
117 118 119 |
# File 'lib/parse/embeddings/binding_audit.rb', line 117 def reset! nil end |
.verify!(klass, field, provider) ⇒ void
This method returns an undefined value.
Verify one property binding against a resolved provider.
Deliberately NOT memoized. The check is a pair of comparisons against values already in memory, so caching it saves nothing measurable — while any cache key cheap enough to be worth computing (class name, provider object id) can go stale when a class is unloaded and redefined with a changed declaration, or when object ids are recycled. A validator that silently skips after a reload is worse than no validator, so correctness wins over an optimization with no observable benefit.
55 56 57 58 59 60 61 |
# File 'lib/parse/embeddings/binding_audit.rb', line 55 def verify!(klass, field, provider) declared = klass.vector_properties[field.to_sym] return if declared.nil? check!(klass, field, provider, declared) nil end |