Skip to content

feat: migrate scoring features to namespaced keys - #10

Merged
jiashuoz merged 2 commits into
mainfrom
feat/namespaced-features
Oct 4, 2026
Merged

jiashuoz merged 2 commits into
mainfrom
feat/namespaced-features

Conversation

@jiashuoz

@jiashuoz jiashuoz commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

Feature keys now use core.*, email.*, and brand.* namespaces. For example, key_total becomes core.credential_total. Rules, weights, extraction, stage gating, CLI inputs, corpus exports, stored reasons, and evaluation artifacts move together; legacy score/corpus inputs fail with feature_renamed and the replacement name.

This implements P1 of the approved generic-feature design. The local scorer keeps the original summation order through immutable registry metadata, and core.Vector carries hash-bucket widths without rounding scorer inputs. Three new namespaced oracles preserve all 8,671 P0 points on ARM64 and both AMD64 math paths. Original flat references remain unchanged; a permanent parity test permits only name/hash/version changes.

Corpus-v2 and cassettes carry feature_key_space: ns-v1. Migration 008 atomically rewrites stored feature keys and rejects unknown flat keys or collisions. Historical reason text remains version 1; new reasons carry version 2 through storage and the Go client. This is a deliberate predeployment format break, with migration guidance in README; no production operations or deployment changes.

Validation:

  • Full suite with ABUSEKIT_REQUIRE_DB=1 go test ./..., lint, and synthetic evaluation gate pass.
  • Native ARM64 and Go 1.23.0 AMD64 non-FMA golden/mutation tests pass; CI covers all three numeric profiles.
  • Seeded Postgres tests preserve numeric values and old reasons, and roll back ambiguous migrations.
  • Built local service: signed ingest, duplicate events, invalid signatures, synchronous evaluation, namespaced reason/version, label snapshot, corpus export, tenant isolation, and CLI scoring/flat-key rejection pass; server logs clean and test database removed.
  • Input-contract regressions were reproduced before fixes, including legacy names and trailing JSON values.

Independent and adversarial review passed after fixes in d3ff2f8:

  • Both reviewers reproduced a legacy-weights compatibility bug; weights now reject flat/mixed keys before scoring (file/construction tests and real CLI check).
  • Added committed fresh/reused reason-version coverage through Postgres and HTTP/SDK.
  • The adversarial review found a reserved-name mismatch between SQL and corpus-v2; SQL now rejects it, with a red-before-green rollback regression.

CI observation: the first run on d3ff2f8 passed all rename/golden/migration checks but failed TestEvaluateSubject_ShortDeadlineDuringClaimNeverLeaksLease once. The lease implementation and test body are unchanged by P1. Focused reproduction passed 20 repetitions on this branch and 100 on base 050ebad; this does not establish the intermittent failure's cause. The failed job passed on rerun without source/test changes; all four final CI checks are green (run 37169875026). The intermittent lease-cleanup failure remains an unresolved follow-up investigation. P1s, tenant profiles, the pack engine, vendor adapters, and hosted deployment remain separate slices.

@jiashuoz
jiashuoz merged commit 9e77c95 into main Oct 4, 2026
7 of 8 checks passed
@jiashuoz
jiashuoz deleted the feat/namespaced-features branch October 4, 2026 08:10
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