commit b41f03f4a0fab7c0dc632f1e9a42713615fc9ba7 Author: anthonyrawlins Date: Thu Oct 2 09:59:59 2025 +1000 Initial commit: SWOOSH bootstrap with statechart spec, OpenAPI, ADRs, and ops harnesses diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9e08f2f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,19 @@ +name: ci +on: + push: + pull_request: +jobs: + validate: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Lint YAML + uses: ibiqlik/action-yamllint@v3 + - name: Validate OpenAPI (spectral) + uses: stoplightio/spectral-action@v0 + with: + file_glob: "api/openapi.yaml" + - name: Basic schema checks + run: | + test -s docs/statechart.yaml + test -s spec/swoosh.spec.yaml diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..f91d458 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,2 @@ +# Code of Conduct +We expect respectful, professional collaboration. Be kind. No harassment. Operate with integrity and auditability. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e033a0d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,14 @@ +# Contributing to SWOOSH + +## Development Principles +- Determinism over convenience; auditability over cleverness. +- Pure reducers + side-effect adaptors. +- Every state advance must be justified by guards and logged to WAL with UCXL DR refs. + +## Workflow +1. Propose changes via RFC in `/rfc`. +2. Link to issues/spec deltas in `/spec` and update statechart if needed. +3. Submit PR with tests (unit + model-based + chaos sim). + +## Commit Messages +Use: `CHORUS--###: short desc` and include UCXL backlink if applicable. diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..71e28e4 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,3 @@ +# Project Governance +- Maintainers decide via lightweight RFCs and ADRs. +- Breaking changes to Transition API require a major version and an ADR. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c1fe8d4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +MIT License + +Copyright (c) 2025 + +Permission is hereby granted, free of charge, to any person obtaining a copy... diff --git a/README.DEV.md b/README.DEV.md new file mode 100644 index 0000000..35aef55 --- /dev/null +++ b/README.DEV.md @@ -0,0 +1,12 @@ +# Developer Guide + +## Running Locally (skeleton) +- Validate specs: `npm i -g @stoplight/spectral` then `spectral lint api/openapi.yaml` +- Lint YAML: `yamllint .` +- Inspect statechart: open `docs/statechart.yaml` in your visualizer of choice. + +## Next Steps +- Implement reducer skeleton in Go/Rust. +- Add WAL adapter (Badger/RocksDB) and snapshotting. +- Implement HLC lib + HMMM signer verification. +- Build transition guard providers (BACKBEAT, policy engine, health probes). diff --git a/README.md b/README.md new file mode 100644 index 0000000..c5092b9 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# SWOOSH — Deterministic Orchestrator for WHOOSH + +**SWOOSH** is a drop-in replacement for WHOOSH’s orchestration core, implemented as a **deterministic hierarchical state machine** (statecharts). It governs project ingestion, council formation, environment provisioning, and execution loops (PLAN → WORK → REVIEW → REVERB) with **idempotent transitions, WAL + checkpoints, and HLC-ordered commits**. + +- **Audit-first**: Every accepted transition is written to a WAL and emits a BUBBLE Decision Record (DR) with UCXL backlink. +- **Chaos-ready**: Explicit guards, timeouts tied to BACKBEAT windows (or sine-pressure), compensation actions, and quorum certificates over HMMM. +- **Drop-in**: Exposes a small, stable Transition API; uses HMMM for signed proposals and CHORUS identity; respects KACHING license gates. + +> Status: *Bootstrap*. This repo seeds the project with SpecKit, statecharts, OpenAPI, ADRs, and ops harnesses. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..31f1892 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy +- All transition proposals must be signed (HMMM keypair). +- Secrets via AGE-encrypted configs. +- License gating enforced before any network ops. +- Report issues via private security channel. diff --git a/adr/0001-adopt-statecharts.md b/adr/0001-adopt-statecharts.md new file mode 100644 index 0000000..a382a1e --- /dev/null +++ b/adr/0001-adopt-statecharts.md @@ -0,0 +1,11 @@ +# ADR 0001: Adopt Deterministic Statecharts + +## Decision +Use hierarchical statecharts with pure reducers governing SWOOSH orchestration. + +## Rationale +Chaos resilience, auditability, time-gated cadence (BACKBEAT), idempotency, replay. + +## Consequences +- Requires WAL + snapshots. +- Transition API becomes the single mutation path. diff --git a/adr/0002-transition-api-and-wal.md b/adr/0002-transition-api-and-wal.md new file mode 100644 index 0000000..b8a5056 --- /dev/null +++ b/adr/0002-transition-api-and-wal.md @@ -0,0 +1,8 @@ +# ADR 0002: Transition API & WAL + +## Decision +All mutations flow through a signed Transition API. Accepted transitions append to WAL, then mutate state. + +## Details +- Store `(state_pre_hash, transition, inputs_hash, signer, idem_key, hlc, window_id)`. +- Emit BUBBLE DR with UCXL backlinks upon accept. diff --git a/api/openapi.yaml b/api/openapi.yaml new file mode 100644 index 0000000..6445272 --- /dev/null +++ b/api/openapi.yaml @@ -0,0 +1,50 @@ +openapi: 3.0.3 +info: + title: SWOOSH Transition API + version: 0.1.0 +paths: + /transition: + post: + summary: Propose a guarded state transition + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [current_state_hash, transition, inputs_hash, signer, idem_key, hlc, window_id] + properties: + current_state_hash: { type: string } + transition: { type: string } + inputs_hash: { type: string } + signer: { type: string, description: "HMMM identity" } + idem_key: { type: string } + hlc: { type: string } + window_id: { type: string } + evidence: + type: array + items: { type: string, description: "UCXL DR links or content hashes" } + responses: + "202": + description: Accepted + "400": + description: Rejected (guard failed / stale / duplicate) + /state: + get: + summary: Read current orchestrator state (projected) + parameters: + - in: query + name: projection + schema: + type: string + example: "Council,Ingestion" + responses: + "200": + description: Current state snapshot + content: + application/json: + schema: + type: object + properties: + hash: { type: string } + projection: { type: object } diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..ea5143f --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,14 @@ +# Architecture + +## Core Concepts +- **Reducer**: Pure function `newState = Reduce(oldState, Transition)`. +- **WAL**: Append-only log of proposed & accepted transitions. +- **Checkpoint**: Periodic snapshot; on restart: `rehydrate = checkpoint + WAL.replay()`. +- **HLC**: Hybrid Logical Clock stamped on every transition for total ordering. +- **Guards**: Pure predicates sourced from policy, BACKBEAT window, health probes, quorum certs. +- **Compensation**: Inverses for PROVISION, ELECT, INDEX, etc. + +## Statechart (overview) +Top-level regions: BOOT, PROJECT_LIFECYCLE (parallel: Ingestion, Council, Environment), EXECUTION (PLAN → WORK → REVIEW → REVERB), CONTROL (PAUSED/DEGRADED/RECOVERY), QUARANTINED, TERMINATED. + +See `docs/statechart.yaml` for machine-parseable spec. diff --git a/docs/STATECHART.md b/docs/STATECHART.md new file mode 100644 index 0000000..57cc622 --- /dev/null +++ b/docs/STATECHART.md @@ -0,0 +1,6 @@ +# Statechart Explainer + +- **Parallel region** ensures Ingestion, Council, and Environment advance independently with clear READY prerequisites for EXECUTION. +- **REVERB** is the only phase for final submissions, aligning with BACKBEAT's reverb concept. +- **QUARANTINED** is sticky; human or policy change required to exit. +- Every transition is guarded by time windows (BACKBEAT) and policy engines when applicable. diff --git a/docs/statechart.yaml b/docs/statechart.yaml new file mode 100644 index 0000000..a40567a --- /dev/null +++ b/docs/statechart.yaml @@ -0,0 +1,119 @@ +machine: SWOOSH +version: 0.1.0 +initial: UNINITIALIZED +states: + UNINITIALIZED: + on: + CONFIG_OK: LICENSE_CHECK + LICENSE_CHECK: + entry: + - guard: kaching.valid + on: + LICENSED: PROJECT_LIFECYCLE + LICENSE_FAILED: TERMINATED + + PROJECT_LIFECYCLE: + type: parallel + states: + Ingestion: + initial: DISCOVER + states: + DISCOVER: + on: + SOURCES_RESOLVED: FETCH + FETCH: + on: + BYTES_OK: VALIDATE + VALIDATE: + on: + SCHEMA_OK: INDEX + POLICY_VIOLATION: QUARANTINED + INDEX: + on: + CORPUS_BUILT: READY + READY: {} + Council: + initial: PLAN_ROLES + states: + PLAN_ROLES: + on: + PROFILES_LOADED: ELECT + ELECT: + on: + QUORUM_CERT: TOOLING_SYNC + TOOLING_SYNC: + on: + MCP_GREEN: READY + READY: {} + Environment: + initial: ALLOCATE + states: + ALLOCATE: + on: + CAPACITY_OK: PROVISION + PROVISION: + on: + INSTALLED: HEALTHCHECK + HEALTHCHECK: + on: + GREEN: READY + AMBER: DEGRADED + READY: {} + DEGRADED: + on: + GREEN: READY + on: + ALL_READY: EXECUTION + + EXECUTION: + initial: PLAN + states: + PLAN: + on: + PLAN_LOCKED: WORK + WORK: + on: + BEAT_REVIEW_GATE: REVIEW + REVIEW: + on: + APPROVALS_THRESHOLD: REVERB + CHANGES_REQUESTED: WORK + REVERB: + on: + NEXT_WINDOW: PLAN + + PAUSED: {} + RECOVERY: + on: + QUORUM_RESTORED: EXECUTION + QUARANTINED: + on: + HUMAN_RELEASE: PROJECT_LIFECYCLE + CONFIRMED_BLOCK: TERMINATED + TERMINATED: {} + +guards: + - name: kaching.valid + doc: License must validate before any network operations. + +events: + - CONFIG_OK + - LICENSED + - LICENSE_FAILED + - SOURCES_RESOLVED + - BYTES_OK + - SCHEMA_OK + - POLICY_VIOLATION + - CORPUS_BUILT + - PROFILES_LOADED + - QUORUM_CERT + - MCP_GREEN + - ALL_READY + - PLAN_LOCKED + - BEAT_REVIEW_GATE + - APPROVALS_THRESHOLD + - CHANGES_REQUESTED + - NEXT_WINDOW + - QUORUM_RESTORED + - HUMAN_RELEASE + - CONFIRMED_BLOCK diff --git a/ops/chaos-harness.md b/ops/chaos-harness.md new file mode 100644 index 0000000..68d76e1 --- /dev/null +++ b/ops/chaos-harness.md @@ -0,0 +1,14 @@ +# Chaos Harness + +## Scenarios +- Node churn (random kill/restart orchestrator replicas). +- Message duplication and reordering on HMMM. +- License server throttling (grace + degrade paths). +- Index swap mid-formation (pin via content hash). + +## Metrics to Watch +- state.advance_latency{region} +- retry_count{transition} +- quarantine_rate +- recovery_time_from_churn +- pending_transitions diff --git a/ops/observability.md b/ops/observability.md new file mode 100644 index 0000000..9f1982c --- /dev/null +++ b/ops/observability.md @@ -0,0 +1,5 @@ +# Observability + +- Export Prometheus metrics for transitions, guards, retries. +- Trace: one span per transition; include guard outcomes and linked evidence. +- Logs: append-only structured logs with state_pre_hash and state_post_hash. diff --git a/rfc/README.md b/rfc/README.md new file mode 100644 index 0000000..20ce61a --- /dev/null +++ b/rfc/README.md @@ -0,0 +1,2 @@ +# RFCs +Propose substantial changes here. Use filename `YYYY-NN-title.md`. Link to affected spec sections. diff --git a/spec/swoosh.spec.yaml b/spec/swoosh.spec.yaml new file mode 100644 index 0000000..cd5b053 --- /dev/null +++ b/spec/swoosh.spec.yaml @@ -0,0 +1,46 @@ +# SpecKit: Product Specification for SWOOSH +meta: + name: SWOOSH + tagline: Deterministic state-machine orchestrator for CHORUS + owners: + - handle: core + role: maintainers + status: bootstrap + roadmap_stage: alpha +goals: + - id: CHORUS-INT-001 + title: Deterministic orchestration under chaos + success_metrics: + - invariant_violation_rate == 0 over 10k randomized runs + - mean_recovery_time_from_churn < 2 beats + - id: CHORUS-INT-002 + title: Audit-first transitions + success_metrics: + - 100% transitions WAL-logged with UCXL DR refs +requirements: + functional: + - Expose Transition API to propose guarded state advances. + - Persist WAL and periodic snapshots; deterministic replay. + - Enforce BACKBEAT/pressure windows on time-gated transitions. + - Council quorum certificates via HMMM signatures. + non_functional: + - Idempotent, replay-safe; total-ordered by HLC. + - Security: age-encrypted configs; license gating via KACHING. +interfaces: + apis: + - name: Transition API + file: ../api/openapi.yaml +artifacts: + statechart: ../docs/statechart.yaml + architecture: ../docs/ARCHITECTURE.md + adr: + - ../adr/0001-adopt-statecharts.md + - ../adr/0002-transition-api-and-wal.md +testing: + plans: + - ../tests/TESTING.md +ops: + runbooks: + - ../ops/chaos-harness.md + - ../ops/observability.md +license: MIT diff --git a/tests/TESTING.md b/tests/TESTING.md new file mode 100644 index 0000000..2de6e28 --- /dev/null +++ b/tests/TESTING.md @@ -0,0 +1,14 @@ +# Testing Strategy + +## Property & Model-Based Tests +- Differential testing: in-memory reducer vs. process with WAL — compare state hashes. +- Fuzz: reorder, duplicate, drop transitions; random restarts; capacity jitter. + +## Invariants +- No time travel (HLC monotonic). +- Exactly-once epoch advance per region. +- READY implies prereqs READY + content/version pinned. +- Quorum cert matches member set hash. + +## Chaos Suite +- Scripts under `/ops/chaos-harness.md`.