Skip to content

Commit 4fb0227

Browse files
committed
release: v0.2.0
1 parent 3f5d7ed commit 4fb0227

7 files changed

Lines changed: 25 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ All notable changes to `orchestratectl` are documented here. The format
44
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the
55
project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7-
## [Unreleased]
8-
9-
> **0.2.0 in progress — breaking.** Entries below accumulate toward the 0.2 simplification release
10-
> (per `docs/decisions/0001-thin-supervisor-vs-harden.md`); they include breaking CLI removals.
7+
## [0.2.0] - 2026-08-16
118

129
### Removed
1310

@@ -21,6 +18,10 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2118

2219
### Added
2320

21+
- **Thin supervisor A6/A1/A5 — explicit worker-exit facts, typed outcomes, and attention-required visibility.** Workers now launch through a thin `run-worker` shim that records the true child exit status/signal as a durable `worker.exited` fact. The supervisor consumes a typed outcome table instead of the old pid×pane×branch×activity-clock inference: `run merge` is the only success truth; non-zero/signal exits fail with work preserved; exit-0-without-merge becomes visible `attention_required`, not done or failed. `run wait` now settles on that non-terminal attention state, and `run show` / `run list` surface resume hints without mutating the run terminal. The idle-unmerged / git-reconcile auto-success heuristics are gone.
22+
- **Teardown safety hardening for non-merge outcomes.** Non-explicit-merge teardown now fails closed when it cannot prove cleanup is safe: dirty worktrees are preserved, git errors preserve instead of remove, detached-HEAD / stale-branch / no-branch worktrees with unique committed work are preserved, and source-relative branch checks are no longer the only guard. This closes the review-found data-loss edges introduced by relying on committed-branch reachability alone.
23+
- **Run-report provenance and rollup correctness.** New `ReportOrigin` provenance distinguishes Agent, Supervisor, and RunMerge-authored reports. Outcome classification, reducer merge adoption, and the landed/report-marker fallback now trust typed `RunMerge` origin and only honor legacy `via` markers when the origin field is genuinely absent, keeping old runs readable while preventing forged merge markers. Supervisor run rollup is now log-authoritative for leaf nodes rather than projection-scan based, so a crash-interrupted node projection cannot make the run terminalize while a log-visible node is still live.
24+
- **Bundled skill install guard for pi.dev.** The `stint-start` and `stint-handoff` bundled skill descriptions are trimmed below pi.dev's 1024-character description limit while keeping their Finnish/English trigger phrases and disambiguators, and a unit test now rejects any bundled skill description over that limit.
2425
- **`config` noun — inspect the config file path and effective resolved config with per-key source (`config-subcommand`).** Follow-up to `run-create-harness-flag` (which introduced `~/.orchestratectl/config.toml` `[harness]` but no inspection surface). Two read-only verbs per AGENTS-AI-FIRST-CLI §8: `orchestratectl config path` prints the config file location (with `exists`, whether or not the file is present — so a caller never has to guess where to write settings), and `orchestratectl config show` prints the effective resolved configuration as per-key rows — `harness.default` plus one `harness.<kind>` per creatable run kind — each carrying its `source` (`env | file | default`) so an agent can reason about **why** a value is what it is. The harness rows reuse the existing `harness::select` precedence resolver verbatim (per-kind override → section default → built-in), so `config show` never re-implements resolution; an `ORCHESTRATECTL_HARNESS` override honestly shadows every row to `source: "env"`. Each row carries a `secret` flag and the §8 redaction contract (`--show-secrets` to reveal, warning on stderr) is wired for future secret-valued keys, though none exist today. Strict validation: a bad harness value in the file fails the command loudly (`invalid_harness`) rather than being silently laundered. Both verbs support `--output json|jsonl|text`; the payloads carry `schema_version_config`. Never mutates the config file.
2526
- **`run merge --report-file` no longer blocks a clean merge on a malformed *advisory* report field (`merge-report-schema-lenience`).** The terminal §7.3 report was validated strictly *before* the git merge, so an advisory-field typo (the recurring `title`/`detail` instead of `spinoff_proposals[].proposed_title`/`proposed_kind`/`rationale`) rejected the whole report and blocked the merge of already-committed, reviewed code. `run merge` now validates leniently: the required, correctness-bearing fields (`success`, the `cancelled`/`reason` §7.7 cross-constraints, root-object shape) stay **strict** — a violation there still returns `schema_violation` (now carrying its structured `expected` hint) and performs no merge — but the advisory sections (`summary`, `discussion_items`, `spinoff_proposals`, `wrap_up_recommendations`) **degrade gracefully**: a malformed element is dropped from the persisted report and surfaced as a machine-readable `report_advisory_warnings[]` entry (plus a human-readable `warnings` line), never a merge blocker. Also visible under `--dry-run`, which doubles as a report-file preflight. Merge authorization/provenance is unchanged — `run merge` stamps the authoritative `ReportOrigin::RunMerge` after validation; `node report` and merge-recovery keep strict validation. (New `octl_core::sanitize_report_advisory`; 3-model `/llm-review` + `/assess-findings` applied.)
2627
- **Thin supervisor A5 follow-up — per-node branch-preserving `run cancel --node` for fan-out (`per-node-run`).** `orchestratectl run cancel <run-id> --node <node-id>` cancels exactly ONE live node of a multi-node fan-out — for unblocking a single stuck child without killing the batch (design §2.5). It appends only that node's terminal cancel `node.report` and **no** `run.status`: the run stays live while its siblings run, and the supervisor's rollup terminalizes the batch (`done | failed | cancelled`) only once every node has settled. The cancelled node classifies as `TerminalOutcome::Cancelled` → `Teardown::SourceRelative`, so its branch + worktree are preserved (invariant 5) — never force-deleted. The node set is resolved log-authoritatively (a node whose projection write was crash-interrupted is still cancellable; an absent id is a `node_not_found` user error), and the operation is idempotent: a duplicate per-node cancel converges/no-ops without a second report. The supervisor rollup now returns `cancelled` (not `failed`) when every terminal node was cancelled and none failed. The whole-run `run cancel <run-id>` form is unchanged. (design.md §2.5/§2.6.)

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ resolver = "2"
33
members = ["crates/octl-core", "crates/octl-cli"]
44

