Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## [0.14.6] — 2026-09-25

The fixes for the trial findings shipped in aep 0.59.3 and ess 0.32.0; the skills now describe that
behaviour instead of the workarounds. Each change was checked against the released binaries.

**`ess`**

- `ess:retrofitting`: `ess infra import openapi` reads OpenAPI 3.0 as well as 3.1. A nullable field
imports as a coverage gap, carried into the draft as an `UNMAPPED:` marker; an object schema must
be closed with `additionalProperties: false`, and that refusal is reported, not worked around.
- Syntax reference: two fields are compared through one struct (`window.ends_at >
window.starts_at`); a right-hand side without a dot is a literal, so the flat form is refused. The
stored-value case links ESS's design note for guards over stored fields.
- `ess:specifying`: the note that the CLI help calls the `system.yaml` layout "legacy" is gone; the
help no longer says so.

**`aep`**

- `aep:planning`: the store's refusal of an empty findings fence now says to write `[]`; the skill
points at it instead of quoting the old message.

## [0.14.5] — 2026-09-25

From the round-4 trials on 0.14.4 (an ESS retrofit of a stock-reservation service and worktree
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ resolver = "2"
members = ["crates/agentplugins-check", "crates/b10x"]

[workspace.package]
version = "0.14.5"
version = "0.14.6"
edition = "2021"
rust-version = "1.85"
license = "Apache-2.0"
Expand Down
2 changes: 1 addition & 1 deletion plugins/aep/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "aep",
"displayName": "AEP",
"description": "Plan governed work in the AEP artifact store and deliver it in reviewed waves: decomposition, plan critique, reverse engineering, story scoping, implementation and adversarial review.",
"version": "0.14.5",
"version": "0.14.6",
"author": {
"name": "Beyond10x"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/aep/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aep",
"version": "0.14.5",
"version": "0.14.6",
"description": "Plan governed work in the AEP artifact store and deliver it in reviewed waves.",
"author": {
"name": "Beyond10x"
Expand Down
7 changes: 3 additions & 4 deletions plugins/aep/skills/planning/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -475,10 +475,9 @@ created review-result:acceptance-round-1 (active) at .engineering/planning/revie
you have recorded your reading of the review rather than the review. That includes the fenced
` ```findings ` block the rubric has each critic close with: it is the half a program reads, and a
record whose findings were flattened into prose is one `aep plan artifact findings` cannot compare
against the next round. On `approve` the rubric's block is `[]`, which the store accepts. The one
edit allowed: a critic that closed with an empty fence (no `[]` inside) is recorded with `[]` in
it, because the store refuses the empty fence ("a review with nothing to report writes no block
at all"). Say in the report that you made that edit.
against the next round. On `approve` the rubric's block is `[]`. The one edit allowed: a critic
that closed with an empty fence is recorded with `[]` in it, as the store's refusal says; say in
the report that you made that edit.
* Repeat `--relate` once per artifact the critic judged. Read the edge name from
`aep plan artifact relations` before you rely on it, the way you would any other vocabulary.
* Write them one at a time. Four critics return at once; the store takes one writer.
Expand Down
2 changes: 1 addition & 1 deletion plugins/b10x/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "b10x",
"displayName": "Beyond10x",
"description": "Set up, upgrade and check the Beyond10x plugins and binaries, route work to them, and create portable plugins.",
"version": "0.14.5",
"version": "0.14.6",
"author": {
"name": "Beyond10x"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/b10x/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "b10x",
"version": "0.14.5",
"version": "0.14.6",
"description": "Set up, upgrade and check the Beyond10x plugins and binaries, route work to them, and create portable plugins.",
"author": {
"name": "Beyond10x"
Expand Down
2 changes: 1 addition & 1 deletion plugins/connectors/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "connectors",
"version": "0.14.5",
"version": "0.14.6",
"description": "Set up, inspect, and invoke governed integrations through the connectors CLI.",
"author": { "name": "Beyond10x" },
"license": "Apache-2.0",
Expand Down
2 changes: 1 addition & 1 deletion plugins/connectors/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "connectors",
"version": "0.14.5",
"version": "0.14.6",
"description": "Set up, inspect, and invoke governed integrations through the connectors CLI.",
"author": { "name": "Beyond10x" },
"license": "Apache-2.0",
Expand Down
2 changes: 1 addition & 1 deletion plugins/ess/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ess",
"displayName": "ESS",
"description": "Write, retrofit, validate and project Executable System Specifications, and hold implementations to them with conformance suites.",
"version": "0.14.5",
"version": "0.14.6",
"author": {
"name": "Beyond10x"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/ess/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ess",
"version": "0.14.5",
"version": "0.14.6",
"description": "Write, retrofit, validate and project Executable System Specifications, and hold implementations to them with conformance suites.",
"author": {
"name": "Beyond10x"
Expand Down
8 changes: 5 additions & 3 deletions plugins/ess/skills/retrofitting/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ cites it. What you cannot read is an `UNMAPPED:` marker, never a plausible value
Use every source that exists. Where two disagree, the draft records both and marks the field
`UNMAPPED:`; the disagreement is a finding, not something to resolve by choosing.

`ess infra import openapi` reads OpenAPI 3.1 only. A 3.0 document exits 1 with the refusal
`only OpenAPI 3.1 is supported, found 3.0.x`; `aep plan reverse openapi` accepts it. Do not
rewrite the contract's version line to get past the refusal.
`ess infra import openapi` reads OpenAPI 3.0 and 3.1. A nullable field (`nullable: true`, or a 3.1
`type: [T, "null"]`) imports as a coverage gap at its pointer, because the interface has no null:
carry each gap into the draft as an `UNMAPPED:` marker. An object schema must be closed with
`additionalProperties: false`, or the import refuses it; that refusal is a finding about the
contract, so report it rather than editing the contract to pass.

`aep` is optional. Without it, write the domain by hand from the schemas, in the shape the `ess:specifying`
skill shows.
Expand Down
2 changes: 1 addition & 1 deletion plugins/ess/skills/specifying/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ scenarios: []

`specification` lists every authored file, relative to this file, and each must exist. `scenarios`
lists authored scenario files, `[]` when there are none. `--path <directory>` then reads exactly
that list. The CLI help calls the list-less `system.yaml` layout "legacy"; it still validates.
that list. A directory with only `system.yaml` still validates, read whole.

**A draft is a proposal, never a silent completion.** Every relation you could not read from code,
an OpenAPI document or an existing artifact is written with an `UNMAPPED:` marker beside the place
Expand Down
13 changes: 7 additions & 6 deletions plugins/ess/skills/specifying/references/syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -325,11 +325,12 @@ Two cases trials hit:

| rule | how to write it |
|---|---|
| a value stored on the entity decides the outcome ("express parcels over 20 kg are refused at dispatch", with the weight given at create) | not expressible: a `when` sees only the dispatch input. Mark it `UNMAPPED:` at the outcome, citing the source line |
| a value stored on the entity decides the outcome ("express parcels over 20 kg are refused at dispatch", with the weight given at create) | not expressible: a `when` sees only the dispatch input. Mark it `UNMAPPED:` at the outcome, citing the source line. A guard over stored fields is proposed in ESS's [design note](https://github.com/beyond10x/ess/blob/main/docs/design/cross-record-and-stored-field-guards.md) |
| two records must not overlap ("a room cannot be booked twice for one hour") | make the contested unit an entity with its own lifecycle (a `Slot` that is `Free` or `Booked`); a second booking is then `wrong_state` on that slot. Overlap between arbitrary time ranges is not expressible; mark it `UNMAPPED:` |

**Order a time range by its length, not by comparing two `Timestamp`s.** `ends_at > starts_at`
validates, but `ess verify conform synthesize` refuses it (`no declared scale contains both
values`). `Duration` does not work either: it is text, and `validate` refuses `length > 0`. Take
`starts_at: Timestamp` and an `Integer` in a named unit (`duration_minutes`) and guard on
`duration_minutes > 0`.
**Compare two fields through one struct.** A right-hand side without a dot is a literal, so
`ends_at > starts_at` compares `ends_at` with the text `"starts_at"` and `validate` refuses it.
Declare the two fields in one struct (`Window` with `starts_at` and `ends_at`, both `Timestamp`),
take it as input, and guard on `window.ends_at > window.starts_at`; `synthesize` orders the two
instants. `Duration` does not compare with a number (it is text), so a length is an `Integer` in a
named unit (`duration_minutes > 0`).
2 changes: 1 addition & 1 deletion plugins/worktree/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "worktree",
"displayName": "Worktree",
"description": "Create, lease, finish, audit and safely clean isolated Git worktrees through the worktree CLI.",
"version": "0.14.5",
"version": "0.14.6",
"author": {
"name": "Beyond10x"
},
Expand Down
2 changes: 1 addition & 1 deletion plugins/worktree/.codex-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "worktree",
"version": "0.14.5",
"version": "0.14.6",
"description": "Create, lease, finish, audit and safely clean isolated Git worktrees through the worktree CLI.",
"author": {
"name": "Beyond10x"
Expand Down
Loading