Skip to content

Releases: onushq/onus

Onus v0.11.0

Choose a tag to compare

@github-actions github-actions released this 14 Oct 06:42
94a5aee

The manifesto's gaps, closed: every agent call checked and logged, scoped Onus Cloud tokens, escalations and a blocked channel, risk inputs and a learned model that only raise lanes, held-out suites from the map, a behaviour diff, coverage, the production loop, a human lane that waits for an owner, and one provenance record per change.

  • The door log and Onus Cloud's calls reach the provenance of changes made through Onus Cloud and CI (onus help provenance): an agent attaches its task's slice of the door log to its pull request with onus_cloud_attach_evidence (doorLog: true; the server cuts the slice from its own log) or onus cloud evidence <pull> --door-log --task <task> (--run is now optional). The slice is the run of entries from the task's first to its last (new schemas/door-log.schema.json). Through onus mcp --token it carries the door's inspection of the token it holds, never the token, so a change made through Onus Cloud by an agent that never escalated has its token on record (new token.source: attached, ranked below every other source). Onus Cloud passes these on once it keeps them; an older one refuses a door log on its evidence route.
    • onus ci pr gains --audit FILE, and onus provenance --audit reads the slice as well as a whole log. The chain is checked over the slice from its first entry; the record keeps the task's entries with doors.source: attached and whether they verified. A slice that does not verify is recorded as not intact, with the entries of the task it names and the reason in the doors gap; one of another task keeps no entries and the gap names both tasks. A slice is the agent's word, since anyone can build one that verifies: the doors gap stays, narrowed to say so. Its decisions on escalations count only when it verifies and is the change's, and Onus Cloud's decision is recorded over them whatever its state, the escalations gap naming any disagreement. A door log that does not verify, a slice or a whole log, no longer gives the token or the task. A door log that holds nothing of the change's task, or reaches a run that does not know the task, leaves the doors gap; onus ci pr gains --task.
    • onus ci pr and onus provenance gain --calls FILE: Onus Cloud's log of the calls made under the task token (new schemas/cloud-calls.schema.json; the API's {"calls": [...]} with createdAt and credentialId is read too). The record sums them up in doors.calls, marked source: onus-cloud: totals, the counts for each route and scope by decision, the token ids, and every denial (at most 100). Calls that name no task are counted as the change's and shown as untasked; with no task known, the doors gap says every call given was counted. Calls alone leave the doors gap, narrowed: they are Onus Cloud's word, not the agent's door log.
    • onus ci pr --submission FILE takes the agent's own submission: the record keeps its token (token.source: agent-submission) and the escalations it lists, when it is for one of the pull request's commits.
    • The action gains a submission input, and otherwise finds one on the records branch at submissions/<pull request number>.json or submissions/<head commit>.json, for ci pr and, through the new onus provenance --agent-submission FILE, for the provenance rebuilt at close. Both take only its token and escalations, and only when it is for one of the pull request's commits. onus ci records pull copies those into the records folder, and a push keeps whatever else is on the branch. onus help ci says what the action cannot know: the token itself, the door log, and what Onus Cloud keeps.
    • Onus Cloud keeps the slices agents attach and passes one cut at the head with --audit (the change's task's, and the first attached, so a later slice cannot displace the agent's), the calls made under the change's scoped token with --calls, and, when no escalation or slice gave the door's inspection, the scoped token's own with --token-inspection. Its pages label the token sources agent-submission and attached. Known gap: an attached slice is the agent's word, so the doors gap stays in every hosted run, narrowed to say so.
    • None of this input stops ci pr, and a door log or calls file that cannot be read stops onus provenance neither: each is a warning and a gap. Only the fields named are read from a call; the API's others (path, userAgent, credentialName) never are. A call with a token, or a field read that looks like one (an Onus Cloud token or API key, a PASETO, a Biscuit), is left out with a warning that names the field, never the value.
    • A token from the agent's submission is marked token.source: agent-submission and ranks below the door's word (audit, inspection): it is plain JSON, possibly from the records branch, so the record takes it on its word. The escalations it lists are recorded as granted until Onus Cloud says otherwise, and the escalations gap says they are its word. An attached slice cut at a commit that is not one of the change's (its head), or that names none, gives neither the task, the token nor any decision, and the doors gap says so. A door log is attached only to the pull request whose head in Onus Cloud is the worktree's commit, so an agent cannot attach its slice, and the other tasks' entries in it, to another change.
  • Provenance records the escalations and token Onus Cloud kept (onus help provenance): onus ci pr and onus provenance take --escalations FILE, Onus Cloud's escalations with their decisions (new schemas/escalation-decisions.schema.json), and --token-inspection FILE, the door's inspection of the task token ({task, rights, expires}, never the token). So a change made through Onus Cloud has its token and escalations on record instead of as gaps.
    • Each escalation keeps its decision, who made it and when, and Onus Cloud's id as cloudId. It is joined to the request the submission or the door kept. Its reason is the decider's, never why the agent asked.
    • The token comes from the inspection, widened by what Onus Cloud granted to the task, with the new source inspection. A token verified by the run, a submission's scope or the door log comes first.
    • Only the change's escalations are kept: those on its pull request, listed by its submission, kept by an earlier record, or filed at one of its commits, its branch or its pull request's head ref (new ref and commit); others only when they share the change's task. An escalation that names none of these never sets the change's task or its token.
    • A final decision from the submission or the door log stands against one Onus Cloud has not made. When both are final and differ, Onus Cloud's is recorded and the escalations gap names the disagreement.
    • An empty list from Onus Cloud is on record, so escalations is not a gap. An escalation that cannot be read is left out with a warning and a gap that names the field, never the value. An inspection ci pr cannot read is named in the token gap. Only a token given in place of its inspection stops ci pr, before anything is written.
    • onus provenance --escalations still reads a folder of requests, and fails on a path that does not exist. With a file and --submission-id, it reads the kept requests too. --verify checks the new fields like any other. Dates that do not exist, such as month 13, are no longer read as times.
  • Area history for one repository (onus help production): onus signals areas --repository owner/name counts only that repository's changes, and the signals tied to no change, as a classification of one of its changes reads them. Onus Cloud keeps one records folder per organisation and shows each repository its own areas this way.
  • The action waits for a review in the human lane, and an owner's approval is the one that counts (onus help ci, onus help lanes): with records: true, the action lists the pull request's reviews with the GitHub CLI, and the members of each owning team when its token can read them, and passes them to onus ci pr --reviews. It asks the owners onus ci pr names to review (GitHub's requested reviewers), each once per pull request. While a human-lane change has no review that counts, the job fails (new input wait-for-review, default true; new output review: waiting or approved). It also runs on pull_request_review, and after an approval re-runs the failed pull_request check for the head, so the human lane waits without Onus Cloud too. Add pull_request_review to the workflow's events and make the job a required check. The new lanes.approval says whose approval counts: owner (the default when the change has owners) counts only a person named as an owner or a member of an owning team; member (the default when nobody owns it) counts anyone with write access. The rule and the owners are read at the base commit: the owners of each changed file's component in the base onus.yaml (an explicit --config inside the repository is read at the base too), else CODEOWNERS at the base, rather than the report's hints.owners, which come from the head. So a change can neither loosen the rule nor name its own approver. New onus ci owners prints those owners, so a host can look up owning teams first. The rule applies in the human lane only; other lanes keep every approval with write access, for provenance. When an owner cannot be checked (a team whose members the reviews file does not list, or an email), or no owner but the author could approve, anyone with write access counts and the review's note says why. A name GitHub refuses to ask is a warning and a line in the comment. Reviews on closed pull requests do nothing. The --reviews file may now be {"reviews": [...], "teams": {"@org/team": [logins]}}. The review answer gains approval and note; the pull record and the outcome keep approval, and the provenance record `approv...
Read more

Onus v0.10.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 12:06
27e833c

Track records that fill themselves in, and agents that work through Onus.

  • Agents hand work in through MCP (ADR 0012, onus help agents): onus mcp adds onus_env_create, onus_env_run, onus_envs, onus_env_destroy, onus_evidence, onus_run_test, onus_submit, onus_judge, onus_escalate, onus_escalation, onus_lanes and onus_outcomes. Agents cannot record outcomes, grant escalations, mint tokens or choose their scope; --no-actions leaves the tools out. Submissions are kept in .onus/submissions/ and shown in onus ui; granted escalation tokens are kept beside their request for the agent to collect.
  • Outcome records kept by CI (ADR 0013, onus help ci): with records: true, the GitHub Action classifies every pull request with its agent setup's track record, records the outcome when it closes and reverts when the default branch moves, all on an onus/records branch of the repository. People record approvals, audits and incidents with /onus approve <row>, /onus audit ok|miss and /onus incident <note> involved: … comments (write access only); an approval re-runs the check. The agent setup is read from an Onus-Agent: trailer, the branch name, the bot author or a Co-authored-by trailer. New onus ci pr|closed|comment|push|records commands do the work and run in any CI system. An incident now counts against its agent setup even after the change is reverted.
  • An outcomes dashboard in onus ui: reads origin/onus/records when there is no local file, and shows changes by week and lane, each agent setup's progress toward auto-merge, and the pull requests in flight.
  • A better map in onus ui: pan and zoom, a layout by folder beside the layers, focus on a component with one or two steps of neighbours, filters for imports, calls and types, a side panel for the selected component, and a treemap of the repository by folder and size.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.10.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.9.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 09:49
f94b04b

A web interface for everything Onus does.

  • onus ui: a web interface for the repository, embedded in the binary and served on 127.0.0.1 behind a per-session token (ADR 0011, onus help web-interface): a dashboard with the component graph, a command palette (⌘K), and light and dark themes. It covers the component graph and every component, symbol and file (dependents, dependencies, tests, invariants and the impact of a change); reports of uncommitted work and of any two refs; the lane policy, submissions, classification and the judge; environments, runs and the evidence store; outcomes, incidents and reverts; root keys, task plans, minting, inspecting and narrowing tokens; escalations; the audit log; onus.yaml; and the guide.
  • JUnit results are counted by their <testcase> elements, so reporters that write no suite totals (such as Node's) are counted.
  • Lane and judge reasons quote row titles instead of wrapping them in backticks, which broke the code spans inside them.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.9.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.8.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 21:24
d1f7a57

Phase 5 complete: environments, the evidence store, traces, the production loop and contract-level scopes (ADR 0010, onus help environments).

  • Environments: onus env create|run|list|destroy builds a container from a commit and environment: in onus.yaml (or the devcontainer). Setup runs once per lockfile and is kept as a warm image; a seed command loads synthetic data. There is no network unless the task's token names hosts, and then only through an egress proxy that allows exactly those hosts. Secrets the token names come from ONUS_SECRET_<NAME> and are redacted from everything stored.
  • The evidence store: each run leaves a manifest and its artifacts (the log, JUnit XML, OTLP traces) under their sha256 in the repository's git directory; onus evidence list|show reads it. onus env run prints a test run for onus submit --evidence, and the judge checks it against its manifest.
  • Traces feed the map: --traces <otlp.json> on onus map, diff and report adds traced call edges from OpenTelemetry spans, such as an event bus dispatching to a handler.
  • The production loop: onus outcomes ingest-reverts finds reverts in git history, onus outcomes incident records incidents, and --result rolled-back records flags turned off and rollbacks. Reverted changes leave an agent setup's record, a recent incident stops it from auto-merging, and onus outcomes backlog lists where held-out tests should go.
  • Contract-level scopes: plans can name writeComponents (notifications.internal), readContracts and escalateBefore: ["contract:*"]; onus token mint --repo resolves them through the map, and the gateway refuses changes to guarded contract files without a granted escalation.

Fixed

  • onus run-test and the judge's re-runs saw an empty tree with container engines that run in a VM (colima, podman machine), which do not share the host's temporary directories. The commit's files are now copied into the container instead of mounted.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.8.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.7.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 20:53
efc6901

Phase 4 complete: risk lanes and the verifying judge (ADR 0009, onus help lanes).

  • onus submit bundles a change for review: the intent, Onus's report, changed paths, test runs to re-run, the token's scope, escalations, approvals and the agent setup, and nothing of the author's reasoning.
  • onus classify puts a change in a lane (auto-merge, judge, human, blocked). The lane comes from a policy in onus.yaml (lanes:) and hard floors no policy can lower: secrets, out-of-scope writes and unapproved weakened tests are blocked; sensitive code, rules of the game and intent mismatches go to a person. New agent setups cannot auto-merge, and a share of auto-merges is audited by a person.
  • onus judge verifies before it judges: it re-runs the evidence in containers, then checks intent, contracts and tests, then runs held-out checks. An optional taste reviewer can raise concerns but never approve. The verdict is approve, reject (with reasons the agent can act on) or escalate.
  • The action's lanes, apply-lane and auto-merge inputs show the lane, label the pull request, fail blocked changes and enable GitHub's auto-merge.
  • onus outcomes record|summary track outcomes per agent setup and judge configuration, including the audit miss rate and the human-lane share.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.7.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.6.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 20:21
dabb3a9

Phase 3 complete: scoped tokens, enforcing doors and evidence-based escalation (ADR 0008, onus help scopes).

  • Task tokens: onus token keygen|mint|attenuate|inspect|check mint Biscuit tokens from task plans (writes, reads, hosts, secrets, refs, ttl). Holders can narrow a token for a sub-agent but never widen it. onus scope suggest proposes reads from the map, leaving out sensitive components.
  • The git gateway: onus gateway serve gives each task a mirror holding only what it may read. It refuses pushes that change anything outside the write scope, with an error that says how to ask, and replays accepted commits onto the real repository with a credential the agent never holds. A red-team test suite is the gate: zero out-of-scope writes.
  • Read scope for the map: onus mcp --token answers only about files the task may read.
  • Escalation: onus escalate records a structured request with graded evidence, the blast radius and sensitive labels. onus escalation decide grants low-risk requests automatically when a failing test is reproduced by onus run-test (a container with no network); grant and deny are for people.
  • Audit: every decision is a hash-chained JSON line; onus audit <log> checks the chain.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.6.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.5.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 19:42
369828e

Phase 2 complete:

  • onus_impact (onus query impact <target> --change remove|rename|change-signature|add-required-member|change-behavior): before a change, the files that break or need a check, one site each (for a new required member only the implementations, found in the source text), and the tests that exercise the target.
  • onus_invariants (onus query invariants [target]): the invariants onus.yaml declares.
  • onus mcp --http <addr>: the MCP tools over streamable HTTP. Only loopback host names are answered unless --allow-host adds one; every tool answers the same over stdio and HTTP.
  • scripts/benchmark-references.mjs: compares the map's dependents with the TypeScript compiler's find-all-references. Recall is 1.000 on the fixture and 0.999 on Twenty (benchmark).

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.5.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.4.1

Choose a tag to compare

@github-actions github-actions released this 08 Oct 19:05
77291a8
  • From replaying every commit of three SvelteKit and TypeScript monorepos:
    • Private declarations that share a name or a small body in different files are no longer reported as renames or moves.
    • A type that only gains optional parameters or fields is a compatible change (contract-type-widened).
    • Drizzle migrations are recognized, with the indexes they create.
    • Awaits merged into Promise.all, rewritten away or deduplicated are not "removed".
    • Guards that moved with renamed variables are matched by their shape.
    • A new package added to several components is one row.
    • Route rows name their component, and first-use rows skip $app and $env.
  • --markdown-out <file> writes the Markdown report alongside the JSON, so the action runs each report once instead of twice.
  • The action's plugins input passes a plugins file (such as the Svelte plugin) without reading it from the analyzed repository.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.4.1. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.4.0

Choose a tag to compare

@github-actions github-actions released this 08 Oct 14:37
477d630

M7 tuning, from an audit of reports on 20 large real pull requests: fewer wrong facts, flags on the changes that need a person, less noise, faster reports. Audited again afterwards, rows with wrong facts went from 7% to under 1% and the reviewers' usefulness score from 2.1 to 3.0 out of 5 (evaluation). A regression corpus (crates/onus-cli/tests/corpus) reproduces each kind of mistake with invented code and keeps it fixed.

  • Fewer false alarms:
    • A contract change is breaking only when a user or implementation outside the change was not updated. Casts (as X) no longer count as implementations; published packages and packages with unresolved imports stay breaking.
    • Types are compared with object and union members sorted, so regenerated code that only reorders is no change.
    • An await, guard or throw that moved into another function (a body extracted into a helper) is not reported as removed.
    • Tests that moved, or went with the code they tested, no longer read as weakened; the latter get a quiet tests-removed-with-code row.
    • Imports of package subpaths (pkg/utils) resolve through exports, mapping build output back to source, so users of shared packages are no longer missed.
    • Lockfile rows list the installed versions that change, or say none do (patch hashes and checksums are not versions).
    • First-use rows skip Node's built-in modules and APIs already used through a namespace.
  • Flags by risk class, each its own row that needs a person: migrations (with what they do to stored data), GraphQL operations (separately when they skip authentication), HTTP routes from file-based routing and controllers, authentication and authorization code, patched dependencies, root build config and infrastructure. Rows that need a person rank first.
  • Less noise: generated code is one quiet row per component; config rows name the keys or Dockerfile instructions that changed; build-tool and workspace files have their own classes instead of "runtime configuration"; widespread config edits are grouped by the keys they change.
  • Faster reports: onus report compares only the paths git reports as different, writes both trees on all cores, shares parsed facts between the two maps, and with a cached base map extracts only the base's changed files. On a 31,000-file repository a report takes about 22 s instead of 29 s, and about 12 s with the cache.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.4.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.

Onus v0.3.0

Choose a tag to compare

@github-actions github-actions released this 07 Oct 16:24
  • Sharper reports and onus_check:
    • Untyped values are compared key by key (Schema.struct({...}), z.object({...}), object literals), and union types member by member.
    • Changes Onus cannot compare are one low-confidence row instead of a "may have changed" row each.
    • Production code that uses an API of an already-used package for the first time is reported with the pinned version.
    • Breaking contract rows name the implementations and test doubles not updated.
    • Changes in components of more than 300 files name their module folders.
  • onus_check for agents: it returns a checklist of what to verify before finishing, and states what it does not verify, so a clean result is evidence, not approval.
  • The map for coding agents (experimental): onus mcp serves the map of a worktree as MCP tools (onus_status, onus_find, onus_symbol, onus_dependents, onus_dependencies, onus_tests_for, onus_owners, onus_component, onus_file, onus_check), and onus query asks the same questions from a shell. Every agent and worktree of a repository shares one map server, which follows file changes and re-parses only changed files, sharing per-file facts across worktrees (ADR 0007). An evaluation found no measurable gain from the navigation tools for agents implementing features, so they are marked experimental and Phase 2 focuses on onus_check.
  • onus find ranks symbols by how many query words match (name, then fields and parameters, then path), finds the types that declare a field, and always lists matching files, instead of returning nothing unless every word was in one name.
  • Mapping a large monorepo is about 25% faster (4.6 s to 3.5 s on Twenty's 31,000 files) with byte-identical maps: public methods are found without a quadratic scan, components are matched with one glob set, packs compile once per process, the file walk is parallel and module resolution is cached.
  • The Homebrew tap is updated by a reusable Homebrew tap workflow that the release calls. Run it by hand to re-sync the tap, or as a dry run to check that HOMEBREW_TAP_TOKEN can still push. Release notes include the brew install line.

Install

brew install onushq/tap/onus
curl -fsSL https://onushq.com/install.sh | sh

Or in a workflow: uses: onushq/onus/action@v0.3.0. Each archive is attested: gh attestation verify <archive> --repo onushq/onus.