๐ System State Transitions and Lifecycle Management
๐ฏ Behavioral Model for Static News Generation Platform
๐ Document Owner: CEO | ๐ Version: 1.4 | ๐
Last Updated:
2026-05-06 (UTC) | ๐ท๏ธ Platform Release: v0.8.54
๐ Review Cycle: Quarterly | โฐ Next Review: 2026-08-03
๐ท๏ธ Classification: Public (Open Source European Parliament Monitoring
Platform)
| Document | Focus | Description | Documentation Link |
|---|---|---|---|
| Architecture | ๐๏ธ Architecture | C4 model showing current system structure | View Source |
| Future Architecture | ๐๏ธ Architecture | C4 model showing future system structure | View Source |
| Mindmaps | ๐ง Concept | Current system component relationships | View Source |
| Future Mindmaps | ๐ง Concept | Future capability evolution | View Source |
| SWOT Analysis | ๐ผ Business | Current strategic assessment | View Source |
| Future SWOT Analysis | ๐ผ Business | Future strategic opportunities | View Source |
| Data Model | ๐ Data | Current data structures and relationships | View Source |
| Future Data Model | ๐ Data | Enhanced European Parliament data architecture | View Source |
| Flowcharts | ๐ Process | Current data processing workflows | View Source |
| Future Flowcharts | ๐ Process | Enhanced AI-driven workflows | View Source |
| State Diagrams | ๐ Behavior | Current system state transitions | View Source |
| Future State Diagrams | ๐ Behavior | Enhanced adaptive state transitions | View Source |
| Security Architecture | ๐ก๏ธ Security | Current security implementation | View Source |
| Future Security Architecture | ๐ก๏ธ Security | Security enhancement roadmap | View Source |
| Threat Model | ๐ฏ Security | STRIDE threat analysis | View Source |
| Classification | ๐ท๏ธ Governance | CIA classification & BCP | View Source |
| CRA Assessment | ๐ก๏ธ Compliance | Cyber Resilience Act | View Source |
| Workflows | โ๏ธ DevOps | CI/CD documentation | View Source |
| Future Workflows | ๐ DevOps | Planned CI/CD enhancements | View Source |
| Business Continuity Plan | ๐ Resilience | Recovery planning | View Source |
| Financial Security Plan | ๐ฐ Financial | Cost & security analysis | View Source |
| End-of-Life Strategy | ๐ฆ Lifecycle | Technology EOL planning | View Source |
| Unit Test Plan | ๐งช Testing | Unit testing strategy | View Source |
| E2E Test Plan | ๐ Testing | End-to-end testing | View Source |
| Performance Testing | โก Performance | Performance benchmarks | View Source |
| Security Policy | ๐ Security | Vulnerability reporting & security policy | View Source |
This state diagram documentation implements controls aligned with Hack23 AB's publicly available ISMS framework.
| Policy | Relevance |
|---|---|
| Secure Development Policy | State management follows secure SDLC lifecycle |
| Information Security Policy | System state transitions comply with security governance |
| Incident Response Plan | Error and failure states trigger incident response procedures |
| Change Management Policy | Deployment state transitions follow change management process |
This document defines all state transitions and lifecycles in the EU Parliament Monitor system. State diagrams capture behavioral aspects that complement the structural views (C4 model), data views (ERD), and process flows (flowcharts).
State diagrams serve to:
EU Parliament Monitor is a static site generator with:
The overall system operates in phases from initialization through publication and monitoring.
stateDiagram-v2
[*] --> Idle: System Ready
Idle --> Initializing: Workflow Triggered<br/>(Schedule/Manual)
Initializing --> ConfigurationLoading: Load Configuration
ConfigurationLoading --> EnvironmentValidation: Validate Environment
EnvironmentValidation --> DependencyCheck: Check Dependencies
DependencyCheck --> DependencyInstall: Missing Dependencies
DependencyInstall --> DependencyCheck: Retry
DependencyCheck --> InitializationFailed: Max Retries Exceeded
DependencyCheck --> Ready: All Dependencies OK
Ready --> MCPConnection: Connect to Data Sources
state MCPConnection {
[*] --> ConnectingMCP
ConnectingMCP --> MCPConnected: Connection Successful
ConnectingMCP --> MCPRetrying: Connection Failed
MCPRetrying --> ConnectingMCP: Backoff Wait
MCPRetrying --> MCPFallback: Max Retries
MCPConnected --> [*]
MCPFallback --> [*]
}
MCPConnection --> DataFetching: Data Source Ready
DataFetching --> Generating: Data Retrieved
DataFetching --> GeneratingFallback: MCP Unavailable
Generating --> Validating: Articles Generated
GeneratingFallback --> Validating: Placeholder Content
Validating --> Testing: Validation Passed
Validating --> ValidationFailed: Validation Failed
ValidationFailed --> Generating: Fix & Retry
Testing --> TestFailed: Tests Failed
Testing --> Publishing: Tests Passed
TestFailed --> [*]: Abort Workflow
Publishing --> Deployed: Git Push Success
Publishing --> PublishFailed: Git Push Failed
PublishFailed --> Publishing: Retry
PublishFailed --> [*]: Max Retries
Deployed --> Monitoring: GitHub Pages Deploy
Monitoring --> Idle: Complete
InitializationFailed --> [*]: Fatal Error
note right of Idle
Waiting for next scheduled
execution (06:00 UTC) or
manual workflow_dispatch
end note
note right of MCPConnection
European Parliament MCP Server
connection with retry logic
and graceful fallback
end note
note right of Deployed
Static files committed to
main branch, GitHub Pages
automatically deploys
end note
| State | Description | Entry Conditions | Exit Conditions | Timeout |
|---|---|---|---|---|
| Idle | System waiting for trigger | Previous workflow complete OR system startup | Schedule reached OR manual dispatch | N/A |
| Initializing | Loading configuration and environment | Workflow triggered | Config loaded successfully | 30s |
| ConfigurationLoading | Reading package.json, .env files | Initialization started | Config parsed and validated | 10s |
| EnvironmentValidation | Checking environment variables, Node version | Config loaded | Environment meets requirements | 10s |
| DependencyCheck | Verifying npm packages installed | Environment validated | All deps available OR missing deps identified | 15s |
| DependencyInstall | Running npm ci to install packages |
Missing dependencies detected | Installation complete | 180s |
| InitializationFailed | Fatal error during startup | Repeated failures, missing critical config | Workflow terminates | N/A |
| Ready | System prepared to execute generation | All checks passed | Data source connection initiated | 5s |
| MCPConnection | Connecting to European Parliament MCP Server | Ready state achieved | Connected OR fallback mode | 30s |
| DataFetching | Retrieving parliamentary data via MCP | MCP connected | Data retrieved OR fallback | 60s |
| Generating | Creating multi-language articles | Data available | All articles generated | 300s |
| GeneratingFallback | Creating placeholder articles | MCP unavailable | Placeholder articles generated | 60s |
| Validating | Running HTML validation, schema checks | Generation complete | Validation passed OR failed | 45s |
| ValidationFailed | Detected invalid output | Validation checks failed | Retry generation OR abort | 10s |
| Testing | Executing ESLint, tests, security scans | Validation passed | Tests passed OR failed | 120s |
| TestFailed | Test suite failures detected | Test execution failed | Workflow aborted | 10s |
| Publishing | Committing and pushing to Git | Tests passed | Git push successful OR failed | 30s |
| PublishFailed | Git push failed | Git operation failed | Retry OR abort | 10s |
| Deployed | Changes pushed to GitHub | Git push successful | GitHub Pages deployment initiated | 5s |
| Monitoring | Awaiting GitHub Pages deployment | Deployed | Deployment complete | 180s |
Legal Transitions:
Illegal Transitions (prevented by workflow):
Individual news articles progress through generation, validation, publication, and archival states.
stateDiagram-v2
[*] --> ArticlePending: Article Scheduled
ArticlePending --> DataCollecting: Fetch Source Data
state DataCollecting {
[*] --> FetchingPlenary
FetchingPlenary --> FetchingCommittee: Plenary Data OK
FetchingCommittee --> FetchingDocuments: Committee Data OK
FetchingDocuments --> FetchingQuestions: Document Data OK
FetchingQuestions --> DataComplete: Question Data OK
FetchingPlenary --> DataFetchError: API Error
FetchingCommittee --> DataFetchError: API Error
FetchingDocuments --> DataFetchError: API Error
FetchingQuestions --> DataFetchError: API Error
DataFetchError --> FetchingPlenary: Retry
DataFetchError --> DataFallback: Max Retries
DataComplete --> [*]
DataFallback --> [*]
}
DataCollecting --> ContentGeneration: Data Available
state ContentGeneration {
[*] --> TemplateLoading
TemplateLoading --> LLMPrompting: Template Ready
LLMPrompting --> ContentReceived: LLM Response OK
LLMPrompting --> LLMRetry: LLM Error
LLMRetry --> LLMPrompting: Backoff
LLMRetry --> PlaceholderContent: Max Retries
ContentReceived --> [*]
PlaceholderContent --> [*]
}
ContentGeneration --> ArticleDraft: Content Generated
ArticleDraft --> LanguageProcessing: Process All Languages
state LanguageProcessing {
[*] --> ProcessingEN
ProcessingEN --> ProcessingSV: English OK
ProcessingSV --> ProcessingDA: Swedish OK
ProcessingDA --> ProcessingNO: Danish OK
ProcessingNO --> ProcessingFI: Norwegian OK
ProcessingFI --> ProcessingDE: Finnish OK
ProcessingDE --> ProcessingFR: German OK
ProcessingFR --> ProcessingES: French OK
ProcessingES --> ProcessingNL: Spanish OK
ProcessingNL --> ProcessingAR: Dutch OK
ProcessingAR --> ProcessingHE: Arabic OK
ProcessingHE --> ProcessingJA: Hebrew OK
ProcessingJA --> ProcessingKO: Japanese OK
ProcessingKO --> ProcessingZH: Korean OK
ProcessingZH --> AllLanguagesComplete: Chinese OK
ProcessingEN --> LanguageError: Translation Failed
ProcessingDE --> LanguageError: Translation Failed
ProcessingFR --> LanguageError: Translation Failed
LanguageError --> ProcessingEN: Retry Language
LanguageError --> PartialLanguageSet: Skip Language
AllLanguagesComplete --> [*]
PartialLanguageSet --> [*]
}
LanguageProcessing --> ArticleValidation: All Languages Processed
state ArticleValidation {
[*] --> HTMLValidation
HTMLValidation --> SchemaValidation: HTML Valid
SchemaValidation --> ContentValidation: Schema Valid
ContentValidation --> SecurityValidation: Content Valid
SecurityValidation --> ValidationComplete: Security OK
HTMLValidation --> ValidationFailed: Invalid HTML
SchemaValidation --> ValidationFailed: Invalid Schema
ContentValidation --> ValidationFailed: Invalid Content
SecurityValidation --> ValidationFailed: Security Issue
ValidationComplete --> [*]
ValidationFailed --> [*]
}
ArticleValidation --> ArticleValidated: Validation Passed
ArticleValidation --> ArticleRejected: Validation Failed
ArticleRejected --> ArticleDraft: Fix Issues
ArticleRejected --> ArticleAbandoned: Unfixable
ArticleValidated --> ArticleStaging: Ready for Publish
ArticleStaging --> ArticlePublished: Git Commit Success
ArticlePublished --> ArticleIndexed: Add to Index
ArticleIndexed --> ArticleLive: GitHub Pages Deploy
ArticleLive --> ArticleMonitored: Active Monitoring
ArticleMonitored --> ArticleArchived: 90 Days Old
ArticleArchived --> [*]: Lifecycle Complete
ArticleAbandoned --> [*]: Generation Failed
note right of ArticlePending
14 article types:
Short-form (8):
- Breaking News (every 4h)
- Week Ahead / Week in Review
- Month Ahead / Month in Review
- Committee Reports
- Motions / Propositions
Long-horizon prospective (2):
- Quarter Ahead (T+90d)
- Year Ahead (T+365d)
Long-horizon retrospective (2):
- Quarter in Review
- Year in Review
Electoral overlay (2):
- Term Outlook (today โ next-election)
- Election Cycle (ยฑ6 mo around election)
Each driven by a unified
news-<type>.md gh-aw workflow
(Stages AโE in one session,
deterministic HTML rendered
from Stage-B artifacts by
src/aggregator/article-generator.ts).
Horizon registry:
src/config/article-horizons.ts
(single source of truth for
data window, cadence, mandatory
artifacts, stage budgets,
electoral overlay).
end note
note right of ContentGeneration
LLM generates article with:
- Title & subtitle
- Summary paragraph
- Detailed analysis
- Key points
- Citations
end note
note right of LanguageProcessing
14 languages:
EN, SV, DA, NO, FI, DE,
FR, ES, NL, AR, HE, JA,
KO, ZH
end note
note right of ArticleLive
Immutable content:
Never modified after
publication
end note
| State | Description | Duration | Rollback Possible |
|---|---|---|---|
| ArticlePending | Article scheduled for generation | 0-60s | Yes |
| DataCollecting | Fetching source data from EP APIs | 10-60s | Yes |
| ContentGeneration | LLM creating article content | 15-120s | Yes |
| ArticleDraft | Initial content created | 0-5s | Yes |
| LanguageProcessing | Translating to all languages | 30-300s | Yes |
| ArticleValidation | Running validation checks | 10-30s | Yes |
| ArticleRejected | Failed validation | Until fixed | Yes |
| ArticleAbandoned | Permanently failed | Permanent | No |
| ArticleValidated | Passed all checks | 0-5s | Yes |
| ArticleStaging | Ready for commit | 0-10s | Yes |
| ArticlePublished | Committed to Git | Permanent | No* |
| ArticleIndexed | Added to language indexes | Permanent | No |
| ArticleLive | Deployed on GitHub Pages | Until archived | No |
| ArticleMonitored | Active monitoring | 90 days | No |
| ArticleArchived | Moved to archive | Permanent | No |
*Git history allows reverting, but articles are conceptually immutable.
Stage-A DataCollecting and Stage-B ContentGeneration follow a different artifact path depending on the horizon family resolved from src/config/article-horizons.ts:
stateDiagram-v2
[*] --> ResolveHorizon: News workflow dispatched
ResolveHorizon --> StandardShortForm: breaking ยท week-* ยท month-* ยท committee-reports ยท motions ยท propositions
ResolveHorizon --> LongHorizonProspective: quarter-ahead ยท year-ahead
ResolveHorizon --> LongHorizonRetrospective: quarter-in-review ยท year-in-review
ResolveHorizon --> ElectoralOverlay: term-outlook ยท election-cycle
state StandardShortForm {
[*] --> ShortForm_StageA: 5 min budget
ShortForm_StageA --> ShortForm_StageB: 22 min budget
ShortForm_StageB --> ShortForm_StageC: 4 min ยท exit minute 36
ShortForm_StageC --> ShortForm_StageD: 2 min budget
ShortForm_StageD --> ShortForm_PR: 2 min ยท PR โค minute 45
}
state LongHorizonProspective {
[*] --> LHP_StageA: 5 min budget
LHP_StageA --> LHP_StageB: 24-25 min budget ยท forward-projection ยท legislative-pipeline-forecast ยท parliamentary-calendar-projection
LHP_StageB --> LHP_StageC: 4 min ยท exit minute 38-39
LHP_StageC --> LHP_StageD: 2 min budget
LHP_StageD --> LHP_PR: 2 min ยท PR โค minute 45
}
state LongHorizonRetrospective {
[*] --> LHR_StageA: 4-5 min budget
LHR_StageA --> LHR_StageB: 24-25 min budget ยท cross-run-diff ยท cross-session-intelligence ยท pipeline-forecast
LHR_StageB --> LHR_StageC: 4 min ยท exit minute 38-39
LHR_StageC --> LHR_StageD: 2 min budget
LHR_StageD --> LHR_PR: 2 min ยท PR โค minute 45
}
state ElectoralOverlay {
[*] --> EO_StageA: 5 min budget
EO_StageA --> EO_StageB: 26-28 min budget ยท electoral artifact set mandatory<br/>term-arc ยท seat-projection ยท mandate-fulfilment-scorecard<br/>presidency-trio-context ยท commission-wp-alignment ยท forward-indicators<br/>+ EP-election scenario branch in scenario-forecast
EO_StageB --> EO_StageC: 4 min ยท exit minute 42 ยท electoral invariants asserted
EO_StageC --> EO_StageD: 2 min budget
EO_StageD --> EO_PR: 2 min ยท PR โค minute 47
}
ShortForm_PR --> [*]: ArticlePublished
LHP_PR --> [*]: ArticlePublished
LHR_PR --> [*]: ArticlePublished
EO_PR --> [*]: ArticlePublished
note right of ResolveHorizon
Horizon registry returns:
- dataWindow (forward/backward/span)
- cadence + auxiliary triggers
- mandatoryArtifacts list
- stageBudgets {A,B,C,D,E}
- electoralOverlay flag
end note
note right of ElectoralOverlay
Stage-C completeness gate
asserts these invariants when
electoralOverlay = true:
1. mandate-fulfilment-scorecard
is present
2. seat-projection is present
3. scenario-forecast contains
an EP-election outcome branch
4. forwardStatementsHorizonDays
is bounded at โค 1825
end note
The drift-guard test test/unit/horizon-registry.test.js asserts every horizon's stageBudgets sum is โค 50 to leave the 10-min buffer for sandbox setup, MCP gateway boot and the safe-output create_pull_request round-trip within the 60-min timeout-minutes cap.
The Model Context Protocol (MCP) connection manages connectivity to the European Parliament data server.
stateDiagram-v2
[*] --> Disconnected: System Start
Disconnected --> Connecting: Initialize Connection
Connecting --> Authenticating: TCP/Stdio Connected
Connecting --> ConnectionTimeout: Timeout (10s)
Authenticating --> Connected: Auth Success
Authenticating --> AuthFailed: Auth Failed
ConnectionTimeout --> RetryWait: Transient Error
AuthFailed --> RetryWait: Retry Auth
RetryWait --> RetryCount: Backoff Complete
state RetryCount <<choice>>
RetryCount --> Connecting: Retry < 3
RetryCount --> FallbackMode: Retry >= 3
Connected --> Healthy: Health Check OK
Healthy --> Active: Ready for Requests
Active --> RequestSending: Tool Call
state RequestSending {
[*] --> SerializingRequest
SerializingRequest --> SendingData: JSON Ready
SendingData --> AwaitingResponse: Data Sent
AwaitingResponse --> ReceivingData: Response Started
ReceivingData --> DeserializingResponse: Data Complete
DeserializingResponse --> RequestComplete: Parse OK
AwaitingResponse --> RequestTimeout: Timeout (30s)
DeserializingResponse --> RequestError: Parse Error
RequestComplete --> [*]
RequestTimeout --> [*]
RequestError --> [*]
}
RequestSending --> Active: Request Success
RequestSending --> RequestFailed: Request Failed
RequestFailed --> RetryRequest: Transient Error
RetryRequest --> RequestSending: Retry
RequestFailed --> Degraded: Persistent Errors
Active --> Degraded: Health Check Failed
Degraded --> Reconnecting: Attempt Recovery
Reconnecting --> Connected: Reconnect Success
Reconnecting --> Disconnected: Reconnect Failed
Connected --> Disconnected: Connection Lost
Disconnected --> FallbackMode: Max Failures
FallbackMode --> [*]: Use Placeholder Content
note right of Disconnected
MCP server not available:
- Server not running
- Network unreachable
- Configuration error
end note
note right of Connected
MCP protocol handshake
complete, server ready
for tool requests
end note
note right of Active
Connection pooling:
- Reuse connection
- Keep-alive pings
- Request queueing
end note
note right of FallbackMode
Graceful degradation:
Generate articles with
placeholder content
end note
| State | Description | Timeout | Recovery Action |
|---|---|---|---|
| Disconnected | No active connection | N/A | Initialize connection |
| Connecting | TCP/stdio connection in progress | 10s | Retry with backoff |
| Authenticating | MCP handshake and auth | 5s | Retry auth |
| ConnectionTimeout | Connection attempt exceeded timeout | N/A | Enter retry wait |
| AuthFailed | Authentication rejected | N/A | Check credentials, retry |
| RetryWait | Exponential backoff delay | 1s, 2s, 4s | Retry connecting |
| Connected | MCP handshake complete | N/A | Proceed to health check |
| Healthy | Server health verified | N/A | Transition to active |
| Active | Ready for tool requests | N/A | Process requests |
| RequestSending | Tool call in progress | 30s | Retry on timeout |
| RequestFailed | Request failed | N/A | Retry or degrade |
| Degraded | Persistent errors detected | N/A | Attempt reconnection |
| Reconnecting | Attempting to restore connection | 10s | Reconnect or disconnect |
| FallbackMode | Using placeholder content | N/A | Continue with fallback |
Retry Policy:
Fallback Triggers:
Data and content validation occurs at multiple stages with different validation rules.
stateDiagram-v2
[*] --> ValidationQueued: Data/Content Ready
ValidationQueued --> SchemaValidation: Start Validation
state SchemaValidation {
[*] --> CheckStructure
CheckStructure --> CheckTypes: Structure OK
CheckTypes --> CheckRequired: Types OK
CheckRequired --> CheckConstraints: Required OK
CheckConstraints --> SchemaValid: Constraints OK
CheckStructure --> SchemaInvalid: Missing Fields
CheckTypes --> SchemaInvalid: Type Mismatch
CheckRequired --> SchemaInvalid: Required Missing
CheckConstraints --> SchemaInvalid: Constraint Violation
SchemaValid --> [*]
SchemaInvalid --> [*]
}
SchemaValidation --> ContentValidation: Schema Valid
SchemaValidation --> ValidationFailed: Schema Invalid
state ContentValidation {
[*] --> SanitizeHTML
SanitizeHTML --> RemoveScripts: Strip Dangerous Tags
RemoveScripts --> RemoveEvents: Remove <script> tags
RemoveEvents --> EncodeEntities: Remove onX handlers
EncodeEntities --> ValidateLinks: Encode < > & " '
ValidateLinks --> CheckLength: Verify URLs
CheckLength --> ContentValid: Length OK
CheckLength --> ContentInvalid: Too Long/Short
ValidateLinks --> ContentInvalid: Broken Links
ContentValid --> [*]
ContentInvalid --> [*]
}
ContentValidation --> SecurityValidation: Content Valid
ContentValidation --> ValidationFailed: Content Invalid
state SecurityValidation {
[*] --> XSSCheck
XSSCheck --> SQLInjectionCheck: No XSS
SQLInjectionCheck --> CSRFCheck: No SQLi
CSRFCheck --> ClickjackCheck: No CSRF
ClickjackCheck --> SecurityValid: No Clickjack
XSSCheck --> SecurityInvalid: XSS Detected
SQLInjectionCheck --> SecurityInvalid: SQLi Detected
CSRFCheck --> SecurityInvalid: CSRF Risk
ClickjackCheck --> SecurityInvalid: Clickjack Risk
SecurityValid --> [*]
SecurityInvalid --> [*]
}
SecurityValidation --> HTMLValidation: Security Valid
SecurityValidation --> ValidationFailed: Security Invalid
state HTMLValidation {
[*] --> ParseHTML
ParseHTML --> CheckDoctype: Parse OK
CheckDoctype --> CheckMeta: Doctype OK
CheckMeta --> CheckSemantic: Meta OK
CheckSemantic --> CheckAccessibility: Semantic OK
CheckAccessibility --> HTMLValid: Accessibility OK
ParseHTML --> HTMLInvalid: Parse Error
CheckDoctype --> HTMLInvalid: Missing/Wrong
CheckMeta --> HTMLInvalid: Meta Issues
CheckSemantic --> HTMLInvalid: Semantic Issues
CheckAccessibility --> HTMLInvalid: A11y Issues
HTMLValid --> [*]
HTMLInvalid --> [*]
}
HTMLValidation --> ValidationComplete: HTML Valid
HTMLValidation --> ValidationFailed: HTML Invalid
ValidationComplete --> [*]: All Checks Passed
ValidationFailed --> ErrorLogging: Log Failure Details
ErrorLogging --> RetryDecision: Assess Error
state RetryDecision <<choice>>
RetryDecision --> RetryGeneration: Fixable Error
RetryDecision --> RejectContent: Unfixable Error
RetryGeneration --> ValidationQueued: Retry
RejectContent --> [*]: Validation Failed
note right of SchemaValidation
JSON Schema validation:
- Structure conformance
- Type checking
- Required fields
- Value constraints
end note
note right of ContentValidation
Content sanitization:
- XSS prevention
- HTML injection
- Link validation
- Length limits
end note
note right of SecurityValidation
Security scanning:
- OWASP Top 10
- Input validation
- Output encoding
- CSP compliance
end note
| Validation Type | Checks Performed | Failure Action | Retry Allowed |
|---|---|---|---|
| Schema Validation | JSON structure, types, required fields, constraints | Log error, reject data | Yes (1 retry) |
| Content Validation | HTML sanitization, link validation, length checks | Log error, sanitize or reject | Yes (auto-fix) |
| Security Validation | XSS, SQLi, CSRF, clickjacking, CSP violations | Log error, reject content | No |
| HTML Validation | Parse errors, doctype, meta tags, semantics, accessibility | Log error, auto-fix or reject | Yes (auto-fix) |
The system handles errors through structured error states with recovery paths.
stateDiagram-v2
[*] --> OperationNormal: Normal Operation
OperationNormal --> ErrorDetected: Exception/Failure
ErrorDetected --> ErrorClassification: Classify Error
state ErrorClassification <<choice>>
ErrorClassification --> TransientError: Retryable
ErrorClassification --> PersistentError: Non-Retryable
ErrorClassification --> FatalError: Critical
state TransientError {
[*] --> NetworkError
[*] --> TimeoutError
[*] --> RateLimitError
[*] --> ServiceUnavailable
NetworkError --> RetryQueue: Log & Queue
TimeoutError --> RetryQueue: Log & Queue
RateLimitError --> BackoffQueue: Log & Wait
ServiceUnavailable --> RetryQueue: Log & Queue
RetryQueue --> [*]
BackoffQueue --> [*]
}
TransientError --> RetryAttempt: Enter Retry
state RetryAttempt {
[*] --> WaitBackoff
WaitBackoff --> IncrementCounter: Backoff Complete
IncrementCounter --> CheckRetryLimit: Counter++
state CheckRetryLimit <<choice>>
CheckRetryLimit --> RetryOperation: Retry < Max
CheckRetryLimit --> ExhaustedRetries: Retry >= Max
RetryOperation --> [*]: Retry
ExhaustedRetries --> [*]: Give Up
}
RetryAttempt --> OperationNormal: Retry Success
RetryAttempt --> PersistentError: Max Retries
state PersistentError {
[*] --> ValidationError
[*] --> ConfigurationError
[*] --> DataQualityError
[*] --> AuthenticationError
ValidationError --> ErrorLogged: Log Details
ConfigurationError --> ErrorLogged: Log Details
DataQualityError --> ErrorLogged: Log Details
AuthenticationError --> ErrorLogged: Log Details
ErrorLogged --> [*]
}
PersistentError --> FallbackMode: Use Fallback
state FallbackMode {
[*] --> UsePlaceholder
UsePlaceholder --> ContinueWorkflow: Placeholder Active
ContinueWorkflow --> [*]
}
FallbackMode --> OperationDegraded: Continue with Limitations
state FatalError {
[*] --> SystemError
[*] --> SecurityViolation
[*] --> DataCorruption
[*] --> ResourceExhaustion
SystemError --> CriticalAlert: Alert Team
SecurityViolation --> CriticalAlert: Alert Team
DataCorruption --> CriticalAlert: Alert Team
ResourceExhaustion --> CriticalAlert: Alert Team
CriticalAlert --> [*]
}
FatalError --> WorkflowAborted: Terminate
WorkflowAborted --> NotificationSent: Send Alerts
NotificationSent --> [*]: End Workflow
OperationDegraded --> OperationNormal: Recovery
note right of TransientError
Retry with exponential backoff:
- 1st retry: 1s delay
- 2nd retry: 2s delay
- 3rd retry: 4s delay
Max 3 retries
end note
note right of PersistentError
Errors requiring intervention:
- Invalid configuration
- Bad input data
- Authentication issues
- Resource not found
end note
note right of FatalError
Critical failures:
- Security violations
- Data corruption
- Out of memory
- Infinite loops
end note
| Error Type | Severity | Retry Strategy | Fallback | Alert |
|---|---|---|---|---|
| Network Error | Transient | 3 retries, exponential backoff | Continue with cache | No |
| Timeout Error | Transient | 3 retries, extended timeout | Skip operation | No |
| Rate Limit Error | Transient | Wait + retry (per X-RateLimit headers) | Queue for later | No |
| Service Unavailable | Transient | 3 retries, exponential backoff | Use fallback service | Warning |
| Validation Error | Persistent | 1 retry with fix | Use last valid data | Warning |
| Configuration Error | Persistent | No retry | Use defaults | Error |
| Data Quality Error | Persistent | No retry | Skip corrupt data | Warning |
| Authentication Error | Persistent | 1 retry | Abort workflow | Error |
| System Error | Fatal | No retry | Abort | Critical |
| Security Violation | Fatal | No retry | Abort | Critical |
| Data Corruption | Fatal | No retry | Abort | Critical |
| Resource Exhaustion | Fatal | No retry | Abort | Critical |
After content generation, the deployment process manages Git operations and GitHub Pages deployment.
stateDiagram-v2
[*] --> PreDeployment: Content Validated
PreDeployment --> GitStaging: Stage Changes
state GitStaging {
[*] --> GitAdd
GitAdd --> GitStatus: Add Files
GitStatus --> ChangesStaged: Verify
ChangesStaged --> [*]
GitAdd --> GitError: Add Failed
GitStatus --> GitError: Status Check Failed
GitError --> [*]
}
GitStaging --> GitCommit: Files Staged
GitStaging --> DeploymentFailed: Staging Failed
state GitCommit {
[*] --> CreateCommit
CreateCommit --> SignCommit: Commit Created
SignCommit --> VerifyCommit: Signature Added
VerifyCommit --> CommitComplete: Verify OK
CreateCommit --> CommitError: Commit Failed
SignCommit --> CommitError: Sign Failed
VerifyCommit --> CommitError: Verify Failed
CommitComplete --> [*]
CommitError --> [*]
}
GitCommit --> GitPush: Commit Success
GitCommit --> DeploymentFailed: Commit Failed
state GitPush {
[*] --> PushToRemote
PushToRemote --> VerifyPush: Push Initiated
VerifyPush --> PushSuccess: Remote Updated
PushToRemote --> PushConflict: Conflict Detected
PushConflict --> PullRebase: Pull Changes
PullRebase --> PushToRemote: Retry Push
PushToRemote --> PushError: Network Error
PushError --> RetryPush: Retry
RetryPush --> PushToRemote: Wait & Retry
PushSuccess --> [*]
PushError --> [*]
}
GitPush --> GitHubPagesQueue: Push Success
GitPush --> DeploymentFailed: Push Failed
state GitHubPagesQueue {
[*] --> Queued
Queued --> Building: Build Started
Building --> Deploying: Build Success
Deploying --> DeploySuccess: Deploy Complete
Building --> BuildError: Build Failed
Deploying --> DeployError: Deploy Failed
BuildError --> [*]
DeployError --> [*]
DeploySuccess --> [*]
}
GitHubPagesQueue --> DeploymentComplete: Pages Live
GitHubPagesQueue --> DeploymentFailed: Pages Failed
DeploymentComplete --> VerifyDeployment: Verify
state VerifyDeployment {
[*] --> HealthCheck
HealthCheck --> ValidateContent: HTTP 200
ValidateContent --> CheckIndexes: Content OK
CheckIndexes --> VerifySuccess: Indexes OK
HealthCheck --> VerifyFailed: HTTP Error
ValidateContent --> VerifyFailed: Content Mismatch
CheckIndexes --> VerifyFailed: Missing Indexes
VerifySuccess --> [*]
VerifyFailed --> [*]
}
VerifyDeployment --> DeploymentMonitored: Verify Success
VerifyDeployment --> DeploymentDegraded: Verify Failed
DeploymentMonitored --> [*]: Deployment Complete
DeploymentFailed --> ErrorNotification: Alert Team
DeploymentDegraded --> WarningNotification: Alert Team
ErrorNotification --> [*]: Workflow Failed
WarningNotification --> DeploymentMonitored: Continue Monitoring
note right of GitCommit
Commit includes:
- Generated articles
- Updated indexes
- Sitemap.xml
Co-authored-by trailer
end note
note right of GitHubPagesQueue
GitHub Pages automatically:
- Builds Jekyll site
- Deploys to CDN
- Updates DNS
~90-180 seconds
end note
note right of VerifyDeployment
Post-deployment checks:
- HTTP status codes
- Content integrity
- Index availability
- Sitemap accessibility
end note
| State | Description | Duration | Rollback |
|---|---|---|---|
| PreDeployment | Final checks before commit | 5s | Yes |
| GitStaging | Adding files to Git index | 10s | Yes |
| GitCommit | Creating signed commit | 5s | Yes |
| GitPush | Pushing to GitHub remote | 10-30s | No* |
| GitHubPagesQueue | GitHub Pages build queue | 30-90s | No |
| Building | Jekyll build process | 30-60s | No |
| Deploying | CDN deployment | 30-60s | No |
| DeploymentComplete | Live on GitHub Pages | Permanent | No |
| VerifyDeployment | Post-deploy validation | 30s | N/A |
| DeploymentMonitored | Monitoring active | Ongoing | N/A |
| DeploymentFailed | Critical failure | N/A | Rollback |
| DeploymentDegraded | Partial failure | Until fixed | Manual |
*Git push can be reverted with git revert, but GitHub Pages redeploys.
The deterministic aggregator in src/aggregator/ is the canonical post-April-2026 execution spine invoked by every unified news-<type>.md agentic workflow at Stage D. Each module has explicit entry/exit states.
stateDiagram-v2
[*] --> FetchStage: Strategy.run() invoked
state FetchStage {
[*] --> FetchingEP
FetchingEP --> FetchingWB: EP OK
FetchingEP --> FetchingEPRetry: Unavailable envelope
FetchingEPRetry --> FetchingEP: Backoff (mcp-retry.ts)
FetchingEPRetry --> FetchingWB: Max retries (degrade)
FetchingWB --> FetchingIMF: WB OK or OR-gate allows
FetchingWB --> FetchingIMF: WB Skip (optional)
FetchingIMF --> FetchComplete: IMF OK
FetchingIMF --> FetchComplete: IMF skip (WB satisfies OR-gate)
FetchingIMF --> FetchFailed: Both WB+IMF failed
FetchComplete --> [*]
FetchFailed --> [*]
}
FetchStage --> TransformStage: Fetch complete
FetchStage --> PipelineAborted: Fetch failed (economic OR-gate blocked)
state TransformStage {
[*] --> NormalizingEP
NormalizingEP --> NormalizingEconomic: EP normalized
NormalizingEconomic --> Unifying: Economic normalized
Unifying --> TransformComplete: Schema unified
TransformComplete --> [*]
}
TransformStage --> AnalysisStage: Unified data ready
state AnalysisStage {
[*] --> Pass1Writing
Pass1Writing --> Pass1Complete: Pass 1 done (60% budget)
Pass1Complete --> Pass2Improving: Read-back + improve
Pass2Improving --> Pass2Complete: Pass 2 done (40% budget)
Pass2Complete --> IntelligenceFiles: Emit analysis files
IntelligenceFiles --> AnalysisComplete: stakeholder-map.md<br/>impact-matrix.md<br/>mcp-reliability-audit.md<br/>reference-analysis-quality.md
AnalysisComplete --> [*]
Pass1Writing --> AnalysisFailed: Time budget exhausted
AnalysisFailed --> [*]
}
AnalysisStage --> GenerateStage: Analysis complete
AnalysisStage --> PipelineAborted: Analysis failed
state GenerateStage {
[*] --> StrategyBuilder
StrategyBuilder --> StakeholderSlots: buildDefaultStakeholderPerspectives
StakeholderSlots --> ChartEmbedding: AI_MARKER sentinels
ChartEmbedding --> RenderHTML: Chart.js embedded
RenderHTML --> GenerateComplete: HTML rendered
GenerateComplete --> [*]
}
GenerateStage --> OutputStage: HTML ready
state OutputStage {
[*] --> WritingFiles
WritingFiles --> UpdatingIndexes: news/ updated
UpdatingIndexes --> OutputComplete: Indexes + sitemap
OutputComplete --> [*]
}
OutputStage --> ValidatorGate: Ready for gate
ValidatorGate --> [*]: Pass โ PR created
ValidatorGate --> PipelineAborted: Fail
PipelineAborted --> [*]: Abort workflow
note right of FetchStage
EP MCP 1.2.13 uniform
unavailable envelope:
{ status:"unavailable",
items:[] }
WB-or-IMF OR-gate via
articlePolicyHasEconomicContext
end note
note right of AnalysisStage
AI-First quality gates:
โฅ80 words/SWOT item
โฅ150 words/stakeholder
โฅ60% prose ratio
โฅ1 Chart.js
0 AI_ANALYSIS_REQUIRED
60-min โฅ45m; 120-min โฅ90m
end note
node scripts/utils/validate-analysis-completeness.js --article-html=... runs as a pre-translation and pre-PR gate. Implemented via scanHtmlForFallbackLeaks + FALLBACK_TEMPLATE_PATTERNS.
stateDiagram-v2
[*] --> Scanning: Invoked with --article-html
Scanning --> AnalysisPresent: Analysis files exist
Scanning --> MissingManifest: Missing analysis files
AnalysisPresent --> ManifestValid: Reference thresholds met
AnalysisPresent --> InsufficientReferences: Below threshold
ManifestValid --> ArticleClean: No fallback template patterns
ManifestValid --> FallbackLeak: AI_ANALYSIS_REQUIRED or AI_MARKER leak
ArticleClean --> EconomicContextOK: articlePolicyHasEconomicContext passes
ArticleClean --> MissingEconomicContext: No WB and no IMF
EconomicContextOK --> Pass: All gates OK
Pass --> [*]: PR creation allowed
MissingManifest --> Fail
InsufficientReferences --> Fail
FallbackLeak --> Fail
MissingEconomicContext --> Fail
Fail --> [*]: Abort PR
note right of ManifestValid
intelligence/mcp-reliability-audit.md
โฅ200 words (breaking โฅ385)
intelligence/reference-analysis-quality.md
โฅ140 words (breaking โฅ190)
Configured in
analysis/methodologies/
reference-quality-thresholds.json
end note
note right of ArticleClean
scanHtmlForFallbackLeaks
checks rendered HTML against
FALLBACK_TEMPLATE_PATTERNS
end note
| Category | Trigger | Remediation |
|---|---|---|
| MissingManifest | Analysis stage did not emit required intelligence files | Re-run analysis stage with longer time budget |
| InsufficientReferences | Word-count thresholds not met | Extend AI reasoning; verify Pass-2 improvement actually ran |
| FallbackLeak | AI_ANALYSIS_REQUIRED / AI_MARKER sentinels present in rendered HTML |
Agent author must fill slots directly; re-run generate stage |
| MissingEconomicContext | Both WB and IMF unavailable | Wait for one economic source to recover, or relax default gate to articlePolicyHasEconomicContext |
news-translate)The news-translate agentic workflow fans out one EN source article to 13 non-EN languages. A pre-gate scan validates analysis completeness before fan-out to prevent replicating broken EN content across languages.
stateDiagram-v2
[*] --> PreGate: news-translate triggered
state PreGate {
[*] --> ScanAllEnglishSources
ScanAllEnglishSources --> PreGatePass: All pass validator
ScanAllEnglishSources --> PreGateFail: Any EN source fails
PreGatePass --> [*]
PreGateFail --> [*]
}
PreGate --> Fanout: Pre-gate pass
PreGate --> [*]: Pre-gate fail (abort)
state Fanout {
[*] --> Queued13
Queued13 --> InProgress: Per-language job starts
InProgress --> Validated: axe-core + htmlhint pass
Validated --> Committed: Language HTML committed
Committed --> Reconciled: news-translate-reconciler cleanup
Reconciled --> [*]
InProgress --> LanguageFailed: Translation / validation failed
LanguageFailed --> Requeue: Within max-patch-size 10240 KB
Requeue --> InProgress: Retry
LanguageFailed --> SkipLanguage: Max retries
SkipLanguage --> [*]: Partial fan-out
}
Fanout --> PRCreated: All languages processed
PRCreated --> [*]: safe-outputs create-pull-request
note right of PreGate
validate-analysis-completeness.js
runs against every EN HTML
source before fan-out โ
prevents fan-out of broken
analysis across 13 languages
end note
note right of Fanout
Languages: sv, da, no, fi, de,
fr, es, nl, ar, he, ja, ko, zh
max-patch-size: 10240 KB
(vs default 1024 KB)
end note
news-<type>.md)Every unified .github/workflows/news-<type>.md workflow runs Stages A โ E in a single 60-minute session and produces exactly one PR. The 14 article-generating workflows (breaking, week-ahead, week-in-review, month-ahead, month-in-review, quarter-ahead, quarter-in-review, year-ahead, year-in-review, term-outlook, election-cycle, committee-reports, motions, propositions) all share this state machine. news-translate.md is the single exception โ see ยงTranslation State Machine below.
stateDiagram-v2
[*] --> Triggered: cron OR workflow_dispatch
Triggered --> MCPSetup: scripts/mcp-setup.sh
MCPSetup --> StageA: EP_MCP_GATEWAY_URL ready
state StageA {
[*] --> AcquiringEPData
AcquiringEPData --> AcquiringIMF: EP MCP probe
AcquiringIMF --> AcquiringWB: IMF probe (cache/imf/imf-probe-summary.json)
AcquiringWB --> StageAComplete: dataMode resolved (full | degraded-* | title-only | minimal)
StageAComplete --> [*]
}
StageA --> StageB: minute โค 12 (per-slug budget)
state StageB {
[*] --> AnalysisPass1
AnalysisPass1 --> AnalysisPass2: ~60% of stage budget
AnalysisPass2 --> ArtifactsEmitted: ~40% of stage budget (read-back & extend)
ArtifactsEmitted --> [*]
}
StageB --> StageC: artifacts written under analysis/daily/<date>/<slug>/
state StageC {
[*] --> RunningValidator
RunningValidator --> GREEN: all gates pass
RunningValidator --> GREEN_WITH_WARNINGS: WARN issues only
RunningValidator --> RED: any RED issue (tradecraft, mermaid, requiredSections)
RunningValidator --> ANALYSIS_ONLY: skipArticle flag set
}
StageC --> StageD: GREEN | GREEN_WITH_WARNINGS
StageC --> [*]: RED โ STAGE_C_GATE:RED stdout, abort
StageC --> [*]: ANALYSIS_ONLY โ no article, manifest updated
state StageD {
[*] --> ArticlePass1
ArticlePass1 --> ArticlePass2: prose draft complete
ArticlePass2 --> HTMLRendered: deterministic aggregator render (src/aggregator/markdown/)
HTMLRendered --> [*]
}
StageD --> StageE: rendered HTML + analysis artifacts ready
state StageE {
[*] --> SafeOutputCall
SafeOutputCall --> PRCreated: safeoutputs___create_pull_request (called exactly once)
PRCreated --> [*]
}
StageE --> Complete: minute โค 45 (target โค 42 standard slugs, โค 47 electoral)
Complete --> [*]: PR awaits review
note right of StageA
Per-slug stage budgets are
authoritative in
src/config/article-horizons.ts
Hard PR deadline minute โค 45
end note
note right of StageC
Verdict union:
GREEN | GREEN_WITH_WARNINGS |
ANALYSIS_ONLY | PENDING (manifest)
RED is stdout-only โ never
persisted to manifest history
end note
| Stage | Description | Output | Gate |
|---|---|---|---|
| A | Data acquisition (EP MCP + IMF + World Bank) | Cached envelopes, manifest with dataMode |
All sources probed, dataMode resolved |
| B | Analysis (2-pass) โ produces 39+ artifacts under analysis/daily/ |
Methodology-driven artifact set with WEP/Admiralty grading | Pass 2 read-back complete |
| C | Completeness gate (scripts/validate-analysis-completeness.js) |
STAGE_C_GATE:GREEN/RED stdout + manifest.history[].gateResult |
RED blocks PR; GREEN allows Stage D |
| D | Article generation (2-pass + deterministic aggregator render) | One HTML article in EN under news/<slug>/<date>/article.html |
Aggregator render succeeds |
| E | Single PR creation via safeoutputs___create_pull_request |
PR with analysis artifacts + article HTML, exactly one call | Hard deadline minute โค 45 |
dataMode State MachineEach Stage-A run resolves a manifest dataMode describing data availability for the run. The DataMode union ('full' | 'title-only' | 'degraded-imf' | 'degraded-voting' | 'minimal') is defined in src/workflows/types.ts with line-floor reduction factors in DATA_MODE_REDUCTION. Stage-C uses these factors to scale per-artifact line floors; structural checks (Mermaid, WEP, Admiralty, SATโฅ10) are never reduced.
stateDiagram-v2
[*] --> Probing: Stage A starts
Probing --> Full: EP MCP OK + IMF OK + World Bank OK<br/>(reduction = 1.00)
Probing --> DegradedIMF: EP OK + IMF FAIL/missing + WB OK<br/>(reduction = 0.85)
Probing --> DegradedVoting: EP partial (votes endpoint degraded)<br/>(reduction = 0.85)
Probing --> TitleOnly: EP returns titles only โ no body content<br/>(reduction = 0.75)
Probing --> Minimal: Multiple sources unavailable<br/>(reduction = 0.65)
Full --> DegradedIMF: IMF probe expires mid-run
Full --> DegradedVoting: Vote tool times out
DegradedIMF --> Minimal: WB also fails
DegradedVoting --> Minimal: IMF also fails
TitleOnly --> Minimal: Even title fetch degrades
DegradedIMF --> Full: WB satisfies economic OR-gate (no transition needed; reported)
DegradedVoting --> Full: get_latest_votes recovers via DOCEO XML
Full --> [*]: Stage B proceeds at full thresholds
DegradedIMF --> [*]: Stage B with -15% line floors
DegradedVoting --> [*]: Stage B with -15% line floors
TitleOnly --> [*]: Stage B with -25% line floors
Minimal --> [*]: Stage B with -35% line floors
note right of Probing
Stage A determines mode from:
- EP MCP get_server_health
- IMF probe summary
(cache/imf/imf-probe-summary.json)
- World Bank Open Data MCP
end note
note right of Minimal
Minimal mode still requires:
- All structural checks
- WEP banding present
- Admiralty grading present
- โฅ10 SATs in
methodology-reflection.md
end note
| From โ To | Trigger | Validator behaviour |
|---|---|---|
full โ degraded-imf |
cache/imf/imf-probe-summary.json reports failure or is missing |
-15% line floor; IMF citation requirement falls back to WB |
full โ degraded-voting |
Vote tool (get_voting_records / get_latest_votes) times out |
-15% line floor; voting-pattern artifacts use cached sample |
full โ title-only |
EP MCP returns metadata envelopes without body content | -25% line floor; full-content artifacts permitted shorter forms |
any โ minimal |
โฅ2 critical sources unavailable | -35% line floor; tradecraft (WEP/Admiralty/SAT) still mandatory |
degraded-* โ full |
Source recovers within run lifetime | Normally not transitioned โ manifest records initial probe state |
Each individual analysis artifact under analysis/daily/<YYYY-MM-DD>/<slug>/ progresses through a six-state lifecycle during Stage B. The catalog of 60 templates in analysis/templates/ seeds the Empty state; each template requires Pass-1 โ Pass-2 work to reach Validated before Stage C accepts it.
stateDiagram-v2
[*] --> Empty: Stage B begins<br/>(template skeleton in analysis/templates/)
Empty --> Draft: AI agent reads methodology<br/>(per-artifact-methodologies.md)
Draft --> Pass1Complete: Initial content written<br/>(โฅ60% of stage budget)
Pass1Complete --> Pass2Refined: Read-back and improve<br/>(โฅ40% of stage budget)
Pass2Refined --> Validated: Local checks pass<br/>(line floor, mermaid syntax, sections)
Pass2Refined --> Pass2Refined: Self-revision loop<br/>(extend shallow sections)
Validated --> Committed: Written to analysis/daily/<date>/<slug>/<artifact>.md
Committed --> [*]: Listed in manifest.files for Stage C validation
Empty --> AbandonedSkip: Optional artifact deemed N/A
AbandonedSkip --> [*]: Marked as skipped in manifest
Draft --> Pass1Failed: Time budget exhausted before Pass 1
Pass1Complete --> Pass2Failed: Time budget exhausted before Pass 2
Pass1Failed --> [*]: Stage B fails, run aborted
Pass2Failed --> [*]: Stage C will RED on shallow content
note right of Pass1Complete
Quality floor signals:
- Mandatory sections present
- WEP/Admiralty grading
- โฅ1 Mermaid diagram (per
artifact-catalog.md)
- No [AI_ANALYSIS_REQUIRED]
markers
end note
note right of Pass2Refined
Pass-2 read-back rule
(ai-driven-analysis-guide.md
Step 10):
Read every section word-by-word,
identify shallow content,
rewrite and extend.
Pass 2 is where quality is
achieved โ not Pass 1.
end note
| State | Description | Validator outcome |
|---|---|---|
| Empty | Template skeleton from analysis/templates/ |
Not yet present |
| Draft | Agent has begun writing, sections incomplete | RED on requiredSections |
| Pass-1 Complete | All sections present; quality may still be shallow | Possibly WARN on word-count |
| Pass-2 Refined | Read-back done; shallow sections extended | Likely passes line floor |
| Validated | Local Mermaid/section/floor checks pass | Local pass (no Stage-C run yet) |
| Committed | Written to disk and listed in manifest.files |
Eligible for Stage-C scan |
| Abandoned/Skip | Optional artifact not produced (rare โ most are required) | Not in manifest.files |
For artifacts that carry political intelligence judgements (scenario-forecast.md, coalition-dynamics.md, wildcards-blackswans.md, intelligence-assessment.md, political-threat-landscape.md, executive-brief.md, synthesis-summary.md, methodology-reflection.md), the content additionally progresses through an OSINT-tradecraft state machine governed by analysis/methodologies/osint-tradecraft-standards.md.
stateDiagram-v2
[*] --> SourceCollection: Stage B begins
SourceCollection --> SourceGrading: Sources gathered
SourceGrading --> HypothesisGeneration: Admiralty A1โF6 grade assigned per source<br/>(reliability letter ร credibility digit)
HypothesisGeneration --> ACHEvaluation: โฅ3 plausible hypotheses identified
state ACHEvaluation {
[*] --> BuildingMatrix
BuildingMatrix --> CountingInconsistencies: hypotheses ร evidence
CountingInconsistencies --> WinningHypothesis: fewest inconsistencies wins
CountingInconsistencies --> KeyAssumptionsCheck: parallel KAC
KeyAssumptionsCheck --> WinningHypothesis: assumptions documented
WinningHypothesis --> [*]
}
ACHEvaluation --> ConfidenceAssignment: hypothesis selected
ConfidenceAssignment --> WEPBanding: source grade ร ACH outcome โ confidence
state WEPBanding {
[*] --> SelectingBand
SelectingBand --> AlmostNoTermsForbidden: banned terms (likely-but-vague) replaced
AlmostNoTermsForbidden --> BandSelected: one of the seven Kent bands<br/>(remote โ almost-certain)
BandSelected --> [*]
}
WEPBanding --> StructuredAnalyticTechniques: probability-banded judgement
state StructuredAnalyticTechniques {
[*] --> CoreSATsApplied
CoreSATsApplied --> SupportingSATsApplied: โฅ10 core SATs applied
SupportingSATsApplied --> SATAttestation: methodology-reflection.md ยง3 table
SATAttestation --> [*]
}
StructuredAnalyticTechniques --> RedTeamReview: SAT attestation present
RedTeamReview --> PreMortem: devil's advocate written
PreMortem --> Publication: top-3 failure modes documented
Publication --> [*]: artifact passes Stage C tradecraft gates
SourceGrading --> InsufficientGrade: only D/E/F sources available
InsufficientGrade --> [*]: artifact downgraded to lower confidence
ACHEvaluation --> InsufficientHypotheses: <3 plausible hypotheses
InsufficientHypotheses --> Publication: justified in methodology-reflection.md
note right of SourceGrading
Admiralty Code (NATO STANAG 2511):
Reliability A (completely reliable) โ F (cannot be judged)
Credibility 1 (confirmed) โ 6 (cannot be judged)
See osint-tradecraft-standards.md ยง2
end note
note right of WEPBanding
Words of Estimative Probability
(Kent scale, ICD-203 ยง6):
Almost no chance (<5%)
Very unlikely (5โ20%)
Unlikely (20โ45%)
Roughly even chance (45โ55%)
Likely (55โ80%)
Very likely (80โ95%)
Almost certain (>95%)
Banned: "possible", "could",
"may", uncalibrated "likely"
end note
note right of StructuredAnalyticTechniques
Required core SATs:
ACH, KAC, Quality of Information,
Indicators & Signposts, What-If,
High-Impact/Low-Probability,
Red Team / Devil's Advocate,
Pre-Mortem, Scenario Analysis,
Lightweight ACH per-file
Plus PESTLE, Stakeholder Mapping,
Bayesian Update, Force-Field,
Cone of Plausibility (supporting)
end note
| Gate | Trigger | Severity |
|---|---|---|
| WEP missing | Probabilistic claim without WEP band | RED |
| Admiralty missing | Source cited without A1โF6 grade | RED |
| BLUF missing | Executive judgement absent from executive-brief.md |
RED |
| <10 SATs attested | methodology-reflection.md ยง3 lists fewer than 10 SATs |
RED |
| Banned WEP term | "possible", "could", "may" in analytic conclusion | RED |
| Reader-block | Sentence/paragraph length exceeds readability ceiling | WARN (RED in --strict) |
| Source-diversity warning | Single source dominates evidence base | WARN (RED in --strict) |
State diagrams use consistent colors to indicate state categories:
stateDiagram-v2
[*] --> Normal: Normal States
[*] --> Transient: Transient States
[*] --> Error: Error States
[*] --> Success: Success States
[*] --> Critical: Critical States
state Normal {
[*] --> Processing
[*] --> Waiting
[*] --> Active
}
state Transient {
[*] --> Connecting
[*] --> Retrying
[*] --> Loading
}
state Error {
[*] --> Failed
[*] --> Rejected
[*] --> Invalid
}
state Success {
[*] --> Complete
[*] --> Validated
[*] --> Published
}
state Critical {
[*] --> Fatal
[*] --> Aborted
[*] --> SecurityViolation
}
note right of Normal
Light blue/gray:
Regular processing states
end note
note right of Transient
Yellow/amber:
Temporary states during
transitions
end note
note right of Error
Red/pink:
Error states requiring
attention
end note
note right of Success
Green:
Successfully completed
states
end note
note right of Critical
Dark red:
Critical failures requiring
immediate intervention
end note
| Color | State Type | Example States |
|---|---|---|
| ๐ต Light Blue | Normal Processing | Active, Generating, Processing |
| ๐ก Yellow | Transient | Connecting, Retrying, Loading |
| ๐ข Green | Success | Complete, Validated, Published, Deployed |
| ๐ด Red | Error | Failed, Rejected, Invalid |
| โซ Dark Red | Critical | Fatal, Aborted, SecurityViolation |
| โช White | Initial/Final | [*] start and end states |
| Metric | Target | Measurement | Alert Threshold |
|---|---|---|---|
| Time in Idle | >95% | Percentage of time waiting | <90% (overloaded) |
| Initialization Success Rate | >99% | Successful init / total attempts | <95% |
| MCP Connection Success Rate | >95% | Connected / connection attempts | <90% |
| Article Generation Success Rate | >98% | Published / attempted | <95% |
| Validation Pass Rate | >99% | Passed / total validations | <98% |
| Deployment Success Rate | >99% | Successful deploys / attempts | <98% |
| Error Recovery Rate | >90% | Recovered / total errors | <80% |
| Fallback Activation Rate | <5% | Fallback / total attempts | >10% |
| State | Target Duration | Warning Threshold | Error Threshold |
|---|---|---|---|
| Initialization | <30s | >45s | >60s |
| MCP Connection | <10s | >20s | >30s |
| Data Fetching | <30s | >60s | >90s |
| Article Generation | <120s | >180s | >300s |
| Validation | <30s | >45s | >60s |
| Testing | <60s | >90s | >120s |
| Git Operations | <30s | >45s | >60s |
| GitHub Pages Deploy | <90s | >150s | >300s |
# Check current workflow state
gh workflow view news-generation --repo Hack23/euparliamentmonitor
# View recent workflow runs
gh run list --workflow=news-generation.yml --limit 20
# Monitor specific run state
gh run watch <run-id>
# Check GitHub Pages deployment status
gh api repos/Hack23/euparliamentmonitor/pages/builds/latest
# View state transition logs
gh run view <run-id> --log
ArticlePublished, content cannot be modified
(only reverted)Publishing without passing
ValidatingPer Hack23 ISMS State Management Policy:
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.4 | 2026-05-06 | CEO | Full review: added unified news-<type>.md Stage AโE run state machine, manifest dataMode state machine (full / degraded-imf / degraded-voting / title-only / minimal per src/workflows/types.ts), six-state analysis-artifact lifecycle (Empty โ Draft โ Pass-1 โ Pass-2 โ Validated โ Committed), and political-intelligence artifact state machine (Admiralty grading โ ACH โ WEP banding โ SAT attestation โ publication) per osint-tradecraft-standards.md |
| 1.3 | 2026-05-03 | CEO | v0.8.54 refresh: long-horizon expansion (term-outlook, election-cycle), 14 unified news workflows, gh-aw pin v0.71.3 |
| 1.2 | 2026-04-20 | CEO | Added Pipeline-Stage, Validator-Gate, and Translation state machines for v0.8.40 (5-stage pipeline, validator gate with fallback-leak scan, news-translate fan-out across 13 languages with 10240 KB max-patch-size); refreshed article-types note to 7 types; updated review cadence |
| 1.1 | 2026-02-24 | CEO | Updated review date and verified current state accuracy |
| 1.0 | 2025-02-17 | CEO | Initial state diagram documentation with comprehensive state machines |
Document Classification: Public
ISMS Compliance: ISO 27001:2022, NIST CSF 2.0, CIS Controls v8.1, GDPR, NIS2, EU CRA aligned
Technology Stack: Node.js 26, TypeScript 6.0.3, gh-aw v0.71.3, AWS S3 + CloudFront, GitHub Pages (fallback), EP MCP 1.3.3, WB MCP 1.0.1, IMF REST SDMX 3.0
Architecture Pattern: Static Site Generator with Agentic AI-First Authoring and Zero Runtime Dependencies
Review Status: Active, next review 2026-08-03
๐ State Diagrams โ Behavioral Model for EU Parliament Monitor
Part of ISMS-compliant Architecture Documentation Suite
๐๏ธ GitHub Repository โข ๐ก๏ธ ISMS Framework โข ๐ Hack23