Summary
After #229 unified stop condition evaluation, the canonical evaluator now runs all 5 conditions (including quorumReviewScore and deliberationLimit) inside the PolicyEnforcer.enforce() pre-write path. This runs inside the EnforcingContributionStore write mutex, meaning every contribution write now pays the cost of:
store.list() — full contribution scan (when quorum or deliberation is configured)
store.thread() per topic root — thread traversal for deliberation depth checks
Impact
For groves with quorumReviewScore or deliberationLimit configured:
- Each write blocks behind the stop evaluation before the mutex is released
- Concurrent writers queue behind one another
- On Nexus-backed stores,
list() can trigger a full remote FTS/manifest scan
- Latency grows with grove size and number of active discussion threads
Groves without these conditions are unaffected (budget, targetMetric, and maxRoundsWithoutImprovement use targeted O(1) queries).
Current mitigations
Proposed approaches
- Scoped evaluation: Only evaluate the thread the incoming contribution touches (requires passing contribution context to the evaluator)
- Materialized aggregates: Maintain per-topic depth/message counters and per-target review counts incrementally on write, so stop checks are O(1) lookups
- Async post-commit evaluation: Move quorum/deliberation checks entirely to the post-write path (already partially implemented for threshold-crossing detection)
Option 2 is the most robust long-term but requires new store schema. Option 3 is the simplest change.
References
Summary
After #229 unified stop condition evaluation, the canonical evaluator now runs all 5 conditions (including
quorumReviewScoreanddeliberationLimit) inside thePolicyEnforcer.enforce()pre-write path. This runs inside theEnforcingContributionStorewrite mutex, meaning every contribution write now pays the cost of:store.list()— full contribution scan (when quorum or deliberation is configured)store.thread()per topic root — thread traversal for deliberation depth checksImpact
For groves with
quorumReviewScoreordeliberationLimitconfigured:list()can trigger a full remote FTS/manifest scanGroves without these conditions are unaffected (budget, targetMetric, and maxRoundsWithoutImprovement use targeted O(1) queries).
Current mitigations
Promise.all(protocol: stop condition evaluators disagree between lifecycle.ts and policy-enforcer.ts #229)maxRoundsis configured (protocol: stop condition evaluators disagree between lifecycle.ts and policy-enforcer.ts #229)Proposed approaches
Option 2 is the most robust long-term but requires new store schema. Option 3 is the simplest change.
References