Skip to main content
What changed across the Aethis platform. Each entry is derived from the source CHANGELOG.md of the package it belongs to and is labelled with that package. Subscribe via the RSS feed for this page.
aethis-mcp
2026-07-19
Adds the Authoring Coach surface to MCP (aethis-mcp#57, workspace epic #514) — skill-building feedback for rule authors, advisory only, never a gate.Engine gate: the POST /api/v1/public/projects/{id}/review endpoint and the ambient review_hint fields are produced by aethis-core (epic phases P1/P4). This release must not be published to npm until that endpoint is live on api.aethis.ai; a released client calling a not-yet-deployed route would 404.
  • aethis_review_project (new tool). Reviews an authoring project against the deterministic authoring-coach rubric and renders the report: a score, per-check evidence across grounding / process / lifecycle, strengths, and the single highest-leverage next skill. Advisory only — it never blocks publishing. The deterministic layer needs no LLM key; coach=true (with an Anthropic key, via the usual anthropic_key_env / anthropic_key_keychain / anthropic_key forms) adds an opt-in LLM-synthesised coaching narrative on top. All server free-text (evidence / strengths / next-skill message / coaching) is fenced with fenceUntrusted before it reaches the model.
  • Ambient review_hint render. aethis_generate_and_test, aethis_refine, and aethis_publish now render a one-line coach hint when the server includes one on the response. The hint is computed entirely server-side (aethis-core P4); the client only renders it (fenced), never computes it.
  • X-Aethis-Client: mcp/<version> on every request. The client now sends a per-surface identifier header so the engine can attribute telemetry (e.g. review_hint-shown counts) to MCP vs CLI vs SDK.
  • 31 tools, up from 30. tests/tool-endpoint-map.ts and the drift suite are updated in the same change. Note: the drift suite’s live-alignment checks stay red against staging until the /review endpoint deploys there (expected epic ordering); the offline structural checks pass.
  • Tests. New mocked unit coverage in tests/client.test.ts (reviewProject request shape, the client-id header) and tests/server.test.ts (aethis_review_project render + fencing, coach key resolution, ambient hint render on generate/publish).
aethis-cli
2026-07-19
  • feat: aethis review [<project>] — the Authoring Coach report for a project. Runs the server-side rubric and prints an authoring score, 2–3 evidence-cited strengths, and the single highest-leverage next improvement (with its docs link and the lever that fixes it). Defaults to the current project in .aethis/state.json; pass a proj_… id to review any of your projects from anywhere. --verbose shows the full per-check table; --json (and any piped/--output json invocation) emits the raw ReviewReport. The deterministic report needs only your API key; --coach opts into LLM mentoring prose billed to your own Anthropic key (ANTHROPIC_API_KEY). Advisory only — the exit code is always 0 regardless of score. New AethisClient.review().
  • feat: every request now sends X-Aethis-Client: cli/<version> so the server can attribute per-surface telemetry (CLI vs MCP). The header carries no credentials and no PII, and is set once at client construction for all commands.
  • Requires aethis-core with the /api/v1/public/projects/{id}/review endpoint live (epic aethis-workspace#514, P1). The public release of this version is held until that endpoint is live on api.aethis.ai.
aethis-sdk-python
2026-07-17
  • feat(models): robot_hints + engine_version on the rulebook schema; engine_version on the ruleset schema. New RulebookSchemaResponse model (rulebook_id, sections, fields, robot_hints, engine_version) for GET /api/v1/public/rulebooks/{id}/schemarobot_hints is the rulebook’s natural-language conversational-agent guidance keyed by beat (general_context, preamble, session_start, postamble, session_end, stuck), None for a rulebook authored before the field existed. SchemaResponse (ruleset schema) gains engine_version: str | None = None for parity, also back-compat (defaults None when the engine doesn’t send it — true of the ruleset schema route today).
  • feat(models): graph/GraphResponse for the new /graph endpoint. New GraphResponse (ruleset_id/rulebook_id, slug, name, graph, mermaid) and RulesetGraph (nodes, edges, sections, stats) model the ruleset/rulebook dependency graph (field → criterion → group → outcome) plus its rendered Mermaid diagram. Node/edge shape varies by node type, so nodes/edges stay loosely-typed dicts rather than a rigid per-type schema — deliberately permissive so a legacy or empty graph (nodes: []) still parses.
  • feat(client): get_graph(ruleset_id) (sync + async) — wraps GET /api/v1/public/rulesets/{id}/graph, returning GraphResponse. Public rulesets can be inspected without an API key, same as get_schema().
  • feat(decide): include_graph_overlay parameter on decide() / decide_rulebook() (sync + async), and a matching graph_overlay: dict[str, Any] | None = None field on DecideResponse. Set include_graph_overlay=True to get this decision’s per-criterion status stamped onto the ruleset’s dependency graph, in the same shape get_graph() returns.
  • All additions are additive and backwards-compatible: every new field defaults to None/False/an empty collection, so a legacy response (no robot_hints, no engine_version, no graph_overlay) still deserialises unchanged.
aethis-mcp
2026-07-17
Propagates the aethis-core 0.37–0.40 authoring batch to the MCP surface (aethis-mcp#49, workspace epic #327). Engine gate: live on api.aethis.ai 0.45.2, confirmed via the drift suite’s live-alignment checks before this release.
  • aethis_graph (new tool). Fetches the ruleset-map graph — either for a single published ruleset (ruleset_id, may be public/anonymous for a public showcase ruleset) or a composed rulebook (rulebook_id, always requires an API key) — the same mutual-exclusivity shape as aethis_decide. Returns {ruleset_id|rulebook_id, slug, name, graph: {nodes, edges, sections, stats}, mermaid}: each node’s display.sentence/display.routes/ display.expr shows how that branch composes, and mermaid is a ready-to-render diagram string.
  • include_graph_overlay on aethis_decide (additive). Stamp a specific decision’s per-criterion outcome (satisfied/not_satisfied/pending) onto that same graph and return it as graph_overlay in the decide response — a “you are here” map for those inputs. Off by default; the response is unchanged when omitted.
  • aethis_create_rulebook / aethis_update_rulebook (new tools). Create an empty draft Rulebook (name/domain/slug/description) or update one, both accepting robot_hints — beat-keyed natural-language guidance for the conversational agent (active beats: general_context, preamble, session_start, postamble, session_end, stuck; reserved: persona, conversational_style, section_transition). An unknown beat is rejected client-side before the round-trip, mirroring aethis-cli’s _validate_robot_hints (v0.23.0). Rulebook composition (outcome_logic, ruleset_refs) is a larger surface not covered by these two tools yet.
  • years_between in the DSL helper reference (README). Documents the new completed-whole-years, leap-correct date operator (mirrors aethis-core Operator.YEARS_BETWEEN, commit 3607558) alongside days_between so generation can use it for age-from-date-of-birth instead of days_between(...) / 365 (division isn’t supported anyway).
  • 30 tools, up from 27. tests/tool-endpoint-map.ts and the drift suite are updated in the same change; every new operation/field/param is verified against the live api.aethis.ai OpenAPI document (engine 0.45.2).
  • Tests. New mocked unit coverage in tests/client.test.ts / tests/server.test.ts for the graph client methods, the create/update rulebook client methods, robot_hints beat validation (known + unknown + reserved), and include_graph_overlay pass-through; the nightly staging integration lane gains a real aethis_graph fetch, a aethis_decide include_graph_overlay round-trip, and an aethis_create_rulebookaethis_update_rulebook robot_hints round-trip (with best-effort archive cleanup of the probe rulebook).
aethis-cli
2026-07-17
  • feat(rulebooks): aethis rulebooks graph <id> — fetch and render the rulebook-level ruleset-map dependency graph (field -> criterion -> group -> outcome). Prints a node-count summary + a table of nodes (id, type, the criterion’s human-readable display.sentence, field count); --mermaid prints the raw Mermaid diagram source for piping into a renderer; --output json returns the full payload ({rulebook_id, graph: {nodes, edges, sections, stats}, mermaid}), including each node’s display.routes/display.expr for programmatic consumers. This endpoint requires a valid API key even for a public rulebook (confirmed against the live engine) — unlike the ruleset-level graph below, there’s no anonymous path. New AethisClient.get_rulebook_graph().
  • feat(rulesets): aethis rulesets graph <ruleset_id> — the single-ruleset analogue, open for public rulesets with no API key required (load_client_or_anon). Same table/--mermaid/--output json shape. New AethisClient.get_ruleset_graph().
  • feat: --include-graph-overlay on aethis decide and aethis rulebooks decide — stamps the decision’s per-criterion status onto the rule-map graph, returned as a graph_overlay field on the response (--output json to inspect it). Additive request flag; a plain-text hint is printed when the overlay is present and JSON wasn’t explicitly requested.
  • feat(rulebooks): aethis rulebooks schema surfaces engine_version. The schema response already carries the aethis-core build that served it (e.g. aethis-core@0.45.2); the CLI now prints it as a header line ahead of the schema payload instead of leaving it buried in the JSON.
  • Requires aethis-core 0.40.0+ (live on api.aethis.ai / staging.api.aethis.ai as of this release) for /graph, include_graph_overlay, and engine_version on /schema. robot_hints (shipped v0.23.0) is unaffected by this release.
aethis-core
2026-07-16

Fixed

  • An API key with expires_at set no longer 500s every request: the Mongo-stored (tz-naive) expiry is normalized to UTC before comparison, so an expired key gets its intended 401 api_key_expired. Latent since the expiry field existed — no key carried a non-None expiry until 2026-07-16 (issue #275).
aethis-sdk-python
2026-07-15
  • feat(errors): typed 401/403/429 exceptions carrying the structured error envelope. classify_response now raises AethisAuthError (401), AethisPermissionError (403), or AethisRateLimitError (429) — each a subclass of AethisAPIError, so existing except AethisAPIError handlers keep catching them (non-breaking). AethisError gains .reason_code, .missing_permissions, and .hint, lifted out of the public API’s structured envelope ({"detail": {"error", "reason_code", "missing_permissions", "hint", ...}}), so a caller can branch on err.reason_code == "denied_missing_permission" or read err.missing_permissions without re-parsing err.body. Plain-string and FastAPI-422-list details are untouched (fields stay None / []). Constructor stays backwards-compatible (new args default to None).
  • test(staging): live integration lane against staging.api.aethis.ai. New tests/integration/ (marker staging, excluded from the PR gate) mints a real API key the way a user does — Clerk sign-in ticket → frontend-API JWT → POST /api/v1/keys/ → teardown — and exercises every public method on Aethis + AsyncAethis (decide, decide_rulebook, list_rulesets, get_schema, whoami, explain, explain_failure, get_source, sync/async session flows) plus live 401/403 typed-error assertions and a contract cross-check. Reports red (never green-by-skip) when creds are missing or staging/contract is unreachable.
  • test(parity): recorded-live fixture parity. tests/shapes.compare_shape diffs the mocked conftest fixture builders (make_decide_response, make_schema_response, make_ruleset_summary) against real staging payloads so the mocked suite can’t silently drift from reality; the builders were updated to match the current engine shape (slug/rulebook_id, graph_overlay/timing, richer next_question/schema fields).
  • chore(ci): coverage floor (--cov-fail-under=45) + staging marker + nightly staging-integration.yml (report-only, workflow_dispatch + schedule, uploads a qa-run-record artifact for the sdk-staging lane). The coverage flags live in the CI command, not in addopts, so a bare pytest / uv run pytest works without pytest-cov (which is only in the dev extra) installed; the floor is still enforced in CI.
aethis-mcp
2026-07-15
Test-infra only — no runtime/behaviour change to the server or its tools.
  • Tool-schema drift suite (tests/drift.test.ts). Guards that the 27 server.tool() input schemas never silently drift from the engine. Reads each tool’s real zod shape (no vendored schema copy) and compares field names, types, and required-ness against the deployed staging OpenAPI document — the oracle. An explicit, checked-in tests/tool-endpoint-map.ts records the tool → operation correspondence and field renames (e.g. force → force_unsafe); a tool missing from the map, an unknown extra tool, an unclassified input field, a mapped operation absent from the engine, or a mapped body field the engine no longer has all fail loud. Runs in the PR gate (network-tolerant) and nightly (network-required).
  • Staging integration lane (tests/integration/, nightly). Runs the built server as a subprocess with a freshly minted staging key and drives it over the real MCP protocol: tools/list (== 27), a read-only core loop, and aethis_decide against a public showcase ruleset; a negative path proves an invalid key returns a structured error result while the server stays alive. Keys are minted via the self-serve path (server-default scopes), named e2e-dx-mcp-*, and revoked + swept in teardown.
  • staging-integration.yml — nightly + manual, report-only, emits a QA-run-shaped run record artifact for downstream ingestion; missing secrets or unreachable staging fail red, never skip-green.
aethis-cli
2026-07-15
  • feat: authorization errors now render the server’s hint and the missing scope readably. A 403 denied_missing_permission (and 401) previously printed the raw error object on commands that render their own errors (projects, whoami, …); the CLI now renders one clean line naming the missing permission plus, on its own dim line, the server’s follow-up hint (e.g. how to request access). The top-level handler and the per-command renderer now share one formatter (aethis_cli.output.format_error_detail / render_api_error), so every command surfaces the same readable message. The hint is rendered with markup disabled (so a hint containing [brackets] isn’t dropped) and non-string missing_permissions items are coerced (so a server quirk can’t turn the error into a traceback).
  • test: new staging integration lane (tests/integration/, marker staging). Acquires an API key the self-serve way (a fenced e2e user’s session → mint with the server’s default scopes, no scopes field), drives the CLI core loop against deployed staging (whoami/status, projects list/archive, rulesets/explain/fields/decide against a public showcase ruleset), and asserts the negative paths a caller actually sees — a scope-reduced key’s 403 and a revoked key’s 401 — with the error envelopes checked against the machine-readable public-API contract. Report-only nightly workflow (staging-integration.yml); never gates a merge. Run locally with the one-liner in tests/integration/README.md.
  • test: the spacecraft authoring e2e moved to its own weekly lane (authoring-e2e-weekly.yml). It drives the LLM authoring pipeline, so it is kept out of the nightly LLM-free cadence; the model is passed explicitly via X-Anthropic-Key, generation is bounded by an explicit iteration cap (SPACECRAFT_GENERATION_TIMEOUT), and the manual marker stays as the local escape hatch.
aethis-core
2026-07-15

Added

  • Read-only cross-tenant /api/v1/admin/* router (epic aethis-workspace#480, P1): /admin/keys, /admin/usage (daily rate-limit counters), /admin/generation-jobs (+ /{id} with trace), /admin/decisions (list excludes field_values; /{decision_id} full record), /admin/publish-audits, /admin/rulebooks, /admin/rulesets (metadata; DSL source additionally requires rulesets:source). Gated by the new internal-only admin:read scope AND api_key.internal == true AND a hard-fail under DISABLE_AUTH=true (503) — scope alone is deliberately not the boundary. admin:read is never self-servable (ALLOWED_SCOPES) and never an alias target. Uniform {items, next_cursor, limit, skipped_invalid} envelope, cursor pagination, server-side max page size, default 30-day lookback on time-series lists, per-doc validation (one malformed record never 500s a list), typed filters (tenant_id=None only via explicit anonymous_only=true, never a wildcard). New admin rate-limit category enumerated in every tier (internal ≈ unlimited). Routes stay in the live /openapi.json but out of the published public contract.
aethis-core
2026-07-15

Added

  • Decision log (epic aethis-workspace#480, P0): every /decide call can now be persisted server-side as a DecisionRecord (collection decisions), fulfilling the DecideResponse docstring’s deferred “server-side audit persistence”. Gated by DECISION_LOG_ENABLED (default off, fail-closed) with TTL retention via DECISION_LOG_TTL_DAYS (default 90) — the TTL index is declared in code and asserted at boot (logging disables loudly if the live index lacks expireAfterSeconds). The write is fire-and-forget off the hot path: bounded pending-task set, client-side insert timeout, fully exception-isolated (no decision-log failure can alter a /decide response). Write failures log structured ERROR, increment a counter, and can alert via DECISION_LOG_ALERT_WEBHOOK (Google Chat, rate-limited; unset = off).
  • DecideRequest.caller_ref — optional opaque caller metadata (flat string→string dict, ≤2 KB, no $/dotted keys) stored on the decision record for the caller’s own attribution (e.g. tda-server sends {firm, application_id}). Never an authorization key or cross-principal predicate (defect shape DS-25); invalid values are dropped with a warning, never rejected.
aethis-core
2026-07-10

Added

  • FieldDefinition (and the /schema + /decide next_question / optimal_path envelope) now carries an optional x_ui_widget: Optional[str] authoring override. Currently only "free_text" is recognised: it tells downstream consumers (Lisa’s expected_input emission in tda-server) to suppress the schema-derived structured-answer affordance (chips / select / date-picker) for that field and render a plain text composer, even though the field has a typed sort. Defaults to None — purely additive. (#255, epic aethis-workspace#422)
aethis-core
2026-07-10

Added

  • /decide: the next_question (and each optimal_path entry) now carries optional sort and enum_values fields, exposing the field’s answer type (Int / Bool / String / Enum / Date / Duration) and, for Enum sorts, its allowed values. Lets callers render typed input affordances (yes/no chips, a date picker, an option list) without a second /schema round-trip. Both default to None, so the change is additive — existing consumers are unaffected. Mirrors the sort / enum_values pair already on /schema’s FieldInfo. Populated on the ruleset path; rulebook /decide callers continue to source the type from /schema. (#254, epic aethis-workspace#422)
aethis-mcp
2026-07-08
  • docs: correct stale paper citation in the construction-insurance demo. The demo cited the withdrawn v3.6/v3.7 claim that GPT-5.4 at reasoning_effort=low scores 7/11 on the exception-chain subset; the paper withdrew that result in v3.8 (instrumented replication: 11/11). The demo now attributes 7/11 to GPT-5.3 only and pins the paper citation at v3.11. No code changes.
aethis-sdk-python
2026-07-04
  • fix(errors): attach the API’s detail (and full body) to AethisAPIError. On the primary error path, classify_response parsed the 4xx detail only to log it, then raised AethisAPIError("Aethis API returned 422") — blinding callers to why the request failed. The exception message now reads "Aethis API returned 422: <detail>" when a detail is present, and AethisError gained .detail / .body attributes carrying the parsed payload (both None for timeouts / connection errors). Constructor signatures stay backwards-compatible (new args default to None).
  • fix(models): DecideResponse.explanation is a single object, not a list. The field was typed list[dict] | None but the engine returns Optional[Dict[str, Any]] ({decision, groups: [...], unused_facts: [...]}), a latent ValidationError for any caller that actually requested one. Retyped to dict[str, Any] | None.
  • feat(decide): include_explanation parameter on decide() / decide_rulebook() (sync + async). The engine has always accepted include_explanation on POST /decide, but the SDK never sent it, leaving DecideResponse.explanation permanently None. Passed through in the request payload alongside include_trace; defaults to False.
  • feat(models): typed FieldNote and NextQuestion.notes. The engine attaches structured author guidance (note_text, source, metadata) to each next_question; the SDK silently dropped it. Adds the FieldNote model (exported from the package) and notes: list[FieldNote] on NextQuestion, defaulting to [] so older responses without notes keep parsing.
  • feat(client): list_rulesets(limit=20, offset=0) (sync + async) — wraps GET /api/v1/public/rulesets, returning the previously-exported-but-unreachable RulesetSummary model. Anonymous callers get public rulesets; an API key additionally surfaces that key’s own rulesets. limit is clamped by the engine to 1-50.
  • docs(readme, _base): capability-table + docstring fixes. README’s “What’s included” table now lists explain_failure, decide_rulebook, list_rulesets, include_explanation, and FieldNote; the build_headers docstring no longer names a nonexistent /next_question endpoint.
aethis-mcp
2026-07-04
Cross-surface review batch (aethis-mcp#50).
  • Surface next_question.notes (additive). aethis_next_question now renders a Notes block after the question when the ruleset author attached notes to it (each note carries note_text, source, and metadata). Notes are labelled by metadata.type (e.g. why, legal_background) when present, and each note’s text is wrapped with fenceUntrusted(...) since it is author-provided server content. Output is unchanged when no notes are present. The tool description now mentions the Notes block.
  • Fence aethis_list_guidance output. The guidance_text and source fields returned by the server were interpolated into the tool result unfenced, unlike every sibling handler. They are now wrapped with fenceUntrusted(...) under the UNTRUSTED_PREFACE warning (GHSA-ph7q-r9q4-922g hardening).
  • Send a single provider header. The per-request LLM key was sent under both X-Anthropic-Key and X-OpenAI-Key. It is now sent only as X-Anthropic-Key, matching how resolveLlmKey resolves the key.
  • Correct the stale latency figure. Two guidance strings claimed decisions are <5ms; corrected to <1ms to match the README and the canonical figure.
  • Docs: rewrote the CLAUDE.md architecture section to the real layout (src/index.ts + src/client.ts + src/credentials.ts, tests under tests/) instead of the non-existent src/server.ts + src/tools/ tree.
aethis-cli
2026-07-04
  • fix: network errors now render one actionable line, not a raw traceback. When the API is unreachable, times out, or a DNS/TLS error occurs, every command now prints Could not reach the Aethis API at <url>: <reason>. plus a “check your connection” hint and exits non-zero, instead of dumping an httpx stack trace. The top-level handler catches httpx.HTTPError (the umbrella over connect/timeout RequestErrors), matching the graceful handling login/account already had.
  • feat: non-interactive environments bypass confirmation prompts. A truthy AETHIS_NONINTERACTIVE or CI env var (values 1/true/yes, case-insensitive) now flips the whole process non-interactive, so destructive commands (account revoke, rulesets archive, projects archive, rulebooks archive, rulebooks tests delete) proceed without waiting on stdin, so a background job or CI step no longer hangs on a [y/N] prompt. The bypass prints a one-line notice so it’s never silently active. The explicit per-command --yes/-y flags keep working unchanged. New shared aethis_cli.prompts.confirm_or_abort helper.
  • docs: refreshed the worked examples in decide/explain/fields help to use public showcase rulesets (aethis/spacecraft-crew-certification, aethis/consumer-credit-prequalification) instead of product-specific slugs.
  • chore: make install uses uv pip install -e ".[dev]" (matching the README) instead of bare pip.
  • minor: dropped the unused upgrade-command strings from update_check._detect_install_method (it now returns just the detected method; the concrete upgrade argv is still built by update’s _upgrade_argv); decide reads the decision field with a safe default so a payload without decision renders as unknown rather than raising KeyError.
aethis-cli
2026-06-25
  • feat(rulebooks): declare robot_hints: in a rulebook file and push them to the engine. Rulebook authors can now provide natural-language guidance for the conversational assistant alongside the rulebook’s other configuration.
    • aethis rulebooks create <name> --file rulebook.yaml — a new --file/-f option reads a robot_hints: block (a sibling of name/domain/outcome_logic) from a rulebook.yaml/.json and sends it on create. CLI flags still own name/domain/slug/description; only the hints are taken from the file. No --file (or a file without a robot_hints: key) is a clean no-op — behaviour is unchanged.
    • aethis rulebooks set-logic <id> -f rulebook.yaml now also accepts a wrapped form: when the top-level object carries an outcome_logic: key, a sibling robot_hints: block is pushed in the same update. A bare Expr AST file (the prior shape) is still accepted unchanged.
    • robot_hints is a mapping of beat-name to a natural-language string. Active beats: general_context, preamble, session_start, postamble, session_end, stuck. Reserved beats (accepted, not yet acted on): persona, conversational_style, section_transition. Unknown beat keys and non-string values are rejected client-side with a clear message before the round-trip.
    • New optional robot_hints parameter on AethisClient.create_rulebook() / update_rulebook(); omitted from the request body when not supplied, so calls against an older engine are unaffected.
    • Requires aethis-core with the rulebook robot_hints field (aethis-core#220); mid-deploy to staging at time of writing. Against an engine without it, the field is ignored/rejected server-side.
aethis-cli
2026-06-16
  • feat(fields): aethis fields is now a command group for the full field-authoring loop. Bare aethis fields [-b <ruleset>] still shows a ruleset’s field schema (unchanged); three subcommands manage the local fields/fields.yaml:
    • aethis fields discover — uploads the project’s sources/ (creating the project if needed), runs server-side LLM field discovery, and merges the proposals into fields/fields.yaml so you start from a real draft instead of a blank file. Existing entries are preserved — only new keys are appended — so hand-authored labels/questions/hints are never clobbered. Prints the completeness score and any critical gaps. Needs an LLM key (ANTHROPIC_API_KEY), same as generate; without one it fails with a clear message naming the env var instead of a raw server header error. New AethisClient.discover_fields().
    • aethis fields pull — syncs the server’s authoritative produced fields (key + type + enum values) back into fields/fields.yaml so local matches reality after a generate. Local-only label/hints are preserved; fields absent from the server schema are kept and reported rather than silently dropped.
    • aethis fields validate — checks fields/fields.yaml before upload: valid type (int/bool/string/enum/date/duration), no duplicate keys, enum requires enum_values. The same validation now also runs inside aethis generate, per contributing file (rulebook + ruleset), so duplicate keys within a file fail fast before any server state changes.
    • discover/pull only ever write a vocabulary that re-validates: an unknown server type or an enum with no values falls back to string instead of producing a file the next validate/generate would reject. Writes also preserve any hand-authored keys the tool doesn’t model (e.g. description) rather than dropping them.
  • feat(generate): the field spec/produced diff is surfaced after generation. After a successful aethis generate, the CLI compares the pinned field vocabulary against what the engine actually produced and prints pinned-but-not-produced / produced-but-not-pinned fields (with a pointer to aethis fields pull) instead of the drift passing silently.
  • feat(init): rulesets can declare rulebook membership explicitly. A rulebook: key in a ruleset’s aethis.yaml (a path to the enclosing rulebook) now declares membership directly; the directory-position convention (<rulebook>/rulesets/<ruleset>/) remains the fallback. The init scaffold documents the key.
  • perf: source uploads are now idempotent. discover and generate share one project-resolution + upload path, and a per-file mtime ledger in .aethis/state.json means a discover followed by a generate (or repeated generates) only re-uploads sources that actually changed instead of re-pushing the whole sources/ tree each time.
  • fix(generate): don’t lose the ruleset id on a fast success. The poll loop occasionally saw the job flip to success a beat before latest_ruleset_id was populated, writing a null id to state and leaving fields pull / the field diff with nothing to work from. It now re-polls briefly for the id and only records a real one — never clobbering a prior good id with null.
  • example + e2e: examples/community-grants-rulebook/ is a generic rulebook (one shared field) with two member rulesets, and tests/e2e/test_rulebook_hierarchy_e2e.py (gated by the manual marker) drives discover/validate/generate/pull against a live API and asserts the shared rulebook field propagates into both members.
  • No engine change required — all endpoints (/fields/discover, /rulesets/{id}/schema, /fields/spec) are already served by aethis-core and used by the MCP server.
aethis-cli
2026-06-16
  • feat(init): field definitions get a real home (fields/fields.yaml). aethis init now scaffolds a fields/ directory with a fields.yaml for declaring the field vocabulary (key + type + optional label/question/hints). Previously fields had no dedicated home and only surfaced implicitly as the inputs: keys inside tests/scenarios.yaml. aethis generate reads fields/fields.yaml, pins the field keys/types via the project field-spec endpoint, and routes each field’s label/question/hints through guidance so a field is defined once.
  • feat(init): --kind rulebook scaffolds a rulebook. aethis init <name> --kind rulebook lays down a rulebook directory with shared guidance/ and fields/ plus a rulesets/ directory for member rulesets. When a ruleset lives under a rulebook (<rulebook>/rulesets/<ruleset>/), aethis generate propagates the rulebook’s guidance hints and field vocabulary into the ruleset — the rulebook definition wins on shared field keys — so a common field (e.g. date of birth) is defined once at the rulebook level and the end user is asked for it only once. --kind defaults to ruleset, so existing behaviour is unchanged.
    • New AethisClient.set_field_spec() (project field-spec endpoint, already served by aethis-core / used by the MCP server). No engine change required.
aethis-cli
2026-06-03
  • feat(rulebooks list): anonymous fallthrough to the public rulebook catalogue. With no cached API key, aethis rulebooks list now lists the cross-tenant public catalogue (rulebooks with public visibility, active status) instead of printing the v0.19.1 pointer message — completing the parity with aethis rulesets list. A dim one-liner (“No API key — showing public rulebooks…”) distinguishes the anonymous view; with a key, the tenant listing is unchanged.
    • New AethisClient.list_public_rulebooks(); use with make_anonymous_client so a cached key doesn’t promote the call to an authenticated tenant listing.
    • Requires aethis-core v0.29.0+ on the target API (live on api.aethis.ai). Against an older engine the anonymous path surfaces the server’s 401 cleanly.
aethis-cli
2026-06-03
  • fix(rulebooks list): stop prompting browser sign-in for anonymous users. aethis rulebooks list with no cached API key used to trigger the lazy-auth browser login — bad first-contact DX for a read-only browse command. Rulebooks are tenant-scoped, so an anonymous caller has nothing to list; the command now prints a pointer to the anonymous public catalogue (aethis rulesets list) and to aethis login, and exits 1 without ever opening a browser.
    • True anonymous fallthrough (listing public rulebooks without an account, mirroring aethis rulesets list) needs engine support for a public rulebook catalogue and is tracked separately; this release removes the login prompt in the meantime.
aethis-cli
2026-06-03
  • feat(update): aethis update — self-update the CLI to the latest release. Detects how the CLI was installed (uv tool, pipx, or pip) and runs the matching upgrade command. aethis update --check reports whether a newer release exists without installing anything.
    • Editable (development) installs are refused with a pointer to git pull && uv sync instead of clobbering the checkout.
    • The exit-time “new release available” banner now points at aethis update rather than a method-specific command.
    • fix: the banner’s uv upgrade hint was uv tool install --upgrade aethis-cli, which re-resolves from scratch and silently drops any extra --with requirements (e.g. plugin packages installed alongside the CLI). Both the banner’s install-method detection and aethis update now use uv tool upgrade aethis-cli, which honours the original install receipt.
    • A successful (or no-op) aethis update refreshes the banner’s 24h cache, so the notice goes quiet immediately after updating.
aethis-mcp
2026-05-29
aethis_refine now performs finding-driven incremental re-authoring: it seeds generation from the section’s active ruleset and asks the engine for the minimal edit to fix failing test cases while keeping passing tests green, instead of re-authoring the whole section from scratch. aethis_generate_and_test is unchanged (from-scratch authoring).Why this matters: fixing one wrong case in a published ruleset previously meant a full-section regenerate — expensive, and prone to silently regressing carefully tuned behaviour (e.g. caseworker-review criteria that intentionally yield undetermined). Refine keeps the blast radius to the criteria that actually need to change; the full-suite gate still guarantees no regression ships.Requires aethis-core with the mode parameter on /generate (engine ≥ the release shipping seed-from-existing refine). Older engines ignore the body and fall back to from-scratch generation.
  • client.generate() / generateAndTest() accept an optional mode and send {mode:"refine"} on the generation request body.
aethis-cli
2026-05-29
  • feat(refine): aethis refine + aethis generate --mode refine for incremental, seed-from-existing re-authoring. Instead of re-authoring a whole section from scratch, refine seeds generation from the section’s active ruleset and makes the minimal edit to fix failing tests while keeping passing tests green.
    • aethis refine [--hint "..."] [--seed-ruleset-id <id>] — the phase-3 TDD-loop command: optionally add a guidance hint, then refine. Defaults to seeding from the section’s active ruleset.
    • aethis generate --mode refine [--seed-ruleset-id <id>] — the same capability via a flag on generate; --mode fresh (default) is unchanged from-scratch authoring.
    • AethisClient.generate() gains optional mode / seed_ruleset_id; a no-arg call still sends no body, so it stays backwards-compatible against engines without the parameter.
    • Requires aethis-core with the mode parameter on /generate (live on api.aethis.ai). Against an older engine the flags no-op (empty body = fresh).
aethis-mcp
2026-05-27
Add the rulebook tier to the MCP read surface. Closes aethis-mcp#43 for the two endpoints the engine exposes today; the public-catalogue equivalent (aethis_discover_rulebooks) is deferred until aethis-core ships a no-auth rulebooks catalogue endpoint.Why this matters: until now, an agent connected via MCP could see the parts (rulesets via aethis_discover_rulesets / aethis_list_rulesets) and evaluate the whole (aethis_decide with rulebook_id), but had no way to find a rulebook or inspect how its rulesets compose. Concrete failure mode from a real 2026-05-27 session: asked whether aethis/uk-fsm was “three rulebooks or one rulebook with three rulesets”, the MCP gave no read path that could answer.

Added

  • aethis_list_rulebooks — lists rulebooks in the current tenant (auth-required, tenant-scoped). Returns the fields needed to distinguish one composed rulebook from N independent rulesets: rulebook_id, slug, name, domain, status, version, outcome_logic (the composition Expr AST), ruleset_refs, timestamps. Mirrors aethis_list_rulesets.
  • aethis_rulebook_schema — fetches one rulebook’s composition, bridged rulesets (with names + slugs + ruleset_ids), and aggregated input fields. Accepts either a slug (aethis/uk-fsm) or an opaque rb_* id. Mirrors aethis_schema but at the rulebook tier.
  • AethisClient.listRulebooks() / getRulebookSchema() — wrap GET /api/v1/public/rulebooks/ and GET /api/v1/public/rulebooks/{slug-or-id}/schema. The schema helper preserves the literal / in slugs (so aethis/uk-fsm hits the engine’s {namespace}/{name} matcher) and URL-encodes opaque ids.

Deferred

  • aethis_discover_rulebooks — the cross-tenant public catalogue equivalent of aethis_discover_rulesets. The engine’s /api/v1/public/rulebooks/ endpoint is tenant-scoped + auth-required on prod today; no anonymous catalogue variant exists. Will land once aethis-core adds it.
aethis-cli
2026-05-27
  • feat(output): gh-style machine-readable output mode (--output json, --json fields, --jq). Every list/show command (and the decision commands) now emit structured JSON on demand, so aethis rulesets list --output json | jq '.[0].slug' just works instead of trying to scrape ANSI-coloured Rich tables.
    • --output table|json — pick the format. Default: table on a TTY, json when piped (matches gh’s pipe-friendly autodetect).
    • --json FIELDS — implies --output json; takes a required comma-separated value (--json id,name) that limits the payload to those fields. (gh’s bare---json introspection trick is not yet exposed — Click/Typer’s option parser can’t cleanly distinguish “flag with no value” from “flag followed by positional”, so it’s deferred to a future --list-fields flag.)
    • --jq EXPR — pipe JSON output through jq before printing. Requires the jq binary on PATH; clear error with install hint if missing.
    • Commands migrated: rulesets list/show, rulebooks list/show/get-fields/tests list/schema/explain/decide, projects list/show, account keys, profile list, guidance list, fields, explain, decide, status. Each command has a sensible JSON shape — status --output json | jq .identity.key_id returns the live key id without rooting through any prose.
    • Footer hints (Try: aethis ...) are suppressed in JSON mode so pipes get clean output.
    • New module aethis_cli/render.py is the single emit point; new test file tests/test_render.py covers the matrix.
  • breaking(guidance export): --output renamed to --output-file to avoid clashing with the new global --output flag. Short form -o unchanged. Affects scripts that pipe to a named file: aethis guidance export --output foo.yamlaethis guidance export --output-file foo.yaml (or -o foo.yaml).
aethis-cli
2026-05-27
  • fix(status, whoami): read the multi-profile credentials file the same way every other command does. aethis login --api-key ... writes profiles.<name>.api_key to ~/.config/aethis/credentials (the multi-profile schema introduced in v0.10), but aethis status and aethis whoami had stale local resolvers that only looked for a flat top-level api_key (and whoami was looking at the wrong filename, credentials.yaml). Result: after a fresh aethis login, aethis status reported no API key and aethis whoami reported No Aethis API key configured, even though the same key worked for aethis projects list, aethis generate, and every other authoring command.
    • Both commands now route through the canonical resolve_cached_key() helper in auth_helpers.py, which honours AETHIS_API_KEY env → active profile → keychain → legacy .yaml file.
    • The _resolve_cached_key symbol is renamed to resolve_cached_key (public). The legacy _resolve_key_silent (status_cmd) and _resolve_api_key_lax (whoami_cmd) are removed.
    • Regression test in tests/test_status_cmd.py writes a real multi-profile credentials YAML to a temp XDG_CONFIG_HOME and asserts both commands surface the key.
aethis-mcp
2026-05-26
  • chore(server): tighten MCP instructions against decision extrapolation. Adds a “Reporting decisions” section to the server instructions block (visible to every client model as part of its system prompt on connect). New rules forbid asserting facts that are not in the tool response, generalising a single-ruleset decision to a composite outcome, naming rulesets/rulebooks not yet observed in the session, and offering follow-up calls against unverified slugs. Triggered by a real user trace where a model summarising a uk-fsm-child-eligibility decision closed with an offer to run the broader aethis/uk-fsm rulebook “to get the complete household-level decision” — the rulebook exists but currently 422s on prod (empty ruleset_refs, see aethis-core#90), so the offer overstated what would actually happen. Advisory, not enforced — but client models reliably honour instructions blocks.
aethis-sdk-python
2026-05-25
  • feat(explain-failure): Aethis.explain_failure() + AsyncAethis.explain_failure() — wraps POST /api/v1/public/rulesets/{ruleset_id}/explain-failure, returning the failing criterion and a targeted fix hint for a mismatched /decide result. Accepts field_values, expected_outcome ("eligible" | "not_eligible" | "undetermined"), and an optional test_name (default "test"). Return type is dict[str, Any] to match explain() / get_source() — can be tightened once the response shape stabilises. Note: ruleset_id must be the concrete identifier (not a slug); the underlying endpoint does not currently resolve slugs. Previously, callers had to drop to raw httpx for this endpoint — flagged in recipes/evaluate-a-case.mdx and recipes/debug-a-decide.mdx.
aethis-sdk-python
2026-05-22
  • docs(readme): rulebook surface advertised on the PyPI landing page. The v0.5.0 release shipped decide_rulebook() and rulebook_id on DecideResponse, but the README still framed the SDK as ruleset-only. Adds a dedicated “Composed rulebook” section with a runnable UK FSM example, the always-scope-gated note, and the async equivalent.
  • docs(install): switch pip install to uv add per workspace no-pip rule. The PyPI landing page is a public-facing surface bound by .claude/rules/no-pip.md. Adds uv pip install as a venv-friendly alternative.
  • docs(engine_version): update sample audit-field comment from aethis-core@0.10.0 to aethis-core@0.27.0 — matches live prod engine.
  • docs(beta): clarify that decision endpoints are anonymous only for single rulesets — rulebook decide is always scope-gated, so the SDK’s “anonymous when no key” claim needed a footnote.
aethis-sdk-python
2026-05-22
  • feat(rulebook): Aethis.decide_rulebook() + AsyncAethis.decide_rulebook() — evaluate a composed multi-ruleset rulebook through the SDK. Mirrors decide() but sends rulebook_id in the payload. Accepts either an opaque rb_<id> or a slug (e.g. aethis/uk-fsm). Requires an API key — rulebook evaluation is always scope-gated. Closes #14. Requires aethis-core v0.27.0+ live on the target API for slug-form rulebook paths.
  • feat(models): add rulebook_id: Optional[str] to DecideResponse — surfaces the rulebook identifier when the response was a composed-rulebook decide. Backwards-compatible: ruleset-only decides keep rulebook_id=None.
aethis-mcp
2026-05-22
  • docs(readme): v0.27.0 accuracy pass. Three fixes for fresh-developer accuracy:
    • Documented rulebook_id as an alternative to ruleset_id on aethis_decide — mutually exclusive; composed-rulebook evaluation always requires an API key.
    • Quickstart example: corrected field name from species to space.crew.species (the actual field ID in the spacecraft-crew-certification ruleset).
    • Windsurf config path: corrected from .windsurf/mcp.json to ~/.codeium/windsurf/mcp_config.json (canonical path per aethis-cli README).
aethis-mcp
2026-05-22
Add rulebook surface to aethis_decide — closes the converged-2-term client-completeness gap for MCP. The tool now accepts either ruleset_id (single ruleset) or rulebook_id (composed rulebook), mutually exclusive. Mirrors aethis-sdk-python v0.5.0 and aethis-cli rulebooks decide.

Added

  • aethis_decide tool accepts rulebook_id as an alternative to ruleset_id. Pass an opaque rb_<id> or a slug like aethis/uk-fsm. Composed-rulebook evaluation is always scope-gated by the engine — anonymous callers get HTTP 401.
  • AethisClient.decideRulebook(rulebookId, fieldValues, options?) — parallel to decide(); sends rulebook_id in the /decide payload.

Changed

  • aethis_decide description and schema updated to reflect both paths. Tool validates that exactly one of ruleset_id / rulebook_id is provided.

Requires

  • aethis-core v0.27.0+ live on the target API for slug-form rulebook paths. The rulebook_id body field on /decide has been supported since aethis-core v0.18.x.
aethis-cli
2026-05-22
  • docs(readme): v0.27.0 accuracy pass. Three fixes for fresh-developer accuracy:
    • Install block: removed the pip install fallback (uv and pipx are the recommended forms per workspace policy). Development section: pip install -e ".[dev]"uv pip install -e ".[dev]".
    • Added Rulebooks command-group section documenting the converged 2-term model surface shipped in v0.14.0–v0.16.1 (aethis rulebooks + aethis rulesets promote-to-live).
    • Updated engine_version example to aethis-core@0.27.0 (was absent; clarified to current production version).
aethis-cli
2026-05-22
  • docs(rulebooks set-logic): the docstring example for field_ref.key now matches engine behaviour. Phase A.16 (aethis-core v0.26.0+) added per-section aggregate group synthesis, so field_ref.key = <ruleset_name> resolves to the AND of that ruleset’s groups. The unscoped group-name and scoped <ruleset_name>.<group> forms remain available for advanced compositions. Requires aethis-core v0.26.0+ live on the target API.
aethis-cli
2026-05-21
  • feat(rulebooks): aethis rulebooks set-logic — set the composition expression on a rulebook. The composition expression (server field outcome_logic) is an Expr AST that combines per-ruleset outcomes into the rulebook’s final decision. Previously settable only via raw PATCH; now exposed via the CLI for multi-ruleset rulebooks (e.g. UK FSM’s child_eligibility AND (household_criteria OR universal_infant)).
    • aethis rulebooks set-logic <id> -f logic.yaml — load from YAML/JSON file
    • aethis rulebooks set-logic <id> --logic '<json>' — inline JSON
    • Exactly one of --file / --logic is required; both forms reject non-object payloads at the client side so server validation isn’t the first line of defence.
aethis-cli
2026-05-21
  • feat(rulesets): ruleset lifecycle commands scoped to a rulebook. Phase B.1b of the converged 2-term model. Adds four new sub-commands under aethis rulesets:
    • aethis rulesets list <rulebook> — list rulesets in a rulebook (grouped by ruleset_name with version counts, live version, and observed states). The legacy -p <project_id> and --public modes are preserved while the project-scoped authoring pipeline retires in a future phase.
    • aethis rulesets create <rulebook> <ruleset_name> [-n "Display name"] — create a new draft Ruleset inside the rulebook. The display name auto-derives from ruleset_name if not provided (child_eligibilityChild Eligibility).
    • aethis rulesets show <rulebook> <ruleset_name> — full version history for one ruleset name (bundle_id, version, state, created), with live version highlighted.
    • aethis rulesets promote-to-live <rulebook> <ruleset_name> <ruleset_id> [--note "..."] — atomically promote a testing-state ruleset version to live via the Phase A.4 service. Auto-cuts a new rulebook version; previous live ruleset is archived.
  • feat(client): four new AethisClient methods — create_ruleset_in_rulebook, list_rulesets_in_rulebook, show_ruleset_in_rulebook, promote_ruleset_to_live.
  • Requires aethis-core v0.20.0+ live on the target API (Phase A.8 endpoints).
aethis-cli
2026-05-21
  • feat(rulebooks): new aethis rulebooks command group. First user-facing surface for the converged 2-term authoring model (workspace PR #64, aethis-core PRs #133-139). A Rulebook is the whole form — the execution unit — that owns a locked field vocabulary, composition logic, rulebook-level test cases, and an integer version history.
    • aethis rulebooks list — list tenant rulebooks
    • aethis rulebooks show <id-or-slug> — full configuration
    • aethis rulebooks create <name> --domain <d> [--slug ...] — create draft
    • aethis rulebooks set-fields <id> -f fields.yaml — replace locked vocabulary
    • aethis rulebooks lock-fields <id> / unlock-fields <id> / get-fields <id>
    • aethis rulebooks tests add <id> -f scenario.yaml — embed full-form test case
    • aethis rulebooks tests list <id> / delete <id> <tc_id>
    • aethis rulebooks activate <id> / archive <id> — lifecycle
    • aethis rulebooks decide <id> -i '{...}' [--explain] — evaluate composed rulebook
    • aethis rulebooks schema <id> / explain <id> — combined schema + explanations
  • feat(client): new AethisClient methods for every rulebook REST endpoint (create / list / show / update / activate / archive / set-fields / lock-fields / unlock-fields / get-fields / add-test / list-tests / delete-test / decide-rulebook / get-rulebook-schema / explain-rulebook).
  • Requires aethis-core v0.19.0+ live on the target API (the Phase A.6 endpoints).
  • The legacy aethis projects / aethis generate / aethis test / aethis publish command tree is unchanged in this release — replacement lands in the next minor (Phase B.1b: ruleset lifecycle + project retirement). No backward-compat shims are planned past public release.
aethis-sdk-python
2026-05-20
  • feat(models): add name: Optional[str] to ruleset response models — surfaces the human-readable section name introduced in aethis-core v0.18.0. Adds RulesetSummary (anonymous catalogue / GET /api/v1/public/rulesets) and RulesetListItem (project-scoped / GET /api/v1/public/projects/{id}/rulesets) as typed models, and adds the same name field to SchemaResponse. Backwards-compatible: pre-backfill rulesets serialise with name=None.
aethis-mcp
2026-05-20
Add optional name parameter to aethis_publish tool — lets clients override the human-readable section name when publishing a ruleset. Companion to aethis-core v0.18.0’s PublishRequest.name field.

Added

  • aethis_publish tool now accepts an optional name parameter. When supplied, it overrides the section name stored on the ruleset (default is a titlecase of section_id, e.g. "english_language""English Language"). Section names are surfaced in rulebook responses so end users can see which sections compose a rulebook.
  • AethisClient.publish() now accepts a third name?: string argument and includes it in the POST body when set.

Tests

  • server.test.ts — two new aethis_publish cases: forwarding name to the client and echoing it in output; confirming name is omitted when not provided.
  • client.test.ts — two new publish() cases: body contains name when provided; body is absent when neither label nor name is set.
aethis-mcp
2026-05-20
Surface the human-readable section name in aethis_list_rulesets and aethis_discover_rulesets tool output. The engine has been returning name on both RulesetSummary (public catalogue) and RulesetListItem (project-scoped) responses since aethis-core v0.18.0; the MCP server already forwarded every API field verbatim via JSON.stringify, so the data was reaching the LLM, but the tool descriptions didn’t advertise the field. The descriptions now mention name so models know to read and surface it to users (e.g. “Knowledge of language and life in the UK” instead of just b_123…).

Changed

  • aethis_list_rulesets tool description now mentions the human-readable name field returned alongside ruleset ID, status, version, field count, and rule count.
  • aethis_discover_rulesets tool description now lists name in the documented response shape.

Tests

  • aethis_list_rulesets and aethis_discover_rulesets server tests assert the name field passes through to the LLM-facing JSON output.
aethis-cli
2026-05-20
  • feat(rulesets): show the human-readable section name column in aethis rulesets list output (both the public showcase and project-scoped tables). Surfaces the new field from aethis-core v0.18.0.
aethis-cli
2026-05-20
  • feat: pluggable auth providers. Profiles now carry an optional auth_mode (default "api_key") and audience field. The new aethis_cli.auth_providers module exposes a process-local registry; plugins (e.g. aethis-cli-internal) can register_provider("gcloud_id_token", ...) to add staff/internal auth schemes without touching the published package. AethisClient accepts an optional auth_provider callable, and make_authed_client(...) picks the right provider based on the active profile’s mode.
  • feat: aethis status now prints the active profile name + auth mode (plus audience when set). For non-api_key modes it shows “provider-minted at request time” instead of calling /me, which is X-API-Key-only.
  • chore: un-hide the --base-url global flag in aethis --help (it was already implemented, just hidden=True).
aethis-mcp
2026-05-19
Security hardening pass. Bundles the v0.5 security review fixes into one release. Closes #33, #34, #35; addresses GHSA-ph7q-r9q4-922g (disclosed on publish).

Security

  • GHSA-ph7q-r9q4-922g (high) — prompt injection via unsanitised API response text in aethis_explain_failure. formatExplainFailure now wraps every API-supplied free-text field (diagnosis, dsl_hint, criterion title / rule_text / source_refs) in an <api_response> fence and prepends a one-line preface telling the model the contents are data, not instructions. Literal closing tags inside payloads are neutralised so a payload cannot break out of the fence. The same fenceUntrusted helper has been applied to other free-text API surfaces (aethis_next_question, aethis_discover_sections, aethis_refine_sections, aethis_discover_fields, formatTestResults).
  • #33src/credentials.ts now resolves the credentials file via fs.realpath and asserts the canonical path sits under $HOME (or under an absolute XDG_CONFIG_HOME the user controls); refuses with UnsafeCredentialsError otherwise. Permissions check now matches ssh / aws-cli behaviour: any group/other bit set on the credentials file → refuse with Permissions 0NNN ... too open. Run: chmod 600 <path>.
  • #34progress_detail from the polling API is sanitised before it lands on stderr: control characters are stripped (TAB preserved) and the body is capped at 120 visible chars + . Full-fidelity output is gated behind AETHIS_MCP_VERBOSE=1. Prevents the server from injecting terminal escape sequences or PII into anything that captures the MCP process stderr.

Changed

  • #35 — Authoring tools now accept safer per-call key forms.
    • New anthropic_key_env: string — name of an env var the MCP server reads at call time. Preferred. The raw value never appears in the tool call so it does not land in the MCP host’s session transcript JSONL.
    • New anthropic_key_keychain: string — macOS keychain reference, either service:account or just account (service defaults to aethis-anthropic-key).
    • Raw anthropic_key / openai_key arguments remain accepted for backwards compatibility but are now marked [sensitive — do not echo or log] in the schema; deprecated in tool descriptions.
    • resolveLlmKey (exported from src/credentials.ts) consolidates the resolution chain and throws MissingLlmKeyError if every form is empty.
    • Applies to aethis_generate_and_test, aethis_refine, aethis_discover_fields, aethis_refine_fields, aethis_discover_sections, aethis_refine_sections.

Docs

  • README: new “Passing your Anthropic key safely” section showing env / keychain forms first; raw-key form marked deprecated.
  • CLAUDE.md: new gotchas covering safe-key resolution and the untrusted-content fencing helper.
aethis-cli
2026-05-19
  • fix(decide): aethis decide --explain no longer crashes with AttributeError: 'str' object has no attribute 'get'. The CLI previously treated the engine’s explanation field as a flat list[dict], but the public decide route returns a layered {decision, decision_path?, groups: [{group, status, criteria: [{title, status, supporting_facts?, ...}]}], unused_facts} shape. The “Rules” block now walks the actual structure and renders each group + criterion with PASS/FAIL marks, supporting fact field/value pairs underneath satisfied criteria, and a final list of unused fields (provided answers that no satisfied criterion referenced — useful for catching field-name typos).
aethis-cli
2026-05-19
  • fix(login): default AETHIS_CLERK_CLIENT_ID to the OAuth Application registered on the clerk.aethis.ai Clerk instance. The previous default belonged to a different Clerk app, so aethis login returned invalid_client against the dev-tools domain set in 0.12.1.
  • fix(account): default AETHIS_CLERK_DOMAIN to clerk.aethis.ai for aethis account generate (matching the 0.12.1 change to aethis login); previously still pointed at the immigration domain.
aethis-cli
2026-05-13
  • feat: decide, explain, and fields no longer prompt for sign-in when no API key is present. Public rulesets are now accessible with zero setup — the CLI silently uses an anonymous client and lets the server return an error only if a private ruleset is requested.
  • fix: hide --base-url global flag from aethis --help (internal dev override; AETHIS_BASE_URL env var unchanged)
  • docs: reorder aethis --help to lead with the no-auth explore flow, then authoring
aethis-mcp
2026-05-12
  • docs: surface aethis-skills as the optional agent workflow layer on top of MCP.
aethis-cli
2026-05-12
  • fix: default Clerk domain changed from clerk.aethis.legal to clerk.aethis.ai so developer portal users can authenticate via aethis login (closes aethis-cli#40)
aethis-mcp
2026-05-11
  • fix: align package.json repository metadata with GitHub provenance so npm Trusted Publishing can verify the package source.
aethis-mcp
2026-05-11
  • fix: pin zod to v3 so the MCP SDK tool registration types match the build-time schema shape; npm publish now runs the prepublishOnly TypeScript build successfully.
aethis-sdk-python
2026-05-10
  • fix: update examples/session.py to use AETHIS_RULESET_ID env var (was deprecated AETHIS_BUNDLE_ID) and replace stale internal default with the public aethis/construction-all-risks slug
aethis-mcp
2026-05-10
  • docs: fix stale bundle/bundle_id/aethis_create_bundle terminology in docs/demo-construction-insurance.md and docs/agentic-decision-systems.md — these files were not caught by the v0.3.0 rename sweep. All references now use ruleset/ruleset_id/aethis_create_ruleset
  • chore: bump server.json version to 0.4.1 (was lagging behind package.json)
  • security: regenerate package-lock.json — bumps hono 4.12.12 → 4.12.18, fast-uri 3.1.0 → 3.1.2, ip-address 10.1.0 → 10.2.0, postcss 8.5.8 → 8.5.14; clears all 6 open Dependabot alerts (closes #19)
aethis-mcp
2026-05-10
  • feat: new aethis_discover_rulesets tool — lists the cross-tenant public showcase catalogue (no authentication required). Mirrors the no-auth policy of aethis_decide / aethis_schema / aethis_explain. Returns slug, ruleset_id, description, field_count, rule_count for each entry; the slug or ruleset_id can then be passed to the existing decision tools. Distinct from aethis_list_rulesets, which remains tenant-scoped and authenticated. Tool count: 24 → 25.
  • feat: client.discoverRulesets(limit, offset) wrapping GET /api/v1/public/rulesets.
  • docs: aethis-decide prompt and server-instructions now point at aethis_discover_rulesets for first-time discovery (no key) before falling back to aethis_list_projectsaethis_list_rulesets for authenticated tenant browsing.
aethis-cli
2026-05-10
  • fix: remove examples/demo_core.sh (internal dev script referencing aethis-core by name and a private API path — not intended for public release)
  • fix: update tests/e2e/test_spacecraft_e2e.py to resolve the spacecraft fixture from examples/spacecraft-crew-rules/ instead of an internal path; drop internal service name from comment
  • docs: fix “rule bundle” → “ruleset” in examples/spacecraft-crew-rules/README.md
aethis-cli
2026-05-10
  • feat(updater): gh-style update-check banner. On startup the CLI kicks off a background thread that queries PyPI; if a newer release is available it prints a one-line notice to stderr at exit: “A new release of aethis-cli is available: 0.11.0 → 0.12.0 — to upgrade, run: <method-aware command>”. Detects whether the install came via uv tool, pipx, or pip and renders the matching upgrade command. Result is cached for 24 h at ~/.config/aethis/update_check.json. Suppressed automatically when stderr is not a TTY (CI, piped output). Disable with AETHIS_DISABLE_UPDATE_CHECK=1. The check never blocks the command — failures are silent.
aethis-cli
2026-05-10
  • feat(rulesets): aethis rulesets list --public lists the cross-tenant public showcase catalogue (no auth required). When run with no --project-id and no project context, falls through to the public catalogue automatically with a one-line hint — so a fresh signup sees something the moment they install the CLI instead of an empty list. Combine with aethis fields -b <slug> / aethis explain -b <slug> / aethis decide -b <slug> to fully exercise a ruleset without an API key.
  • feat(profiles): named credential profiles with both per-invocation flag (aethis --profile new-dev …) and sticky default (aethis profile use new-dev). Manage with aethis profile list/use/add/remove. Reserved profile name anonymous forces unsigned mode — handy for testing what a fresh signup sees without losing your admin key. aethis login --profile <name> writes into the named slot. Credentials file format upgraded to {active_profile, profiles: {...}}; legacy single-key files are read transparently and rewritten to the new shape on next save.
  • feat(client): AethisClient(unsigned=True) and make_anonymous_client() helper for paths that must hit the anonymous surface without accidentally sending a cached key.
  • feat(client): client.list_public_rulesets(limit, offset) wrapping GET /api/v1/public/rulesets.
aethis-cli
2026-05-08
  • feat(publish): thread --force through to the server-side TDD gate introduced in aethis-core 0.11.0. client.publish() gains a force_unsafe: bool = False keyword; aethis publish --force now passes force_unsafe: true in the request body so the server-side gate is bypassed (and a publish_force_bypass audit event is recorded). Older engines ignore the field — no breakage. Without --force, the new gate refuses publishing over a failing test suite even when the CLI’s own test gate is bypassed (e.g. by a direct curl that doesn’t use the CLI). Closes the cli/server asymmetry that nearly shipped a 10/11 ruleset to a canonical aethis/* slug on 2026-05-07.
aethis-sdk-python
2026-05-07
  • docs: link to the test-driven authoring guide on docs.aethis.ai and surface the publish-gate guarantee (rulesets cannot publish with a failing test) in the private-beta callout. Reference surface only — no code changes
aethis-mcp
2026-05-07
  • docs: surface the test-gate guarantee — aethis_publish refuses to publish a ruleset with a failing test, derived from positioning bible §5/§7. Strengthens the existing Note to an Important callout and annotates the publish line in the four-stage workflow
  • docs: drop force=true mention from troubleshooting — surfacing the override on the public README undermines the “cannot be published with failing tests” guarantee. The API parameter remains in the engine; whether to deprecate it is tracked separately
  • docs: fix tool count (25 → 24); tools table sums to 24 (5 + 7 + 8 + 2 + 2). Fixed in README header and in CLAUDE.md
aethis-mcp
2026-05-07
  • docs: link to docs.aethis.ai/agents/onboarding from Install section
aethis-cli
2026-05-07
  • docs: link to docs.aethis.ai/agents/onboarding from MCP one-liner section
aethis-sdk-python
2026-05-06
  • docs: remove positioning paragraph above Install — reference surface (per aethis.os/positioning/surface-types.md); the tagline is enough
aethis-sdk-python
2026-05-06
  • docs: add private-beta callout for authoring endpoints (decision endpoints remain anonymous)
aethis-sdk-python
2026-05-06

Changed

  • docs: align README with positioning bible — add problem/solution/methodology intro paragraph before Install section.
  • docs: add aethis-bible: markers to derived copy blocks (sourced from public-messaging.md §3/§4).
  • fix: terminology audit found no deprecated “rule bundle” or <5ms instances in README; no replacements needed.
aethis-sdk-python
2026-05-06

Changed

  • Aethis(api_key=...) and AsyncAethis(api_key=...) now accept api_key=None (or no argument) for the developer beta. Evaluation endpoints (/decide, /schema, /explain, /source) work anonymously, so the SDK no longer forces a key on instantiation. When api_key is omitted, the x-api-key header is simply not sent. Authoring endpoints will still return 401 without a key. Existing callers passing api_key="..." are unaffected.
  • README quickstart now shows Aethis() (no key) as the primary form, targets aethis/uk-fsm/child-eligibility (a live public ruleset) instead of the dated eng_lang:20250912-ec5d7c23, and prints the audit fields (inputs_hash, decision_id, decision_time, engine_version) added in 0.3.2. Configuration table updated: api_key is now documented as optional during the developer beta.
  • examples/oneshot.py refreshed to match: no key required by default, AETHIS_BUNDLE_ID env var renamed to AETHIS_RULESET_ID (catching the 0.3.0 bundle → ruleset rename it had missed), targets the live UK Free School Meals ruleset, prints the audit fields.

Notes

  • Backwards-compatible: Aethis(api_key="ak_live_...") continues to work exactly as before.
  • This pairs with the public-surface positioning that evaluation is free during the developer beta — see docs.aethis.ai.
aethis-sdk-python
2026-05-06

Added

  • DecideResponse.decision_id — per-call audit identifier returned by the engine.
  • DecideResponse.inputs_hash — canonical SHA-256 fingerprint of the input set.
  • DecideResponse.decision_time — ISO-8601 timestamp of the decision.
  • DecideResponse.engine_versionaethis-core@<semver> string identifying the engine that produced the decision.

Fixed

  • DecideResponse previously declared ruleset_id twice; Pydantic silently overrode the first declaration with the second. Deduplicated.
  • The four audit fields above were already returned by /api/v1/public/decide but were silently dropped by Pydantic because the model didn’t declare them. Callers can now read them directly off the typed response — no need to reach for the raw JSON. This is the audit-trail fingerprint that the docs and homepage prominently advertise (inputs_hash, decision_id); shipping an SDK that hid it was a defect.

Notes

  • Backwards-compatible. All four new fields default to None, so older engines that don’t emit them still parse cleanly.
aethis-sdk-python
2026-05-06

Fixed

  • aethis_sdk.__version__ now resolves from installed package metadata via importlib.metadata instead of a hardcoded constant. Previously reported "0.1.0" on every install regardless of the actual package version. Falls back to "0.0.0+unknown" only if the package is imported without being installed (editable dev or zip-on-PYTHONPATH).
  • Package description on PyPI: "…and bundle schemas""…and ruleset schemas" to match the v0.3.0 public-surface rename.

Added

  • README PyPI / Python-version / License shields.
aethis-mcp
2026-05-06
  • docs: restructure README as dev MCP docs — Install / Quick start / Tools / Setup leads, positioning sections (Problem, Accuracy, When to use this, How it works, Example walkthrough) removed; their content belongs in docs.aethis.ai or the benchmarks repo
  • docs: trim narrative paragraphs across Quick start, Conversational eligibility, and Authoring; collapse repeated Tips into terse callouts
  • docs: header tagline rewritten to a single factual line; link bar updated to the new structure
aethis-mcp
2026-05-06
  • docs: normalise tone to documentation register — replace argumentative Proof section with one-liner accuracy claim, neutralise example framing, trim sales-y bullets in When to use this
  • docs: add private-beta callout for authoring tools (decision tools remain public, no key required)
aethis-mcp
2026-05-06
  • docs: align README with positioning bible — promote 225-scenario accuracy framing
  • docs: add aethis-bible: markers to derived copy blocks
  • docs: fix latency claim to <1ms (was <5ms)
  • fix: replace deprecated “rule bundle” terminology with “ruleset”
aethis-cli
2026-05-06
  • docs: remove Why Aethis section — package README is a reference surface (per aethis.os/positioning/surface-types.md); install / quick start / authentication is the right lead, not a problem statement
aethis-cli
2026-05-06
  • docs: add private-beta callout for authoring tools (decision tools remain public, no key required)
  • docs: clarify in Authentication that aethis login requires an invite during the beta
aethis-cli
2026-05-06
  • docs: align README with positioning bible — add Why Aethis section, solution framing, TDD methodology beat
  • docs: add aethis-bible: markers to derived copy blocks
  • fix: replace deprecated “rule bundle” terminology with “ruleset” in pyproject.toml description
aethis-sdk-python
2026-05-05

Changed (Breaking)

  • Renamed the public bundle concept to ruleset throughout the SDK to match the aethis-core 0.10.0 API contract. Every bundle_id parameter and JSON key is now ruleset_id. URL paths inside the client moved from /api/v1/public/bundles/... to /api/v1/public/rulesets/.... The Session constructor now takes ruleset_id and exposes session.ruleset_id instead of session.bundle_id. Class names: BundleSummaryRulesetSummary.

Required

  • Engine aethis-core 0.10.0 or newer. Older engines respond at the legacy /bundles/* paths and this client will 404. Pin aethis-sdk==0.2.0 to keep working against an older engine.
aethis-mcp
2026-05-05
  • Breaking: renamed the public bundle concept to ruleset throughout the MCP tool set, to match the aethis-core 0.10.0 API contract. The compiled rule artefact is now called a ruleset in every tool name, parameter, and prose description. Specifically:
    • Tools: aethis_create_bundleaethis_create_ruleset, aethis_list_bundlesaethis_list_rulesets, aethis_archive_bundleaethis_archive_ruleset
    • Parameters: every bundle_idruleset_id
    • JSON keys returned to the agent: bundle_id/latest_bundle_id/bundle_version/deprecated_bundles/result_bundle_id/bundle_refsruleset_id etc.
    • URL paths inside the client: /bundles/.../rulesets/...
  • This release requires aethis-core 0.10.0 or newer. Older engines respond at the legacy /bundles/* paths with bundle_id JSON keys; this client expects /rulesets/* and will 404. Pin aethis-mcp@0.2.6 if you need to keep working against an older engine until you can deploy.
  • MCP tool renames are part of the public LLM-facing contract. Coding agents that have learnt the old tool names (aethis_list_bundles etc.) from training data will get “no such tool” errors and need to retry against the new names. Tool descriptions explicitly call out the new naming so the LLM picks it up on first read.
aethis-cli
2026-05-05
  • Breaking: renamed the public bundle concept to ruleset throughout the CLI to match the aethis-core 0.10.0 API contract. The compiled rule artefact is now called a ruleset everywhere — in command names, in flag names, in JSON keys, and in prose. Specifically:
    • aethis bundles list/archiveaethis rulesets list/archive
    • --bundle-id flag → --ruleset-id
    • client.list_bundles() / archive_bundle() / get_bundle_schema() / explain_bundle() / get_bundle_source() / set_bundle_visibility() SDK methods → *_ruleset
    • JSON keys bundle_id / latest_bundle_id / bundle_version / bundle_refsruleset_id etc.
    • Default scope strings bundles:read/explain/writerulesets:* (validated against the engine’s permission registry)
  • This release requires aethis-core 0.10.0 or newer. Older engines return bundles:* scopes and the CLI will reject them as invalid. Pin to aethis-cli==0.7.2 if you need to keep working against an older engine until you can deploy.
aethis-mcp
2026-05-03
  • Docs: replaced two stale aethis.ai/sign-up request-access pointers in the README authoring section with aethis.ai/developer-access. After the Clerk cutover, /sign-up serves the Clerk SignUp form for invitees rather than the Notion request-access form. No code or behaviour changes.
aethis-cli
2026-05-03
  • Docs: replaced the stale aethis.ai/sign-up request-access link with aethis.ai/developer-access in the README “Author your own rules” section and in the aethis whoami hint shown when the active key has no authoring scope. After the Clerk cutover, /sign-up serves the Clerk SignUp form for invitees rather than the Notion request-access form, so external “Request access” pointers were broken. No code path changes.
aethis-mcp
2026-05-01
  • Docs: README Quick start now leads with aethis mcp install --target all (via aethis-cli v0.5.0+). The manual claude mcp add and per-client JSON tabs are demoted to “Manual install” beneath. Setup section gains a Keys & security subsection covering AETHIS_API_KEY vs ANTHROPIC_API_KEY placement (MCP client config, not shell), rotation workflow (aethis account generate + aethis account revoke), and multi-machine guidance.
  • Discoverability: package.json keywords extended with regulation, policy, eligibility-check, deterministic-decision — matches the highest-intent search terms used by developers in regulated domains. Existing keywords retained.
  • CLAUDE.md updated to note the aethis mcp install install path so future contributors don’t re-document the manual JSON as primary.
No code or behaviour changes.
aethis-cli
2026-05-01
  • Docs: README gains a dedicated Authentication section explaining the three modes (aethis login for explicit setup, lazy auth for inline mid-command sign-in, --no-prompt for CI). Authoring quickstart leads with aethis init (the v0.7.0 wizard prompts for a name and runs sign-in itself, so aethis login as a separate step is no longer needed). Environment-variable table expanded to cover AETHIS_BASE_URL and ANTHROPIC_API_KEY. Troubleshooting entry for Auth error now mentions the lazy-auth prompt and --no-prompt. CLAUDE.md updated to document the aethis mcp install path, lazy-auth helper, and --no-prompt flag for future agents working on the CLI. No behaviour change.
aethis-cli
2026-05-01
  • New: aethis init first-run wizard. With no args, prompts for the project name (default = current directory name); a positional aethis init <name> keeps working unchanged. If no API key is cached, triggers the same OAuth flow as aethis login before any filesystem writes — Ctrl-C during browser sign-in no longer leaves a half-scaffolded project on disk. After scaffolding, prints the next-step ladder (aethis sections discoverfields discovergenerate --poll) so new users have a clear path forward. New --no-prompt flag for scripted use; with that flag, missing required values fail fast and missing auth surfaces a clean AuthRequired error instead of opening a browser. 10 new tests covering prompted, non-prompted, no-auth + interactive, no-auth + --no-prompt, and name-validation paths. Closes #15.
aethis-cli
2026-05-01
  • New: lazy auth. Authenticated commands (aethis projects list, generate, publish, etc.) now detect missing credentials or 401 responses and offer an inline browser sign-in prompt: "No API key. Open browser to sign in? [Y/n]". On accept, the same OAuth flow as aethis login runs, the key is cached, and the original command retries — exactly once, no infinite loops. Non-TTY stdin/stdout (CI, pipes) and the new --no-prompt global flag skip the prompt and surface a clean AuthRequired error. --api-key <key> still bypasses the helper entirely. New helper module aethis_cli/auth_helpers.py; the OAuth flow inside commands/login_cmd.py was factored into a reusable run_browser_login(). 17 new tests in tests/test_lazy_auth.py. Closes #12.
aethis-cli
2026-05-01
  • New: aethis mcp install --target <client> writes the MCP server entry into your editor’s config in one shot. Supports claude-code (project-level .mcp.json), cursor (~/.cursor/mcp.json), claude-desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS, ~/.config/Claude/... on Linux), windsurf (~/.codeium/windsurf/mcp_config.json), and --target all for everything at once. Idempotent, preserves any other configured MCP servers. aethis mcp uninstall --target <client> reverses the install. Closes #16.
aethis-cli
2026-05-01
  • UX: aethis login --help now reads “Sign in and store an API key locally. First-time setup — this is all you need.” aethis account generate --help clarifies it’s for additional keys (rotation, multi-machine, scoped access). After successful aethis login, a tip line points at aethis status / aethis account keys. README quickstart collapses any “first login then generate” sequence into a single aethis login step. No behaviour change. Closes #13.
aethis-cli
2026-05-01
  • Docs: README install section now leads with uv tool install aethis-cli (recommended) and pipx install aethis-cli, with pip install in a venv as the third option. Pairs with Aethis-ai/docs#12. Closes #14.
aethis-mcp
2026-04-28
First version published to npm since 0.2.2. The v0.2.3 tag exists in git but predates the publish workflow — it never reached npm. This release rulesets all work since 0.2.2.

Registry

  • MCP Registry submission ready. Added mcpName: io.github.aethis-ai/aethis-mcp to package.json and a top-level server.json declaring the npm package, transport, and environment variables. Submit via mcp-publisher after npm publish.

Breaking Changes

  • openai_key parameter renamed to anthropic_key on aethis_generate, aethis_generate_and_test, and aethis_refine. The old parameter name is still accepted for backwards compatibility but will be removed in a future release.

Improvements

  • Better error messages on generation failure. Failed jobs now surface classified error details (invalid key, rate limit, connection failure) instead of “unknown error”.
  • Sends both X-Anthropic-Key and X-OpenAI-Key headers for backwards compatibility with older API versions.
  • aethis_explain_failure clarification. Tool docs now note that ruleset_id must be the concrete ID from a /decide envelope; slugs are not yet resolved on this endpoint (tracked in aethis-core#51).

Docs

  • Proof section updated to cite the Simpson et al. 2026 benchmark paper. Replaced the pre-paper 11-scenario table (GPT-5.4-mini 82%, GPT-5.3 27%) with paper-backed figures from Table 8b of the published benchmark. Removed the 27% GPT-5.3 claim — the paper identifies that figure as a harness-configuration bug; the corrected value is 63.6%.
  • Proof section: add §6.10 LegalBench external-validation paragraph. v3.8 of the paper adds external validation across 9 LegalBench tasks (949 held-out cases). Combined paired-binomial McNemar’s: p < 0.001 vs Sonnet 4.6, p = 0.003 vs Opus 4.7, p < 0.001 vs GPT-5.4. Linked to the public LegalBench harness at confidently-wrong-benchmark/legalbench/.
  • Proof section: replaced 11-scenario subset table with v3.8 adversarial extension (§6.4.1). The v3.7 11-scenario exception-chain table no longer differentiates current frontier models from the engine (GPT-5.4 default and low both 11/11, Opus 4.7 11/11). The Proof section now leads with the v3.8 adversarial extension (20 newly-authored scenarios; engine 20/20; Opus 4.7 18/20; GPT-5.4 default 19/20 with 0 reasoning tokens; Sonnet 4.6 19/20) and the shifting-ground argument from paper §6.5 Finding 6.
  • Use aethis/construction-all-risks slug in CAR proof example for stable URL across ruleset regenerations.
  • Invite-only beta messaging replaces “rolling out now” framing throughout README — explicit approval-gated framing aligned with current onboarding.
  • docs.aethis.ai badge added to README.

Internal

  • Added .github/workflows/publish.yml (provenance via OIDC + NPM_TOKEN) so future tag pushes auto-publish.
  • Added Claude PR review workflow (dry-run mode).
  • Added internal CLAUDE.md for agent onboarding.
aethis-cli
2026-04-28
Two bug fixes that block the documented quickstart against public bundles.

Bug fixes

  • aethis decide -b <slug> / explain -b <slug> / bundles archive -b <slug> now accept slugs. The classifier in _id_utils.classify_id previously returned "unknown" for slugs (e.g. aethis/uk-fsm/universal-infant), and require_bundle_id rejected them with "is not a valid Bundle ID". The public API resolves both bundle IDs and slugs on /decide, /schema, and /explain, so the CLI now passes both through. Error message updated to mention slugs and link to aethis bundles list.
  • aethis fields -b <bundle> no longer requires an aethis.yaml. It now uses the same load_client_or_fallback() helper as decide, explain, bundles, and projects — read-only commands work from any directory. Previously this command errored out with "No aethis.yaml found" even when called with a concrete bundle reference.
aethis-sdk-python
2026-04-27

Added

  • DecideResponse.slug — stable, human-readable handle for the ruleset (e.g. aethis/uk-fsm/child-eligibility). Set when the resolved ruleset was published under a slug; None otherwise. Prefer this over ruleset_id for any reference that should survive ruleset regeneration.
  • SchemaResponse.slug — same handle, surfaced from GET /rulesets/{id}/schema.

Notes

  • Backwards-compatible. Existing code that reads ruleset_id keeps working unchanged; slug is purely additive.
  • Requires the aethis-core engine release that surfaces the field in /decide and /rulesets/{id}/schema responses (rolling out 2026-04). Older engines will simply leave slug=None.
aethis-cli
2026-04-19

aethis status output polish

  • Server line now shows just the URL when it’s the default (https://api.aethis.ai) — the (default — no override) suffix was noise in the common case. Overrides (AETHIS_BASE_URL, aethis.yaml) still show source with a green marker.
  • Identity line now says ✗ API key rejected (run \aethis login` to re-authenticate)when/mereturns 401/403/404, instead of the raw✗ 404 from /me (Not Found)` HTTP message. Other HTTP errors keep a contextual message.
aethis-cli
2026-04-19
This release ships the rich-status and read-only-from-anywhere work that the 0.2.0 notes already described but which hadn’t actually been merged into a published release yet. (The code was sitting in a local branch; the prior 0.2.x/0.3.x wheels still had the minimal status command.)

aethis status — context-aware summary

  • aethis status with no args now prints CLI version, resolved server URL (with source — env / yaml / default), loaded aethis.yaml, bundle id from .aethis/state.json, and whoami identity (key id, tenant, tier, scopes, can_author). Helps answer “what will my next command actually hit?” before running it.
  • aethis status -p <project_id> (or from inside a project dir) still shows generation progress, appended after the global summary.

Read-only commands usable from anywhere

  • aethis explain, decide, bundles list, bundles archive, projects list, projects show, projects archive no longer require an aethis.yaml in the current directory — they fall back to AETHIS_BASE_URL (or the default https://api.aethis.ai).
  • aethis explain / decide now reject Project IDs (proj_*) passed to -b/--bundle-id with a one-line hint pointing at the Bundle column of aethis projects list, instead of silently 404’ing.

Internals

  • New resolve_base_url_with_source() / load_client_or_fallback() helpers in aethis_cli/config.py that the above commands share.
  • New aethis_cli/commands/_id_utils.py + test coverage for bundle-id validation.
  • New tests for explain, status, and _id_utils.
aethis-cli
2026-04-19

Docs cleanup

  • README and docs.aethis.ai/interfaces/cli no longer document AETHIS_BASE_URL or show base_url: in the aethis.yaml example — public users always hit https://api.aethis.ai, and the documented values were just duplicating the default. The env var still works as an override for devs and CI; it’s intentionally undocumented.
  • Dropped the AETHIS_CLERK_DOMAIN env var from the README (marked “development only” and confusing for public users). The override still works in code.
aethis-cli
2026-04-19

Trim public CLI to the developer API surface

The public CLI now only ships commands every developer can use against https://api.aethis.ai. Privileged and staff-only commands have been removed and will live in a separate internal plugin package.Breaking changes:
  • Removed aethis source — internal-only DSL viewer; moved to the aethis-cli-internal plugin.
  • Removed aethis account permissions — IAM permission registry; internal-only.
  • Removed the aethis guidance domain … group (and the deprecated aethis domain guidance … alias) — domain-level guidance is staff-managed.
  • Removed the global --base-url flag (plus the per-command --base-url on login, account generate, account keys, account revoke). The AETHIS_BASE_URL env var still overrides the default. The flag had no meaning for the public API target and cluttered --help.
New: third-party plugin support.
  • The CLI now discovers plugins via Python entry points under the aethis_cli.plugins group. A plugin exposes one callable register(app: typer.Typer) -> None and attaches extra commands to the root app. Plugin load failures print a single warning to stderr and never crash the CLI.
  • The staff-facing aethis-cli-internal package uses this hook to re-attach source, domain guidance, permissions, and the --base-url flag.
aethis-cli
2026-04-19

Consolidated guidance command tree

  • aethis domain guidance ... moved under aethis guidance domain ... — the domain group exists only to host guidance, so having two top-level trees for the same concept was confusing. All four subcommands (add, list, import, export) behave identically on the new path.
  • The old aethis domain guidance ... path still works as a hidden deprecated alias: invocations continue to succeed and emit a one-line deprecation notice to stderr. It is no longer shown in aethis --help. Planned removal in a future release.
aethis-cli
2026-04-19

aethis status — global CLI context

  • New behaviour: aethis status (no args) now prints a one-screen summary of the current CLI context: CLI version, resolved server URL (with source — --base-url / env / yaml / default), loaded aethis.yaml + project, bundle id from .aethis/state.json, and whoami identity (key id, tenant, tier, scopes, can_author). Answers “what will the next command hit?” — the usual cause of “why is my project missing?” is talking to the wrong server.
  • Backward compatible: aethis status -p <project_id> (or invoked from a project dir) still shows generation progress, now appended after the global summary.

UX improvements for read-only commands

  • aethis explain, decide, bundles list, bundles archive, projects list, projects show, and projects archive no longer require an aethis.yaml in the current directory — they fall back to AETHIS_BASE_URL (or the default https://api.aethis.ai) when invoked from anywhere.
  • aethis explain and decide now reject Project IDs (proj_*) passed to -b/--bundle-id with a one-line hint pointing at the Bundle column of aethis projects list, instead of silently proceeding to a 404.
  • aethis --base-url <url> is now a top-level flag, equivalent to setting AETHIS_BASE_URL for one invocation. Lets you hit staging or a self-hosted instance without editing aethis.yaml.
  • aethis projects list prints a short tip after the table showing how to copy a Bundle value into aethis explain -b ….
  • Configuration and authentication errors now render as a single red line via the existing cli() handler, not a Rich traceback panel. pretty_exceptions_enable=False is set on every Typer app.

Better --help

  • Top-level aethis --help now shows common flows (status, list, explain, decide), authoring flow, and how to target a different server.
  • explain, decide, bundles list, projects list, and status all have “Examples:” blocks in their per-command help.
aethis-mcp
2026-04-14

New Tools

  • aethis_add_domain_guidance — Add cross-section guidance hints at domain level (e.g. uk_citizenship). Applies automatically to all projects in the domain during generation.
  • aethis_list_domain_guidance — List all active domain-level guidance hints.
  • aethis_list_guidance — List all guidance hints accumulated for a project. Use before adding new guidance to avoid duplicates.
  • aethis_explain_failure — Diagnose a failing test case. Returns criterion statuses with DSL metadata and a targeted fix hint.

Improvements

  • aethis_add_guidance now accepts process_type ("rule_generation" | "field_extraction"). Use field_extraction for field design principles (solicitor navigation, raw-facts principle). Defaults to "rule_generation".
  • aethis_add_domain_guidance accepts notes — SME commentary or legislation provenance stored on the hint. Never sent to the LLM.
  • Two-level hint retrieval: generation now fetches domain-level hints (cross-section) alongside project-level hints in a single pass.
aethis-mcp
2026-04-09

New Tools

  • aethis_discover_fields — Discover input fields from source text. Returns field names, types, and completeness assessment. Call before writing test cases.
  • aethis_refine_fields — Iterate on field discovery with targeted feedback.

Improvements

  • Added aethis-author and aethis-decide MCP prompts for compatible clients (Claude Desktop, Cursor, VS Code Copilot).
aethis-mcp
2026-04-05
Initial release.

Features

  • Decision tools: aethis_schema, aethis_decide, aethis_next_question, aethis_explain
  • Discovery tools: aethis_list_projects
  • Authoring tools (TDD workflow): aethis_create_ruleset, aethis_generate_and_test, aethis_add_guidance, aethis_refine, aethis_publish, aethis_archive_project, aethis_archive_ruleset
  • HTTPS enforcement for remote hosts
  • Exponential backoff with retry on 429/502/503/504
  • Works with Claude Desktop, Claude Code, Cursor, and Windsurf
Note: v0.1.0 used aethis_create_ruleset (renamed to aethis_create_ruleset) and aethis_project_status (replaced by aethis_list_projects). These tools were removed in v0.2.x.
aethis-cli
2026-04-05
Initial release.

Features

  • Account management: aethis account generate (browser OAuth), aethis account keys, aethis account revoke
  • Project authoring: aethis init, aethis generate --poll, aethis test, aethis publish
  • Decision tools: aethis decide, aethis fields, aethis explain
  • Project management: aethis projects list, aethis bundles list, aethis bundles archive
  • Security: HTTPS enforcement, OS keychain storage, PKCE OAuth flow
  • Example: Spacecraft Crew Certification Act 2049 with 5 golden test cases