@intentic/engine 1.310.0 → 1.311.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +30 -23
  2. package/package.json +5 -5
package/README.md CHANGED
@@ -1,28 +1,35 @@
1
- # @intentic/engine
2
-
3
- The stateless **reconcile engine**. It walks a `DesiredStateGraph` in dependency order and converges it through the **Provider SPI**: never constructing providers itself, only consuming a `ResourceType → Provider` map. Depends on [`@intentic/graph`](../graph) + [`@intentic/resources`](../resources); the real providers live in [`@intentic/providers`](../providers).
4
-
5
- ## Responsibilities
6
-
7
- - `apply`, converge once: per node, `read` → `diff` → `create`/`update`/`noop`, gating on readiness.
8
- - `plan`, dry run: classify every node without mutating infra.
9
- - `reconcile`: loop apply→read until a plan reads all-noop ("state reads true"), returning a `ConvergeResult`.
10
- - Define the **Provider SPI** the rest of the system implements: `Provider`, `Providers`, `Observed`, `DiffResult`, `ProviderContext`.
11
- - Emit structured `EngineEvent`s (for the CLI's ndjson/json output) and handle readiness, orphans, and pruning.
1
+ # engine
2
+
3
+ The stateless reconcile engine that plans, applies and prunes a desired-state graph by asking each resource's provider what exists in live infrastructure.
4
+
5
+ ```mermaid
6
+ flowchart LR
7
+ cli["cli<br/>plan · apply · destroy"] --> engine(["engine"])
8
+ engine -- "each node, in order" --> read["provider.read"]
9
+ read -- "absent" --> create["apply: create"]
10
+ read -- "inputs changed" --> update["apply: update"]
11
+ read -- "matches" --> noop["noop"]
12
+ create --> ready["readyWhen probe<br/>outputs → store"]
13
+ update --> ready
14
+ ```
15
+
16
+ - There is no state file. A provider finds its resource by the `intentic.id` stamp; a stamped `intentic.hash` that differs from the node's inputs forces an update before the provider's own `diff` is consulted.
17
+ - `apply` walks the graph in dependency order, one node at a time, and stores each node's outputs so later `$ref` inputs resolve. `plan` does the same reads without mutating. `reconcile` alternates the two until a plan reads all noop, bounded by `maxIterations`.
18
+ - `prune` deletes what the previous artifact declared and the current one lacks, in reverse order with the old inputs. `collectOrphans` and `pruneOrphans` catch stamped resources no graph mentions. `applyMoves` re-stamps renamed resources first so they are not recreated.
19
+ - The engine constructs no providers. Callers pass a `Providers` map from [providers](../providers), or `createFakeProviders` for an in-memory world in tests.
20
+ - Progress leaves as structured `EngineEvent`s; the CLI renders them and the daemon tails them.
12
21
 
13
22
  ## Key files
14
23
 
15
- - [src/reconcile/apply.ts](src/reconcile/apply.ts) / [src/reconcile/plan.ts](src/reconcile/plan.ts) / [src/reconcile/reconcile-loop.ts](src/reconcile/reconcile-loop.ts): the converge/dry-run/loop logic.
16
- - [src/provider.ts](src/provider.ts) / [src/types.ts](src/types.ts): the SPI and engine types (`Provider`, `DiffResult`, `EngineConfig`, `Step`, `Orphan`).
17
- - [src/readiness.ts](src/readiness.ts): `httpProbe` / `waitReady` (readiness gates), and `pollUntil`, the one waiting loop every "is it up yet" in the engine and the providers is written on.
18
- - [src/resolve-inputs.ts](src/resolve-inputs.ts): resolve refs/secrets into concrete provider inputs.
19
- - [src/reconcile/orphans.ts](src/reconcile/orphans.ts) / [src/reconcile/prune.ts](src/reconcile/prune.ts) (drift cleanup; [src/providers](src/providers)) `createFakeProviders` (in-memory SPI for tests).
20
-
21
- ## How it fits
22
-
23
- The execution core. `state-resolver` produces the graph; `providers` supplies the concrete SPI map; the `cli` wires them together and runs `reconcile`. The engine stays infra-agnostic: all I/O is behind the SPI.
24
+ - [src/provider.ts](src/provider.ts) — the `Provider` contract: `read`, `diff`, `apply`, and optional `list`, `delete`, `restamp`.
25
+ - [src/reconcile/apply.ts](src/reconcile/apply.ts) — one converge pass over the graph.
26
+ - [src/reconcile/reconcile-loop.ts](src/reconcile/reconcile-loop.ts) — apply then plan until nothing is left to do.
27
+ - [src/reconcile/reconcile.ts](src/reconcile/reconcile.ts) — provider lookup and the stamped-hash drift check.
28
+ - [src/reconcile/prune.ts](src/reconcile/prune.ts) — removal of dropped nodes and orphans.
29
+ - [src/providers/fake.ts](src/providers/fake.ts) — in-memory providers that prove a second apply is a noop.
24
30
 
25
- ## Conventions & gotchas
31
+ ## Commands
26
32
 
27
- - The engine never imports `providers`: it takes a `Providers` map as input, so it can run against fakes.
28
- - `diff` must be **pure** (read does the I/O); apply is the only mutating step. `EngineEvent` is part of the public contract for embedders. See [ARCHITECTURE.md](../../ARCHITECTURE.md).
33
+ ```sh
34
+ pnpm --filter @intentic/engine test
35
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentic/engine",
3
- "version": "1.310.0",
3
+ "version": "1.311.0",
4
4
  "description": "Stateless reconcile engine: plan/apply, the Provider SPI, and the reconcile loop.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -30,13 +30,13 @@
30
30
  }
31
31
  },
32
32
  "dependencies": {
33
- "@intentic/base": "1.310.0",
34
- "@intentic/graph": "1.310.0",
35
- "@intentic/resources": "1.310.0",
33
+ "@intentic/base": "1.311.0",
34
+ "@intentic/graph": "1.311.0",
35
+ "@intentic/resources": "1.311.0",
36
36
  "tslib": "2.8.1"
37
37
  },
38
38
  "devDependencies": {
39
- "@intentic/sdk": "1.310.0",
39
+ "@intentic/sdk": "1.311.0",
40
40
  "@intentic/testing": "0.0.0",
41
41
  "@intentic/tsconfig": "0.0.0",
42
42
  "@types/bun": "1.4.0",