feat(ingest): PriorityGate — RFC-003 Phase 1b (logic only, not wired)#57
Merged
Conversation
Pure priority-gate logic for asset-source precedence. Stateless,
deterministic, fully unit-tested — but NOT yet wired into the
ingest hot path. Phase 1b2 will integrate with
processor_assets.mergeCTISIntoAsset once per-field attribution
data (Phase 1d) is populated in asset_sources.contributed_data.
Ship-the-logic-first approach rationale:
1. Gate algorithm is non-trivial (combined Priority + TrustLevels
ranking, ownership semantics, tie-break rules from RFC-003).
Reviewable in isolation with a 12-case test matrix.
2. Integration is the risky part — touches ingest hot path. Better
to validate the algorithm on its own before touching 1,000+
assets/sec ingest throughput.
3. Standalone file, zero runtime cost, easy to revert if customer
answers on open questions mandate changes.
What's in:
- `PriorityGate` interface with CanWrite + FilterProperties
- `defaultPriorityGate` implementation (stateless, share-safe)
- Reason constants (feature_disabled, unowned_field, same_source,
higher_or_equal_rank, lower_rank) — used by metrics + audit
- rankOfSource() combines Priority list position + TrustLevels
buckets into a single comparable integer; listed sources always
outrank TrustLevel-only sources (Q2 rule)
Test matrix (12 cases, all passing):
- Feature off → all writes allowed (regression guard)
- Unowned field → always allowed (new knowledge never blocked)
- Same source → self-overwrite allowed
- Listed beats listed by position
- Listed beats unlisted (Q2)
- TrustLevels outrank each other (Primary > Low)
- Equal rank → allow (Q8 tie-break goes to last-write-wins)
- Priority wins over TrustLevels advisory
- Position is stable (off-by-one regression guard)
- FilterProperties splits allowed vs skipped
- Feature-off fast path returns input unchanged (zero alloc)
- Nil incoming map handled safely
What's NOT in:
- Wiring into processor_assets.go — Phase 1b2
- Writing asset_sources.contributed_data.fields on each ingest — Phase 1d
- Redis cache for tenant settings — Phase 1b3 (perf optimization)
- Skip-audit API (GET /assets/{id}/source-skips) — Phase 1d
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pure priority-gate logic for asset-source precedence. Stateless, deterministic, fully unit-tested — but NOT yet wired into the ingest hot path. Phase 1b2 will integrate with
processor_assets.mergeCTISIntoAsset once per-field attribution data (Phase 1d) is populated in asset_sources.contributed_data.
Ship-the-logic-first approach rationale:
What's in:
PriorityGateinterface with CanWrite + FilterPropertiesdefaultPriorityGateimplementation (stateless, share-safe)Test matrix (12 cases, all passing):
What's NOT in: