Skip to content

feat(ingest): PriorityGate — RFC-003 Phase 1b (logic only, not wired)#57

Merged
0xmanhnv merged 1 commit into
developfrom
feat/asset-source-priority-gate
Apr 23, 2026
Merged

feat(ingest): PriorityGate — RFC-003 Phase 1b (logic only, not wired)#57
0xmanhnv merged 1 commit into
developfrom
feat/asset-source-priority-gate

Conversation

@0xmanhnv
Copy link
Copy Markdown
Collaborator

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

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
@0xmanhnv 0xmanhnv merged commit b2c0536 into develop Apr 23, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant