mirror of
https://github.com/PR0M3TH3AN/bitgate.git
synced 2026-10-27 08:31:00 +00:00
The performance fixture the plan asks for found a real defect on its first run: evaluation was quadratic in state size. Both the snapshot and its fingerprint were rebuilt for every target, so each of 5,000 evaluations walked every report and every mute list. A 5,000-target pass took ~47 seconds. - the runtime memoizes the materialized snapshot and its fingerprint until a store reports a change - evaluateMany computes the fingerprint once and shares it across the batch - decisions are cached per (profile, target); report and mute changes invalidate only the targets they touch, while administrative, trust, policy, and viewer changes drop the whole cache - cached decisions are deeply frozen, since the cache hands the same object to every caller Same pass now takes ~85ms cold, ~6ms warm. Adds tests/performance (5,000 targets, 500 authors, 100 muters per author) and tests/security (one case per enumerated requirement testable at this layer). 605 tests; lint, typecheck, and the declaration build pass from a cold checkout.
4.2 KiB
4.2 KiB
Changelog
Notable changes to this repository. The package version and the wire schema version move independently: a breaking package release does not imply a new event schema, and a new schema does not require a major package bump unless the public API changes with it.
[Unreleased]
Added
- Core decision model. Four independent dimensions (
ranking,visibility,interaction,transaction) with severity ladders and commutative max-merge composition. - Stable reason identifiers (
REASON_IDS) as part of the public contract. Renaming or removing one is a breaking change. - Structured evidence, redacted by default and merged across an object's targets, so a multi-target object explains itself with everything that contributed.
- Administrative-state reduction with capability filtering at merge time, community-source marking, and protected-actor stripping.
- Snapshot fingerprints for cache invalidation and mismatch records.
- Application adapter contract (
createApplicationAdapter,evaluateObject,collectTargets). - Codecs: canonical v1 on
kind:30078, NIP-56 reports, NIP-51 mute lists, legacy administrative lists, bech32/NIP-19, replaceable selection with a deterministic same-timestamp tiebreak, injected signature verification. - Runtime: six stores, transport orchestration, chunked report subscriptions, viewer lifecycle, diagnostics, idempotent teardown.
- Commands with local capability checks, protected-target refusal, partial relay acceptance, and stable error codes.
- Characterization corpus: 34 generated fixtures covering the behaviors the migration plan's Phase 0 requires, plus a conformance suite that evaluates them.
- Commerce proof-of-fit (
examples/commerce) demonstrating the engine outside a video application using only the public API. - Decision caching keyed by (profile, target) with targeted invalidation: report and mute changes invalidate only the targets they touch, while administrative, trust, policy, and viewer changes drop the whole cache. Cached decisions are deeply frozen so a consumer cannot corrupt later reads.
- Performance fixture (
tests/performance/) over 5,000 targets, 500 authors, and 100 trusted muters per author, asserting no network access, bounded subscription counts, and targeted invalidation. - Security requirements suite (
tests/security/) covering the enumerated requirements testable at this layer. - GPL-3.0-or-later
LICENSE,README, and an integration guide.
Fixed
- Per-package
typesfields pointed at paths the build never produced, so consumers received no type declarations at all. Declarations now emit per package and resolve. reduceAdminStateaccepted malformed target identifiers, becausegetTargetKeyformats anything it is given.community-user-denyfired for any contributor rather than only for community-curated sources, making a direct moderator action indistinguishable from a federated one.composeDecisionskept only the first decision's evidence, so an object governed by several targets lost the evidence that drove its verdict.OverrideStore.clear()shadowed the inherited listenerclear(), leaking subscribers on teardown. NowclearOverrides().- Evaluation was quadratic in state size: both the snapshot and its fingerprint
were rebuilt for every target, so each call walked every report and mute
list. A 5,000-target pass took ~47s. The runtime now memoizes the snapshot
and its fingerprint until a store changes, and
evaluateManycomputes the fingerprint once for the batch. The same pass now takes ~85ms cold and ~6ms warm.
Changed
- The evaluator no longer carries application thresholds. The previous invented
defaults (5/3/10/5) are gone; applications supply category thresholds through
a policy definition. The characterized reference values live in
@nostr-governance/bitvid-compatas one application's profile. createAuthorityStatetakes an options object and always grants the root every capability and protection.- Evaluation takes a
GovernanceSnapshotand aViewerStaterather than a flat state object, and reads an injected clock instead of wall time.