metaspn-gates is a config-driven gate + state-machine evaluator for MetaSPN entity pipelines.
- Deterministic gate evaluation from config
- Hard requirements and soft thresholds
- Per-gate per-entity cooldown checks
- Transition attempt snapshots
- Transition application + task emissions
- Config parsing and validation from mapping
metaspn-schemasintegration hooks (currently used for typed emission shaping)- Optional
metaspn-schemasemission shaping (Task+EmissionEnvelope)
evaluate_gates(config, entity_state, features, now)apply_decisions(entity_state, decisions, caused_by=None)parse_state_machine_config(payload)load_state_machine_config(path)
load_state_machine_configcan usemetaspn_schemasparsing/validation hooks when exposed by that package version.- Canonical schema hooks:
- parser:
parse_state_machine_config(mapping payload) - validator:
validate_state_machine_config
- parser:
- If
metaspn_schemasis unavailable, it falls back to JSON parsing only. - Current dependency target:
metaspn-schemas>=0.1.0,<0.2.0. apply_decisions(..., use_schema_envelopes=True)attaches schema-shaped payloads whenentity_state.entity_idis present.
For the sample M0 progression (SEEN -> OBSERVED -> PROFILED) the minimum keys are:
entity_state.state:SEENorOBSERVEDentity_state.track:M0features.ingestion.resolved_entity_id: required forSEEN -> OBSERVEDfeatures.profile.handle: required forOBSERVED -> PROFILEDfeatures.profile.confidence: numeric threshold forOBSERVED -> PROFILED(sample gate uses>= 0.7)
Reference fixture:
/Users/leoguinan/MetaSPN/metaspn-gates/tests/fixtures/m0_state_machine_config.json
For the M1 routing progression (SEEN -> OBSERVED -> PROFILED -> QUALIFIED -> ROUTED) the minimum keys are:
entity_state.state: one ofSEEN,OBSERVED,PROFILED,QUALIFIEDentity_state.track:M1entity_state.entity_id: required for emitted task metadatafeatures.ingestion.resolved_entity_id: required forSEEN -> OBSERVEDfeatures.profile.handle: required forOBSERVED -> PROFILEDfeatures.profile.confidence: thresholded forOBSERVED -> PROFILEDfeatures.social.followers: required floor forPROFILED -> QUALIFIEDfeatures.scores.routing_readiness: required forPROFILED -> QUALIFIEDandQUALIFIED -> ROUTEDfeatures.scores.profile_quality: thresholded forPROFILED -> QUALIFIED
M1 reference fixture:
/Users/leoguinan/MetaSPN/metaspn-gates/tests/fixtures/m1_routing_state_machine_config.json
For recommendation gating (QUALIFIED -> RECOMMENDABLE -> DRAFT_READY) the minimum keys are:
entity_state.state:QUALIFIEDorRECOMMENDABLEentity_state.track:M2entity_state.entity_id: required for downstream task metadatafeatures.profile.handle: required recommendation eligibility hard requirementfeatures.scores.recommendation_score: recommendation and draft thresholdsfeatures.scores.intent_score: recommendation eligibility thresholdfeatures.context.channel: channel-scoped cooldown keyfeatures.context.playbook: playbook-scoped cooldown keyfeatures.context.suppress_recommendations: suppression flag for recommendation gatefeatures.context.suppress_drafts: suppression flag for draft gate
M2 reference fixture:
/Users/leoguinan/MetaSPN/metaspn-gates/tests/fixtures/m2_recommendation_state_machine_config.json
Learning helpers are exposed for reviewable gate analytics artifacts:
evaluate_attempt_outcomes(...)classify_failure_reason(...)generate_calibration_proposals(...)
These produce deterministic outputs for:
- moved-too-early detection
- false-negative/false-positive classification
- calibration recommendations (threshold/cooldown direction hints)
- Calibration outputs are proposal-only artifacts.
- No threshold or cooldown values are auto-applied silently.
- Every proposal has
auto_apply=Falseand must be explicitly approved by a human/operator workflow.
Demo fixture:
/Users/leoguinan/MetaSPN/metaspn-gates/tests/fixtures/demo_state_machine_config.json
Demo progression:
SEEN -> OBSERVEDenqueuesenrich_profileOBSERVED -> SHORTLISTEDenqueuesscore_entitySHORTLISTED -> READYoptionally enqueuesdraft_messagewhenfeatures.demo.draft_enabled=true
Digest explainability helper:
format_decision_trace(decisions)returns rows withpassed,blocked, andreason.format_admin_decision_trace(decisions)returns audit-focused rows for admin review including gate versions, failed requirement ids, and cooldown scope context.
Season 1 fixture:
/Users/leoguinan/MetaSPN/metaspn-gates/tests/fixtures/season1_state_machine_config.json
Season 1 lifecycle states:
NOT_STARTED -> ACTIVE -> ENDED -> CLAIMABLE -> CLOSED
Season 1 policy checks:
evaluate_season1_policy(entity_state, "stake")is allowed only inACTIVEevaluate_season1_policy(entity_state, "unstake")is allowed only inCLAIMABLEevaluate_season1_policy(entity_state, "claim")is allowed only inCLAIMABLE
Season 1 founder heartbeat requirement:
- Activation (
NOT_STARTED -> ACTIVE) requiresfeatures.founder.stake > 0.
Season 1 suppression/cooldown behavior:
- Activation gate uses
cooldown_on="attempt"with a 300-second cooldown, so repeated activation checks are throttled deterministically even on failed attempts. - Suppression is handled through normal gate suppression fields where configured; a
suppressed gate returns reason
suppressedand does not transition or emit tasks.
Token fixture:
/Users/leoguinan/MetaSPN/metaspn-gates/tests/fixtures/token_health_state_machine_config.json
Token minimum keys:
entity_state.state:CANDIDATEorWATCHLISTEDentity_state.track:TOKENfeatures.token.holder_count: hard requirement floorfeatures.token.creator_behavior_risk: hard requirement ceilingfeatures.scores.credibility: threshold for both gatesfeatures.scores.organic_volume: soft thresholdfeatures.scores.concentration: soft thresholdfeatures.token.address,features.token.chain,features.token.symbol: copied into task emission metadata for token workers
- GitHub Actions workflow:
/Users/leoguinan/MetaSPN/metaspn-gates/.github/workflows/publish.yml - Publish trigger: GitHub Release published (or manual
workflow_dispatch) - Publishing method: PyPI Trusted Publishing via
pypa/gh-action-pypi-publish
- In PyPI, create project
metaspn-gatesand configure Trusted Publisher for this GitHub repo/workflow. - In GitHub, create environment
pypi(optional protection rules supported).
- Bump
/Users/leoguinan/MetaSPN/metaspn-gates/pyproject.tomlversion. - Tag and push a release commit.
- Publish a GitHub Release for that tag.
publish.ymlbuilds and uploads to PyPI.