Skip to content

Release 0.9.0: approve facts whose evidence speaks for itself - #12

Merged
renezander030 merged 2 commits into
mainfrom
release/0.9.0
Oct 16, 2026
Merged

renezander030 merged 2 commits into
mainfrom
release/0.9.0

Conversation

@renezander030

@renezander030 renezander030 commented Oct 16, 2026 •

Copy link
Copy Markdown
Owner

A configured rule can now approve the facts whose evidence speaks for itself, while every inference and every correction still waits for a person.

Added

  • workspace.auto_approve (empty by default) lists rules that approve a new fact at filing:
    • {fact_type: source-fact, require: source-link} approves a fact that names its --source and --link.
    • {fact_type: action-record, require: said} approves a fact that carries the reviewer's own words.
    • belief cannot be listed (the configuration is refused), and revise, invalidate and retire always wait, whatever their evidence.
    • A fact filed with --supersedes-rejection always waits for a person.
    • A said rule trusts the caller to pass the reviewer's own words.
    • A rule's approval records decided_by: policy:<type>:<require> and is bound to the content digest like a reviewer's approval.
  • kg propose / kg bundle --said "...": the reviewer's own words when the fact is their statement. They are part of the approved digest, pass the secret gate, travel into the episode provenance and name a bundle's source.
  • The drain dry run reports decided_by for each planned item: the rule, or reviewer.

Changed

  • kg-workspace reject also rejects an approved item, whoever approved it, until a drain claims it. It used to refuse anything but a pending item.
  • The drain claims each item under the workspace lock just before its first write, and skips an item rejected or changed since it read the queue. An item with a landed fact can no longer be rejected (retire it instead). A rejection records decided_by: reviewer and drops the approval digest.

Verification

  • uv run ruff check .: pass.
  • uv run pytest: 215 passed (20 new; the 4 added after review fail on the first push). Two earlier dry-run tests now also expect decided_by: reviewer.
  • release_audit.py --allow-remote --identity-base origin/main: pass.
  • Container MCP smoke (docker build + scripts/mcp_smoke.py): pass.
  • Through the installed CLIs:
    • A sourced source-fact and a --said action-record are approved at filing and labelled in the dry run.
    • A belief with --said stays pending.
    • kg-workspace reject stops an approved item.
    • A configuration listing belief is refused.
    • The 0.8.0 end-to-end run on a real Ladybug file still passes 8/8.
  • Help text and MCP tool schemas are unchanged except for --said.

Reviewing

  • Base: main at fca90b3. Version 0.9.0 in pyproject.toml, server.json and uv.lock.
  • Read config.py (FACT_TYPES, AutoApproveRule.approves) first, then workspace.py (file_facts, _approve, _approving_rule, the reject condition, _claim, _planned), then cli.py and gates.py.
  • drain changes only by the claim before each item's first write (_claim). Untouched: ingestion, retirement, the MCP server, retrieval.
  • No other PR is open.

workspace.auto_approve lists rules that approve a new fact at filing: a
source-fact naming its source and link, or an action-record carrying the
reviewer's own words given with --said. A belief cannot be listed, and
revise, invalidate and retire always wait. A rule's approval records
decided_by and is bound to the content digest; kg-workspace reject still
stops any approved item before it drains.
- A fact filed with --supersedes-rejection always waits for a person,
  whatever rule its evidence matches.
- The drain claims each approved item under the workspace lock just
  before its first write, and skips an item rejected or changed since it
  read the queue.
- kg-workspace reject refuses an item a drain has claimed or that has a
  landed fact; retire those instead.
- A rejection records decided_by: reviewer and drops the approval digest.
- Document that a said rule trusts the caller to pass the reviewer's words.
@renezander030
renezander030 merged commit ccb02f5 into main Oct 16, 2026
4 checks passed
@renezander030
renezander030 deleted the release/0.9.0 branch October 16, 2026 16:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant