From 7a50da55d9f9490ddc5be40839669ca0599bed9f Mon Sep 17 00:00:00 2001 From: Alan Szmyt Date: Wed, 16 Sep 2026 07:58:37 -0400 Subject: [PATCH 1/2] feat(core): bootstrap deterministic extension seam Add closed v1 extension models, deterministic catalog resolution, and a hermetic injected execution port with CI coverage. Roadmap-Step: FLO-Q02 Closes #23 --- .github/workflows/ci.yml | 80 + .gitignore | 1 + Cargo.lock | 135 ++ Cargo.toml | 24 + README.md | 67 +- ROADMAP.md | 70 +- contracts/README.md | 21 +- .../extension-manifest.v1.example.json | 2 +- docs/architecture/foundation/ARCHITECTURE.md | 21 +- docs/integrations/README.md | 28 + docs/integrations/extension-contract.md | 154 +- examples/hermetic_extension.rs | 173 ++ rust-toolchain.toml | 4 + src/catalog.rs | 895 +++++++++ src/contracts.rs | 1788 +++++++++++++++++ src/execution.rs | 494 +++++ src/hermetic.rs | 179 ++ src/lib.rs | 21 + tests/catalog.rs | 650 ++++++ tests/common/mod.rs | 105 + tests/contracts.rs | 238 +++ tests/execution.rs | 456 +++++ 22 files changed, 5547 insertions(+), 59 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 examples/hermetic_extension.rs create mode 100644 rust-toolchain.toml create mode 100644 src/catalog.rs create mode 100644 src/contracts.rs create mode 100644 src/execution.rs create mode 100644 src/hermetic.rs create mode 100644 src/lib.rs create mode 100644 tests/catalog.rs create mode 100644 tests/common/mod.rs create mode 100644 tests/contracts.rs create mode 100644 tests/execution.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9363cde --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,80 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + rust: + name: Rust ${{ matrix.toolchain }} + runs-on: ubuntu-latest + env: + RUSTUP_TOOLCHAIN: ${{ matrix.toolchain }} + strategy: + fail-fast: false + matrix: + toolchain: + - "1.85.0" + - stable + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.toolchain }} + components: clippy, rustfmt + + - name: Cache Cargo data + uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.toolchain }} + + - name: Check formatting + run: cargo fmt --all -- --check + + - name: Lint all targets + run: cargo clippy --all-targets --all-features --locked -- -D warnings + + - name: Test all targets + run: cargo test --all-targets --locked + + - name: Test documentation + run: cargo test --doc --locked + + - name: Run hermetic extension example + run: cargo run --example hermetic_extension --locked + + - name: Verify package contents + run: cargo package --locked + + repository-validators: + name: Repository validators + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: Validate contracts + run: python3 tools/validate_contracts.py + + - name: Validate architecture specifications + run: python3 .agents/specs/validate-specs.py + + - name: Validate repository skills + run: python3 .agents/skills/validate-skills.py + + - name: Validate repository agents + run: python3 .agents/agents/validate-agents.py diff --git a/.gitignore b/.gitignore index f5576b2..d6a442f 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ __MACOSX/ __pycache__/ *.pyc dist/ +/target/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..a56c262 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,135 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "flow" +version = "0.1.0" +dependencies = [ + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "proc-macro2" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..077af1e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "flow" +version = "0.1.0" +edition = "2024" +rust-version = "1.85" +description = "Deterministic orchestration contracts and extension seams for the Ego Hygiene suite" +license = "MIT" +repository = "https://github.com/egohygiene/flow" +publish = false + +[dependencies] +semver = "1.0.26" +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.140" +thiserror = "2.0.12" + +[dev-dependencies] + +[lints.rust] +unsafe_code = "forbid" + +[lints.clippy] +all = "warn" +pedantic = "warn" diff --git a/README.md b/README.md index 1850b26..43e2335 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,57 @@ Each holon remains usable as both a Rust library and a standalone CLI. Flow may compose them through stable public library interfaces or versioned CLI contracts, without introducing direct dependencies between sibling holons. -This repository is currently architecture-first. It intentionally contains no -copied holon source or working orchestrator yet. The approved suite boundaries, -dependency directions, and first orchestration slice are recorded in the -[roadmap](ROADMAP.md) and [integration contracts](docs/integrations/README.md). +The repository remains architecture-led, but it is no longer documentation +only. The current FLO-Q02 candidate adds a small Rust library that validates the +federated extension contracts, resolves one capability deterministically, and +executes one caller-injected in-process extension through a seam proven by a +hermetic reference port. It does not copy holon source or claim a product +orchestrator, CLI, external process adapter, durable run state, or resume +support. + +## Executable checkpoint + +The first executable checkpoint is deliberately library-only: + +- closed Rust models and semantic validation cover the six extension-v1 + documents; +- `ExtensionCatalog` inspection and resolution retain deterministic selection + and rejection evidence; +- `Orchestrator` invokes a matching `ExtensionPort` and returns an execution + only after Flow validates event and terminal-result correlation; and +- a no-effects, no-artifacts hermetic port and example prove the seam without a + provider binary, filesystem output, network access, or external service. + +Run the reference example with: + +```console +cargo run --example hermetic_extension --locked +``` + +`EventSink` is the observation boundary for this checkpoint. A future logging +or OpenTelemetry adapter can attach there, but observations do not influence +provider selection or execution identity. `emit` is fallible and its error is +visible to the provider; rejection makes `Orchestrator` return +`ExecutionError`. A sink cannot directly mutate provider evidence or grant +authority. No logging backend or telemetry exporter ships in this slice. + +`ValidatedExecution` means the provider evidence passed Flow's contract, +identity-correlation, ordering, diagnostic redaction-flag, and +terminal-consistency checks. It does not authenticate the caller-issued +configuration digest, authorization ID, or grants digest; the caller still owns +configuration canonicalization and authorization issuance. Diagnostics marked +`redacted: false` and other invalid provider evidence are retained only on +`ExecutionError` and never reach the caller's `EventSink` or a +`ValidatedExecution`. A `redacted: true` value remains a provider assertion; +this checkpoint does not content-scan diagnostics or sanitize unrestricted +contract strings. + +Only `trusted` candidates are resolution-eligible in this checkpoint; +`Orchestrator` executes only a caller-injected in-process port. `sandboxed` +candidates fail closed because no sandbox backend exists. Declared execution +limits are validated and correlated as metadata, not enforced. The injected +code has no Flow-owned timeout, cancellation, stdout/stderr bound, panic +isolation, filesystem or network containment, or other side-effect enforcement. ## Architecture @@ -37,11 +84,13 @@ skills, agents, templates, and validators used to maintain these documents. ## Status -Flow is in the **contract and adapter definition** phase. Current descriptions -of Aniflow, Optiflow, and Renderflow are grounded in their default branches as -inspected on 2026-08-13. The holons remain independently released repositories; -Flow will compose named releases through public libraries or versioned CLI -contracts and will not import sibling source. +Flow is in the **executable contract seam** phase. Issue #23 supplies the +candidate library implementation and CI definition for the remaining FLO-Q02 +evidence; FLO-Q02 stays active until that change is merged and exercised by +default-branch CI. Current descriptions of Aniflow, Optiflow, and Renderflow are +grounded in their default branches as inspected on 2026-08-13. The holons +remain independently released repositories; real provider adapters and the +restore-and-assess workflow remain follow-up work. ## License diff --git a/ROADMAP.md b/ROADMAP.md index dd9e257..5150542 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,12 +3,12 @@ schema: aether.architecture-document/v1 id: flow-roadmap title: Flow Roadmap kind: architecture-document -version: 0.3.0 +version: 0.4.0 status: draft owners: - egohygiene created: 2026-08-13 -updated: 2026-09-12 +updated: 2026-09-16 governed_by: - architecture-roadmap depends_on: @@ -30,22 +30,27 @@ repository: egohygiene/flow visibility: public publication: central route: /roadmap/flow/ -updated: 2026-09-12 +updated: 2026-09-16 --> -## 2026-09-12 execution snapshot +## 2026-09-16 execution snapshot > This evidence-reconciled snapshot is the issue-generation and visual-roadmap handoff. The longer-horizon strategy below remains canonical context; generated HTML, JSON, progress, issue plans, and commit lists are projections. -**Lifecycle:** contract and architecture prototype -**Current gate:** Freeze Flow #7's federated extension contract before final -provider SDK mappings, then add CI and a minimal executable orchestrator. +**Lifecycle:** executable contract prototype + +**Current gate:** Merge Flow #23's library-only execution seam and observe its +success and adversarial cases on default-branch CI before expanding provider +adapters. + **North-star outcome:** Federated orchestration across holons with stable provider seams, resumable work, and explicit evidence. ### Visual roadmap publication **Mode:** `central` **Route:** `/roadmap/flow/` -**Current publication evidence:** Architecture and contract source only; no executable release or Pages publication observed. +**Current publication evidence:** Architecture, contract source, and the Flow +#23 executable-core candidate; no executable release or Pages publication +observed. Publish the public-safe projection through egohygiene.io at /roadmap/flow/. This repository owns intent and acceptance evidence; it does not add a second site deployment. @@ -77,7 +82,7 @@ issues: [] id: FLO-Q02 status: active depends_on: [FLO-Q01] -issues: [7] +issues: [7, 23] --> #### FLO-Q02 — Freeze extension seams and create a tested executable core @@ -93,13 +98,21 @@ then a minimal orchestrator executes a fixture through one provider seam in CI. manifest and lock contracts. - [x] Invocation, event, result, and resolution schemas cover both execution modes and compatibility failures. -- [ ] A runnable command or library path exists. +- [x] A runnable library path and hermetic example exist in the Flow #23 + candidate revision. - [ ] Default-branch CI proves success and failure behavior. **Current evidence:** - Flow #7 defines the extension/trust schemas, synthetic fixtures, and - compatibility outcomes. No executable orchestrator or CI is claimed. + compatibility outcomes. +- Flow #23 supplies a Rust 1.85 library candidate for deterministic resolution, + injected in-process execution, Flow-owned event/result validation, and a + no-effects hermetic example. Its CI definition covers Rust 1.85, stable Rust, + and every repository validator. +- FLO-Q02 remains active until #23 is merged and a default-branch CI run proves + both success and adversarial behavior. This evidence does not claim a public + CLI, process execution, real provider adapters, durable state, or resume.