55
[workspace.package]
6-
version = "0.1.8"
6+
version = "0.2.0"
77
edition = "2021"
88
rust-version = "1.85"
99
license = "MIT"

crates/octl-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ path = "src/main.rs"
2121
workspace = true
2222

2323
[dependencies]
24-
octl-core = { path = "../octl-core", version = "=0.1.8" }
24+
octl-core = { path = "../octl-core", version = "=0.2.0" }
2525
clap = { workspace = true }
2626
serde = { workspace = true }
2727
serde_json = { workspace = true }

crates/octl-cli/tests/snapshots/envelope_snapshots__version_json.snap

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,72 +5,72 @@ expression: value
55
{
66
"schema_version": 1,
77
"data": {
8-
"version": "0.1.8",
8+
"version": "0.2.0",
99
"commit": "[COMMIT]",
1010
"skills": [
1111
{
1212
"name": "orchestratectl-overview",
13-
"cli_version": "0.1.8",
13+
"cli_version": "0.2.0",
1414
"schema_version": 1
1515
},
1616
{
1717
"name": "octl-run-overview",
18-
"cli_version": "0.1.8",
18+
"cli_version": "0.2.0",
1919
"schema_version": 1
2020
},
2121
{
2222
"name": "octl-spawn-spinoff",
23-
"cli_version": "0.1.8",
23+
"cli_version": "0.2.0",
2424
"schema_version": 1
2525
},
2626
{
2727
"name": "worktree-spinoff",
28-
"cli_version": "0.1.8",
28+
"cli_version": "0.2.0",
2929
"schema_version": 1
3030
},
3131
{
3232
"name": "worktree-merge",
33-
"cli_version": "0.1.8",
33+
"cli_version": "0.2.0",
3434
"schema_version": 1
3535
},
3636
{
3737
"name": "worktree-research",
38-
"cli_version": "0.1.8",
38+
"cli_version": "0.2.0",
3939
"schema_version": 1
4040
},
4141
{
4242
"name": "worktree-technical-decision",
43-
"cli_version": "0.1.8",
43+
"cli_version": "0.2.0",
4444
"schema_version": 1
4545
},
4646
{
4747
"name": "worktree-bug-analysis",
48-
"cli_version": "0.1.8",
48+
"cli_version": "0.2.0",
4949
"schema_version": 1
5050
},
5151
{
5252
"name": "worktree",
53-
"cli_version": "0.1.8",
53+
"cli_version": "0.2.0",
5454
"schema_version": 1
5555
},
5656
{
5757
"name": "worktree-status",
58-
"cli_version": "0.1.8",
58+
"cli_version": "0.2.0",
5959
"schema_version": 1
6060
},
6161
{
6262
"name": "stint-start",
63-
"cli_version": "0.1.8",
63+
"cli_version": "0.2.0",
6464
"schema_version": 1
6565
},
6666
{
6767
"name": "stint-handoff",
68-
"cli_version": "0.1.8",
68+
"cli_version": "0.2.0",
6969
"schema_version": 1
7070
},
7171
{
7272
"name": "fan-out",
73-
"cli_version": "0.1.8",
73+
"cli_version": "0.2.0",
7474
"schema_version": 1
7575
}
7676
],

crates/octl-cli/tests/snapshots/envelope_snapshots__version_jsonl.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
source: crates/octl-cli/tests/envelope_snapshots.rs
33
expression: value
44
---
5-
{"schema_version":1,"data":{"version":"0.1.8","commit":"[COMMIT]","skills":[{"name":"orchestratectl-overview","cli_version":"0.1.8","schema_version":1},{"name":"octl-run-overview","cli_version":"0.1.8","schema_version":1},{"name":"octl-spawn-spinoff","cli_version":"0.1.8","schema_version":1},{"name":"worktree-spinoff","cli_version":"0.1.8","schema_version":1},{"name":"worktree-merge","cli_version":"0.1.8","schema_version":1},{"name":"worktree-research","cli_version":"0.1.8","schema_version":1},{"name":"worktree-technical-decision","cli_version":"0.1.8","schema_version":1},{"name":"worktree-bug-analysis","cli_version":"0.1.8","schema_version":1},{"name":"worktree","cli_version":"0.1.8","schema_version":1},{"name":"worktree-status","cli_version":"0.1.8","schema_version":1},{"name":"stint-start","cli_version":"0.1.8","schema_version":1},{"name":"stint-handoff","cli_version":"0.1.8","schema_version":1},{"name":"fan-out","cli_version":"0.1.8","schema_version":1}],"schema_version":1,"supported_schemas":[1],"state_schema_version":1,"supported_state_schemas":[1]},"warnings":[]}
5+
{"schema_version":1,"data":{"version":"0.2.0","commit":"[COMMIT]","skills":[{"name":"orchestratectl-overview","cli_version":"0.2.0","schema_version":1},{"name":"octl-run-overview","cli_version":"0.2.0","schema_version":1},{"name":"octl-spawn-spinoff","cli_version":"0.2.0","schema_version":1},{"name":"worktree-spinoff","cli_version":"0.2.0","schema_version":1},{"name":"worktree-merge","cli_version":"0.2.0","schema_version":1},{"name":"worktree-research","cli_version":"0.2.0","schema_version":1},{"name":"worktree-technical-decision","cli_version":"0.2.0","schema_version":1},{"name":"worktree-bug-analysis","cli_version":"0.2.0","schema_version":1},{"name":"worktree","cli_version":"0.2.0","schema_version":1},{"name":"worktree-status","cli_version":"0.2.0","schema_version":1},{"name":"stint-start","cli_version":"0.2.0","schema_version":1},{"name":"stint-handoff","cli_version":"0.2.0","schema_version":1},{"name":"fan-out","cli_version":"0.2.0","schema_version":1}],"schema_version":1,"supported_schemas":[1],"state_schema_version":1,"supported_state_schemas":[1]},"warnings":[]}

crates/octl-cli/tests/snapshots/envelope_snapshots__version_text.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
source: crates/octl-cli/tests/envelope_snapshots.rs
33
expression: value
44
---
5-
orchestratectl 0.1.8
5+
orchestratectl 0.2.0
66
commit: [COMMIT]
77
envelope schema: 1
88
supported envelopes: 1

0 commit comments

Comments
 (0)