5333 Commits

Author SHA1 Message Date
Bo 3842ea0e00 docs: make README onboarding practical for Claude and Codex (#1145)
## What changed

Put Claude Code and Codex plugin installation and a complete first
research task near the top of the README. Define skills in plain
language, show the runtime-specific prompts and expected answer, and add
a short task-to-skill menu.

Clarify when the optional CLI is needed, keep the exact dependency table
in a collapsible section, and bring upgrade commands and 3.7 migration
guidance together. Advanced architecture and factory material links to
its canonical documentation. Contribution policy is preserved.

## Validation

- Documentation links, metadata counts, and release-message checks
passed.
- All 44 product-boundary/runtime-requirements Bats checks passed.
- Default local aggregate: 10 passes, zero failures, one optional
missing OL-suite skip.
- All 13 applicable AO gates passed; generated projections are current.
- GitHub GFM renders both prompt examples and the collapsed dependency
table; self-links match headings/anchors.
- Fresh independent source/readability review passed for commit
`db3e06a6bafb71696327ef20d5401e660c10692f`, covering the complete README
and all acceptance criteria.
- The full strict documentation-site check reported 99 warnings in
unchanged site pages (73 outside its allowlist). A clean
release-baseline build fails with the identical warning multiset; the
README adds zero warnings and is not a site-build input. This existing
site issue is recorded separately. No gate or allowlist was weakened.
2026-09-13 21:50:50 -04:00
Bo 20f9d4a338 Release AgentOps 3.7.0 (#1144)
## What

Release the prepared AgentOps update as **3.7.0**, the minor release
after 3.6.0. Align the CLI and plugin versions, regenerate the Gemini
manifest, and rename/update the curated notes and changelog links.

## Why

The operator selected a minor release. No 4.0.0 tag or release was
published. Migration instructions and the documented removed
commands/skills remain accurate.

## How I tested

- Go lint and focused version/manifest tests passed.
- Full regeneration parity, changelog mirror parity, and release-note
coverage from v3.6.0 passed.
- The exact 3.7.0 release rehearsal passed in 143 seconds; all 73 full
repository gates passed. All 12 security tools ran with zero
missing/error tools, critical findings or security-high findings;
existing advisories remain reported.
- All nine hosted checks passed on
`092e1814b6cba46cd9ac1d797dab2a5c8c7c188c`, including Go race/shuffle
tests and 1,509 executed Bats passes (31 environment-dependent skips,
zero failures). A new CLI wiring regression confirms `ao version --json`
reports the build version.
- Actual fresh native Claude/Codex 3.7.0 installs and upgrades from
3.6.0 passed with exact 34-skill inventories. Existing implementation
validation from PR #1143 remains applicable to unchanged source.
- Fresh author-distinct correction review passed for exact head
`092e1814b6cba46cd9ac1d797dab2a5c8c7c188c`, covering all changed paths
and four acceptance criteria with no unchecked scope. Verdict digest:
`e7b24a297a0b232138de011473df8be6eb3eeaf47afd1f300398eecafab2fbab`.

## Checklist

- [x] Version owners and generated metadata agree on 3.7.0.
- [x] Migration/removal guidance is preserved.
- [x] Exact-candidate release checks pass before tagging.
- [x] Fresh correction review is recorded before tagging.
v3.7.0
2026-09-13 20:28:12 -04:00
Bo d972fa2090 Prepare AgentOps 4.0.0 plugins, skills and CLI release (#1143)
## What

Prepare AgentOps 4.0.0 across the Claude plugin, Codex plugin, skills
and CLI. Claude writers capture the supplied check status during its
original invocation, and plugin conformance verifies exact skill
membership and link destinations. Full release security now scans the
repository and blocks on Python collection failures that previously
produced a false green result.

## Why

The 3.6.0-to-current interval removes published commands and 20 skill
names, so this is a major release with migration instructions. Release
validation also exposed stale skill assertions and test prerequisites
that need to match the current product contracts without weakening
acceptance.

## How I tested

- Native Claude Opus/Haiku success, failing-check and direct-writer
trials: each check ran once, and the direct child returned plain JSON.
- Actual fresh installs and upgrades from 3.6.0 in isolated Codex and
Claude homes: 34 skills, expected agents, and exact installed package
bytes.
- Exact candidate `b721d02559e1495be6095ad97b820e88ceb4a049`: all 73
full repository gates, regeneration parity, and the complete local
release rehearsal passed. All 12 security tools ran with zero skips,
tool errors, critical findings or high-severity security findings. The
unchanged advisory policy reports 35 quality-high findings on unchanged
files.
- Python: 327 tests and 72 subtests passed. Hosted Bats: 1,509 passed,
31 environment-dependent skips, zero failures. Go
lint/build/vet/race/shuffle checks and CLI smoke/integration passed.
- All 11 hosted checks passed, including Windows correctness,
macOS/Linux installation, security, and the six-target no-publish
GoReleaser snapshot. Local archive checksums and a real macOS CLI
initialization/status/version smoke also passed.
- Fresh author-distinct review passed all four acceptance criteria and
all 35 changed paths with no unchecked acceptance. Canonical subject and
caller-intent verification passed; verdict digest
`68af2c935ed0106cd91b3950f5d168e662f4071f660fcbd113c36b7cd0f0426e` binds
manifest
`7affc77e25eaff69ba36c5ce05582b4f0385c954b76b62c02b97f97041f489b2`.

## Checklist

- [x] Breaking changes documented in the migration guide and complete
release notes.
- [x] No credentials or private runtime proof included.
- [x] Final full release checks pass on the exact candidate.
- [x] Fresh author-distinct final PASS is recorded before merge.

This prepares the release candidate; it does not publish a tag or
release.

Coverage limits remain explicit: native plugin tests used isolated macOS
homes and local marketplaces, guard installation remains opt-in, and
reader instructions do not prove sandbox confinement. Semgrep retains
pre-existing warning-level parser diagnostics. Snapshot metadata follows
the existing 3.6.0 tag; this is a packaging rehearsal, not a published
4.0.0 archive.
2026-09-13 17:21:16 -04:00
Bo 86cdae4f3a Fix native Codex role registration paths (#1142)
A normal Codex session found both project role registrations but could
not spawn either: native role loading rejected the symlink-backed
configuration files with `Too many levels of symbolic links`.

Point each registration directly at its canonical regular TOML source.
Keep the role instructions and model pins in their existing owner files.
Strengthen the registration regression test so `.resolve()` cannot hide
this failure again.

Validation: six focused role tests pass; projection regeneration check
passes; `tests/run-all.sh` passes (10 passed, one unavailable optional
OL integration suite skipped). A fresh interactive Codex session,
without role or model overrides, launched both Luna roles; the reader
returned three line-referenced decisions covering 1,203 lines, and the
writer returned a successful one-file test receipt. Fresh independent
transcript review passed all supplied smoke criteria, including exactly
one writer check, receipt isolation, missing-reference refusal without
writes, and the live hook denying two oversized reads while allowing a
bounded read. The reader inherited the parent’s workspace-write sandbox
as documented; this run proves bounded behavior, not enforced read-only
access.
2026-09-13 05:55:53 +00:00
Bo 937d6c8269 Add native Codex context-budget delegation and opt-in refusal (#1140)
## What

Add Codex-native `bulk-reader` and `code-writer` roles pinned to
`gpt-5.6-luna`, opt-in role/config installation, and an opt-in native
`PreToolUse` Bash adapter for the shared read-budget guard. Source-owned
guidance and role files ship through the existing generated Codex
bundle; the menu stays at 34 skills.

The installed Codex 0.154 runtime can refuse covered shell calls before
execution. The adapter enforces that predicate; slice discipline,
target-only writes and receipt-only replies are role instructions, not
an output filter or per-file sandbox. Native exact-definition hook trust
remains required.

## Why

Follow-up to #1137 and its [fresh author-distinct
review](https://github.com/boshu2/agentops/pull/1137#issuecomment-5648513520).
Correct the unverified statement that Codex has no refusal-capable hooks
and provide real native delegation without subprocess model execution.

This branch incorporates the isolated fixes in #1139 and targets main;
land the repairs first. The fixes PR contains no Codex-native changes.
Work and original acceptance are recorded in private BD `age-z25n`; `bd
context --json` resolves the existing private Dolt store.

[Design and live
evidence](https://github.com/boshu2/agentops/blob/codex/context-budget-native/docs/design/codex-context-budget.md)
records the runtime/config contracts, exact available model identifiers
and published comparable rates, source paths, invocation, transcripts,
accounting and limits.

## How I tested

Current head: `40edb5f216b71bfa659627dca10fc0a9e04c1821`. Fresh
author-distinct review: **Job2 native PASS; combined subject FAIL**.
Reviewer context `01a09778-bef6-7883-880b-6764fdd783b9`, observed
`gpt-6-astra`/ultra, authored no candidate code. All 52 changed paths
have identical start/end manifests (SHA-256
`b1f13ca731658bc699838189f928535a386ab6de6b381b0419bb0f7ebdd88cdc`);
acceptance `not_checked: []`. The native repeated-refusal naming finding
is fixed and independently reproduced as resolved. Local final checks
pass. [Hosted Validate
CI](https://github.com/boshu2/agentops/actions/runs/34722978404) remains
pending at this update; no merge is performed.

Real Claude Opus follow-up closes plugin-name resolution, inherited hook
invocation, complete reader coverage and observed parent/child content
separation. **It also finds a remaining Claude writer failure:** two of
three final workers ran their supplied check twice; a direct receipt
used Markdown fences. This combined PR does not claim a full Claude
writer PASS. Details, excluded failed attempts and exact identities are
in the design note.

- `./cli/bin/ao gate check --scope range:origin/main..HEAD`: 33 passed;
the earlier unchanged registry run `./cli/bin/ao gate check --full`
passed **73 gates** at `90c8b31ee` (historical receipt). `bash
scripts/regen-all.sh --check`: all 11 checks passed.
- Door9, hookless cold-start, doc-hook drift, shellcheck on five changed
shell files, and Node syntax checks on both workflows plus the native
config editor passed.
- A7 Bats suites plus workflow and all native suites: **223 passed, zero
skipped**. All **21 documentation-reference tests** and the strict
full-document reference scan also pass after clarifying the native
hook-manager terminology.
- `bash tests/run-all.sh`: **10 passed, 0 failed, 1 skipped** (optional
OL directory absent). This is the default static tier.
- `bash scripts/validate-codex-install-bundle.sh`: passed, **34 skill
packages**. Changelogs are identical; diff check clean.
- Live registered reader: parent `01a09776-004f-79a0-af85-c75b472a1e68`
used only spawn/wait; child `01a09776-3c38-7281-b582-01fef5101f17` was
natively identified as bulk-reader/Luna/low. Six separate slices covered
1,772 lines without truncation; parent received five findings and
coverage only.
- Live registered writer: parent `01a09771-8908-7a00-b101-919b558cf8c1`
used only spawn/wait; child `01a09771-bbbf-7232-add4-cc9ec55ad759` was
code-writer/Luna/medium. Required reference, seven-line Bats target,
receipt only, child check passed; coordinating parent independently ran
Bats successfully without reading the target.
- Live hook: native parent `01a09769-14d2-7c22-9b7d-50847de07c90`, final
turn `01a09771-25f2-7830-830b-498d7ca1945e`, refused a 400-line cat
before execution and allowed a three-line sed slice. Real payload is
PreToolUse/Bash/tool_input.command; hashed deny ledger schema verified.
An explicit session hook was trusted in `/hooks` for this proof.
- Credentials-free native config/read and hooks/list probes verify
personal and ordinary project discovery. Codex 0.154 reads
linked-worktree project hooks from the primary checkout; `--project` now
rejects linked worktrees before writing, with a real Git regression.

Known failed: Claude writer check-once behavior and direct receipt
fencing.

Not checked: arbitrary hosted/MCP read interception; adversarial
enforcement of role instructions; other runtime versions/accounts; cost
savings, comparative latency or ADR-0002 value-proof clearance. Earlier
reader attempts with an overlarge final slice or truncated aggregate
output are disclosed and excluded from the successful coverage proof.

## Checklist

- [x] `make build && make test` passes (if Go changes) — no Go changes;
gate runner built once.
- [x] No secrets or credentials in code
- [x] Breaking changes documented — opt-in additions; unsupported
linked-worktree hook installation refuses before mutation.
2026-09-13 05:37:17 +00:00
Bo a3d6018f2c Fix read-budget refusals, installer backups and workflow boundaries (#1139)
## What

Repair the opt-in read-budget guard, installer and Claude workflows from
#1137. The fixes cover conservative literal shell parsing, preserved
installer backups, bounded worker returns, distinct filesystem targets,
actual plugin-qualified names, complete reader coverage, exact receipt
identity and measured writer line counts.

## Why

The [fresh review of
e32e88c](https://github.com/boshu2/agentops/pull/1137#issuecomment-5648513520)
found major guard, installer and workflow defects. Subsequent real
Claude Opus sessions closed the previously untested name-resolution,
hook-inheritance and reader-context gaps and exposed further writer
defects.

This is the Claude repair branch. The separately requested Codex
implementation and correction of the old Codex/no-PreToolUse paragraph
are in #1140, which incorporates these fixes.

## How I tested

Exact head: `53bcfec1480c205290f286b4a7ccd582216eb6f9`. Fresh
author-distinct review is **FAIL overall**: A1–A5 and A7 pass, while A6
fails on the retained Codex premise assigned to #1140. Reviewer context
`01a097b8-b07c-7542-8a5a-5857fab3d069` was dispatched without inherited
history and authored no candidate code. All 31 changed paths have
identical start/end manifests (SHA-256
`ca3f3ed77038cea39cff609a02b2c2cf97356d481b70a22252939d54dc0a89c2`);
acceptance `not_checked: []`, because the failing surfaces were checked.
The reviewer also independently ran 58 guard shapes and preserved the
repeated-check defect.

[Hosted CI](https://github.com/boshu2/agentops/actions/runs/34722743295)
is green at this exact head (all eight checks succeeded). This does not
clear the observed model behavior failure.

All required A7 checks pass: 33 selected gates, 197 Bats tests, 11
projection checks, Door9, hookless cold-start, doc-hook drift,
shellcheck, workflow syntax, identical changelogs and clean diff checks.
No Go source changed. New regressions failed before their repairs and
passed afterward.

Native Claude 2.1.263 resolved requested Opus to `claude-opus-5`; plugin
children used `claude-haiku-4-5-20251001`. Sessions used explicit
fixture permissions, finite wall/output bounds and private native
transcripts.

- Real hook calls refused oversized Read/Bash calls, allowed a slice,
and wrote one hashed record per refusal. Actual child agent/tool IDs
prove hook inheritance.
- Parent `e075d6ee-5e6c-4a9a-bced-f8b04c8c62b1`: direct reader and
native Workflow each covered all 1,105 fixture lines with correct refs
10, 560, 1095. Independent transcript comparison confirms coverage, no
parent file dump and truthful missing-file results. Registered names
require the `agentops:` prefix.
- Parent `4b97e6e7-8620-4319-b94e-a10216cccddc`: two Workflow writers
and one direct writer created only assigned targets, returned accurate
seven-line receipts, and passed independent Bats checks. Native parent
received no complete child write payload or raw check output. Hard-link
aliases, literal duplicate targets and missing references were rejected
before writers started.

**Known live failure remains:** two of those three final workers ran the
supplied check twice despite the ONCE instruction. The direct agent also
fenced its metadata JSON despite the plain-JSON instruction. These are
preserved observed failures, not unchecked scenarios; this PR does not
claim complete one-shot Claude writer readiness. Earlier failed attempts
are retained and excluded from clean proof.

Target-only writes, check-once behavior and content-free direct-agent
replies are model instructions, not a filesystem sandbox or output
filter. No ADR-0002 value-proof clearance, savings percentage or latency
claim. Other runtime versions/accounts and adversarial enforcement of
advisory behavior were not tested.

## Checklist

- [x] `make build && make test` passes (if Go changes) — no Go changes;
gate runner built once.
- [x] No secrets or credentials in code
- [x] Breaking changes documented — ambiguous missing batch paths fail
before writers start; use separate calls.
2026-09-13 05:29:36 +00:00
renovate[bot] 269edb6687 chore(deps): update anthropics/claude-code-action digest to 9cdae7f (#1141)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/56cf60fde42f7b19c3abfd5c9c48b69a1288461f..9cdae7f0d995e3ba7c33f226087fdf82a59cd520))
| action | digest | `56cf60f` → `9cdae7f` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-12 22:12:17 +00:00
renovate[bot] e5cef93efb chore(deps): update anthropics/claude-code-action digest to 56cf60f (#1138)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/19dda84776b3518d98b8798e591daee763049ed3..56cf60fde42f7b19c3abfd5c9c48b69a1288461f))
| action | digest | `19dda84` → `56cf60f` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-12 19:58:38 +00:00
renovate[bot] e8122695a5 chore(deps): update dependency python to 3.14 (#1127)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [python](https://redirect.github.com/actions/python-versions) |
uses-with | minor | `3.12` → `3.14` |

---

### Release Notes

<details>
<summary>actions/python-versions (python)</summary>

###
[`v3.14.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.7-31064857500):
3.14.7

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.6-27283001424...3.14.7-31064857500)

Python 3.14.7

###
[`v3.14.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.6-27283001424):
3.14.6

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.5-25647354415...3.14.6-27283001424)

Python 3.14.6

###
[`v3.14.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.5-25647354415):
3.14.5

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.4-25113653268...3.14.5-25647354415)

Python 3.14.5

###
[`v3.14.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.4-25113653268):
3.14.4

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.3-21673711214...3.14.4-25113653268)

Python 3.14.4

###
[`v3.14.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.3-21673711214):
3.14.3

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.2-20014991423...3.14.3-21673711214)

Python 3.14.3

###
[`v3.14.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.2-20014991423):
3.14.2

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.1-19879739908...3.14.2-20014991423)

Python 3.14.2

###
[`v3.14.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.1-19879739908):
3.14.1

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.14.0-18313368925...3.14.1-19879739908)

Python 3.14.1

###
[`v3.14.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.14.0-18313368925):
3.14.0

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.15-31064747964...3.14.0-18313368925)

Python 3.14.0

###
[`v3.13.15`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.15-31064747964):
3.13.15

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.14-27320626148...3.13.15-31064747964)

Python 3.13.15

###
[`v3.13.14`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.14-27320626148):
3.13.14

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.13-27225391538...3.13.14-27320626148)

Python 3.13.14

###
[`v3.13.13`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.13-27225391538):
3.13.13

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.12-21673645133...3.13.13-27225391538)

Python 3.13.13

###
[`v3.13.12`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.12-21673645133):
3.13.12

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.11-20014977833...3.13.12-21673645133)

Python 3.13.12

###
[`v3.13.11`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.11-20014977833):
3.13.11

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.10-19879712315...3.13.11-20014977833)

Python 3.13.11

###
[`v3.13.10`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.10-19879712315):
3.13.10

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.9-18515951191...3.13.10-19879712315)

Python 3.13.10

###
[`v3.13.9`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.9-18515951191):
3.13.9

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.8-18331000654...3.13.9-18515951191)

Python 3.13.9

###
[`v3.13.8`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.8-18331000654):
3.13.8

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.7-16980743123...3.13.8-18331000654)

Python 3.13.8

###
[`v3.13.7`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.7-16980743123):
3.13.7

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.6-16792117939...3.13.7-16980743123)

Python 3.13.7

###
[`v3.13.6`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.6-16792117939):
3.13.6

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.5-15601068749...3.13.6-16792117939)

Python 3.13.6

###
[`v3.13.5`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.5-15601068749):
3.13.5

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.4-15433317575...3.13.5-15601068749)

Python 3.13.5

###
[`v3.13.4`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.4-15433317575):
3.13.4

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.3-14344076652...3.13.4-15433317575)

Python 3.13.4

###
[`v3.13.3`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.3-14344076652):
3.13.3

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.2-13708744326...3.13.3-14344076652)

Python 3.13.3

###
[`v3.13.2`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.2-13708744326):
3.13.2

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.1-13437882550...3.13.2-13708744326)

Python 3.13.2

###
[`v3.13.1`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.1-13437882550):
3.13.1

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.13.0-13707372259...3.13.1-13437882550)

Python 3.13.1

###
[`v3.13.0`](https://redirect.github.com/actions/python-versions/releases/tag/3.13.0-13707372259):
3.13.0

[Compare
Source](https://redirect.github.com/actions/python-versions/compare/3.12.14-31661455385...3.13.0-13707372259)

Python 3.13.0

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Disabled because a matching PR was automerged
previously.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

## Compatibility repair

Python 3.14 requires compatible published wheels. This branch includes
the merged NumPy 2.5.3 and SciPy 1.18.1 updates, resolves the resulting
overlap and removes the stale Python 3.12/3.13-only comment. Against
current main, only the Python version and that comment change.

Validation at `6ee7477a988a7f17f34b446c5c9ae98c810228a6`:

- Isolated Python 3.14.6 wheel-only installation of both evaluator
requirement files succeeded.
- 9 receipt tests, 13 taskbank verifier tests and all 23 calibration
controls passed. All 88 final readout/statistics tests passed.
- Independent final source and compatibility review passed with no
findings.
- All seven GitHub checks passed, including Linux and Windows
correctness, security and gate checks.

The branch is current with main and ready to merge.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Bo <boden.fuller@gmail.com>
2026-09-12 19:49:34 +00:00
Bo e32e88c338 Add opt-in read-budget guard and cheap-model bulk-read/code-write delegation (#1137)
Bring the Spotify Claude Code context-budget setup into AgentOps as one
opt-in PreToolUse guard (skills/cc-hooks/hooks/read-budget-guard.sh, policy
core.context:unbounded-read) with its opt-in installer, two Workflow-tool
conveyors (bulk-read, code-write), two plugin subagents (bulk-reader,
code-writer), their docs, regenerated projections, and three bats suites.
Nothing ships wired by default; the skill menu is unchanged.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H2bDH2j6XDPPcLQS84PdzN
2026-09-12 12:58:20 -04:00
renovate[bot] 6e63d64caa chore(deps): update dependency harbor to v0.23.0 (#1136)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| harbor | `==0.22.0` → `==0.23.0` |
![age](https://developer.mend.io/api/mc/badges/age/pypi/harbor/0.23.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/harbor/0.22.0/0.23.0?slim=true)
|

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-12 05:23:45 +00:00
Bo e6a1b0f54e Clarify retrospective timing and reduce coordinator overhead (#1135)
When a request includes coding and a retrospective, the retrospective
can accidentally become a prerequisite for the code judgment it needs to
analyze. Clarify the existing Plan, Validate, Postmortem and optional
goal guidance so code acceptance, delivery facts and requested analysis
have distinct consumers. Overall completion still requires every
requested deliverable; explicitly requested interim analysis states its
cutoff and pending checks.

Tighten the existing coordination guidance: pass focused context, assign
integration and review ownership, act on a known blocking CI failure
before the entire run ends, and use native waits for unchanged pending
state. Skill Eval now explicitly distinguishes following an instruction
from proving benefit, and fresh context from small input. Preserve
BDD/DDD, required independent judgment, caller authority and protected
evidence storage. AGENTS.md stays within its existing 250-line limit; no
skills, controllers or gates are added.

Validation: exact-head CI passed, all 28 selected gates passed, and all
50 root/product-boundary tests passed. The local aggregate passed with
its existing absent legacy-integration skip. Fresh independent review
returned PASS over all 37 changed paths with no findings or unchecked
candidate criteria, including current generated parity. Earlier trigger,
description-budget and terminology failures were repaired without
changing tests or limits. Static checks and document review establish
contract consistency, not measured model uplift or token savings.
2026-09-11 17:59:34 -04:00
Bo 66323acc64 fix: protect session mining and ground skill feedback in evidence (#1134)
Session mining could overwrite its source when the checkpoint referred
to the same file, consume pending events during `--dry-run`, and miss
native Codex custom-tool input edits when checking for transcript
rewrites. The CLI now rejects source/checkpoint aliases before output or
writes, previews from the current watermark without persisting it, and
preserves native custom input so edits invalidate the checkpoint.
Regression controls retain normal incremental mining and legacy argument
handling.

Postmortem now accepts real goal/session evidence without requiring a
fabricated verdict file, uses current Memory ownership and protected
external storage, and separates structural checks from causal support.
Implement guidance emphasizes early representative checks and exact
repair verification. The Go standard and its local rule now point to the
actual CI complexity gate and explain its committed-file scope. Normal
projections are regenerated; no skill roots, framework or gate
thresholds were added or weakened.

The bounded evaluation used three useful coding tasks with fixed
behavior acceptance. Trial two exposed a real workflow defect: lint and
fast checks passed while CI rejected complexity 25. Checkpoint
construction was extracted, reducing MineSession to 20, and the Go
guidance was corrected before the third task. The failed attempt stays
in the evidence; this is an observational result, not proof of token
savings or superiority over native prompting. Final local Go
build/vet/test, lint, strict whole-campaign complexity and 37 selected
gates pass. [CI run
34628874411](https://github.com/boshu2/agentops/actions/runs/34628874411)
is green on `62205367e91946f84723147763662ca39ad4b580`, including Linux
race/shuffle tests, Windows, Bats and security. The independent review
checked all 27 changed paths and returned PASS with no unresolved
findings or unchecked acceptance; its earlier complexity FAIL remains
preserved. The local aggregate retains its existing skip for the absent
legacy OL test directory.
2026-09-11 17:35:50 -04:00
Bo c6558508d1 Consolidate AgentOps into a 34-skill engineering menu (#1133)
AgentOps' 55-skill catalog contained overlapping entry points, stale
routes and descriptions that could lose meaningful guidance in the Codex
projection. This change consolidates 21 roots into existing owners,
leaving 34 distinct skills and a generated, task-oriented menu. README
documents every retired name and its replacement.

Planning now establishes observable behavior in the caller's existing
intent, using proportional Given/When/Then examples and domain language.
Implementation and final validation carry those same examples forward.
Original adaptations informed by Matt Pocock's engineering skills
strengthen existing owners rather than adding a new workflow. Routine
edits need no mandatory plan, coverage report, mutation exercise or
learning artifact.

Codex retains complete source descriptions and translates explicit-only
invocation policy. All descriptions fit the existing 180-character
limit; the root instructions retain their 250-line limit. Generated
catalogs, projections, routers, moved references/helpers and their live
consumers are updated together. RPI remains explicitly selected.

Validation passed: projection/conformance checks, the local aggregate
(10 passed; one existing optional-directory skip), and exact-commit CI
covering the complete gate registry, Bats, Go build/vet/race/coverage,
Windows and security. A fresh author-distinct reviewer passed all
acceptance criteria over the complete 573-path subject at
aa642a55d6, including the installed-link
and protected-backup changes. Review findings were repaired and
revalidated. Existing ranker goldens are regression checks, not
model-quality measurements. A fixed six-case fresh-context pilot
supplied an exact candidate menu: three of four targeted cases loaded
expected guidance, a simple refactor selected no skill, and both
no-skill controls selected none. No wrong owner was selected. This pilot
preceded final wording repairs for existing ranker/context limits; it
does not establish installed automatic activation, coding benefit or
savings. No live coding task was run in that pilot.
2026-09-10 22:18:05 -04:00
Bo fba70c8d18 Keep skill reviews compact and clarify when judgment is finished (#1132)
The preceding implementation caught a real defect through fresh review,
but its review report duplicated scope and digest inventories and
closeout waited for a second report after merge. Most of that overhead
contradicted existing guidance; this change clarifies the ambiguous
parts in two existing skills.

Validate now allows a concise report referencing the complete bound
manifest and receipts, while retaining full inspection, every criterion,
findings, identity, freshness and unchecked scope. It distinguishes
candidate judgment from native delivery facts without allowing early
PASS when delivery belongs to accepted review scope. RPI uses native
completion watches or bounded waits and checks the expected subject and
required results before treating completion as success.

Generated companions are regenerated. No new skills, gates, schemas or
workflow machinery. These are narrow guidance corrections; later use
must demonstrate any reduction in wasted effort.

Validation: both existing skill validators pass; aggregate: 10 passed /
0 failed with the existing absent OL integration suite skipped; all 73
selected full gates pass; generated projections are current; exact-head
CI passed all 6 jobs. Fresh author-distinct review passed the complete
nine-path subject with no findings and empty unchecked scope. No new
phrase-matching tests were added for this documentation change.
2026-09-10 19:01:43 -04:00
Bo 4f5fd6301c Use CASS and MS for evidence-led instruction improvement (#1131)
## What

Use CASS to discover session evidence and MS to find existing skill
guidance. Reserve AO exact excerpts for an identified source-precision
gap. Correct guidance and helpers that treated repetition as success,
inferred user prompts from early line numbers, or refreshed the index
before every search.

Repeated failed prompts now remain unassessed. Native message roles
identify user prompts, search helpers preserve unavailable reads, and
recovery requires observed state before attempting repairs. Existing
CASS/MS documentation explains their respective roles without adding
another mining framework.

## Validation

- Seven focused helper behavior tests and CASS/MS skill validators pass.
- Generated projections are current. The local aggregate passed 10
groups with no failures; its absent OL integration suite was explicitly
skipped. Full AO gates passed all 73 selected checks.
- Fresh independent review caught an incomplete-status recovery edge
case. The repair, regression test, and generated copies have been
rechecked with no remaining findings; final local checks pass.
- CI passed on the exact final commit, including Linux/Windows
correctness, Go race tests, security and the required summary check.
- A bounded private exercise used three CASS query families and MS
search/full loads. It reached a justified no-change decision because
selected native sources were unavailable or did not match returned
locations. Retrieval success was not credited as learning, and no AO
extraction was needed. No private session content or locators are
included in this PR.

## Limits

This establishes retrieval and evidence-handling behavior. It does not
establish that a new instruction improves later task outcomes. The CASS
artifact validator deliberately skipped its opt-in live corpus smoke
test; the separately bounded retrieval exercise is described above.
2026-09-10 18:14:35 -04:00
Bo 36b3c00ad7 Extract bounded session evidence for instruction improvement (#1130)
## What

Extend `ao provenance mine-session` with `--view excerpts` and an
explicit instruction target. Native agents can inspect bounded
Codex/Claude records with literal text, JSON field pointers, exact byte
spans and SHA-256 identities, then propose a supported skill, AGENTS.md
or task-prompt edit. Existing event JSONL and checkpoint behavior stay
the default.

## Why

Instruction improvement needs precise session evidence. The existing
normalized parser truncates long text and does not provide bounded,
directly citable extraction. This view supplies the deterministic
reading step; native agents retain interpretation and review.

## How I tested

- Focused application and command regressions passed, including legacy
checkpoints, native message/tool forms, long Unicode text, malformed
data, continuation, limits and writer errors.
- Source-built AO extracted nine selected records from real AgentOps
sessions. All selected range hashes matched; analysis produced one
candidate prompt clarification and one justified no-change finding.
Private source material and proposals remain outside Git. This
demonstrates usability, not causal uplift.
- Go build/vet/race-shuffle passed. Full gates: 73/73 passed, including
lint. Aggregate: 10 passed, one optional absence. Generated projections
passed. All seven GitHub checks passed at
`31c128015a2e48a2a787b165e02966938381cf65`, including Linux, Windows and
security.
- A fresh author-distinct reviewer verified all eight changed paths,
exact source ranges and targets, the private proposal/no-change support,
and the clean-commit demo binary; no implementation or support findings.

The command reads explicit authorized files and writes JSON to stdout.
It runs no model, creates no index or checkpoint in excerpt mode, and
automatically edits or publishes nothing. It does not enforce
restricted-source isolation or redact output.

## Checklist

- [x] Required Go build, vet and tests pass
- [x] No private session content or credentials added to this diff
- [x] Existing event interface preserved; new flags documented
2026-09-10 17:25:45 -04:00
Bo 3213afcf1c Default to native execution and report independently accepted work (#1129)
## Change

Make native coding-agent execution the default AgentOps entry path with
zero mandatory skills. Preserve full bundles and add repeatable `ao
skills link --skill NAME` selection, validating the entire selection
before writes. Align product, installation, architecture and generated
command documentation.

Extend the existing trial readout to separate endpoint test results,
execution state and independently accepted work. Bind supplied judgments
to exact content, acceptance and native evidence. Reject empty
implementation subjects and require the caller's complete criterion ID
set before reporting acceptance. Preserve genuine nonempty and
deletion-only subjects, valid failures and missing-proof outcomes.

## Validation

- Native onboarding from empty home/consumer directories produces no
setup files; selective/full linking and failure boundaries are covered.
- Actual RED/GREEN regressions cover empty subjects and the
partial-criterion omission found by independent review.
- Full Go build, vet and race/shuffle tests; affected Go lint; 88 Python
readout/statistics tests passed.
- All 73 gates, generated projections, strict documentation build and
local aggregate passed (10 passed; one documented optional absence).
- All nine PR checks succeeded at
`7df0d42b12f35ffc22008cc10a40339afcfbb6a0`.
- Fresh author-distinct review passed all six acceptance criteria over
all 59 changed paths, with no findings or unchecked scope, after
repairing the criterion-coverage finding.

## Evidence limits

The real native coding repair demonstrates usability, not comparative
skill uplift. The strict live-session machine replay remains NOT_PROVEN
where execution/identity observations are unavailable; the source review
PASS is retained separately. Existing cohort limits and the historical
aggregate-enforcement gap remain unwaived. No new comparative cohort,
scheduler, skill-corpus deletion, memory migration or global
installation is included.
2026-09-10 20:28:22 +00:00
renovate[bot] ca6c86bc52 chore(deps): update dependency numpy to v2.5.3 (#1126)
> ℹ️ **Note**
> 
> This PR body was truncated due to platform limits.

This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [numpy](https://redirect.github.com/numpy/numpy)
([changelog](https://numpy.org/doc/stable/release)) | `==2.2.6` →
`==2.5.3` |
![age](https://developer.mend.io/api/mc/badges/age/pypi/numpy/2.5.3?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/numpy/2.2.6/2.5.3?slim=true)
|

---

### Release Notes

<details>
<summary>numpy/numpy (numpy)</summary>

###
[`v2.5.3`](https://redirect.github.com/numpy/numpy/compare/v2.5.2...v2.5.3)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.5.2...v2.5.3)

###
[`v2.5.2`](https://redirect.github.com/numpy/numpy/compare/v2.5.1...v2.5.2)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.5.1...v2.5.2)

###
[`v2.5.1`](https://redirect.github.com/numpy/numpy/compare/v2.5.0...v2.5.1)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.5.0...v2.5.1)

###
[`v2.5.0`](https://redirect.github.com/numpy/numpy/releases/tag/v2.5.0):
(June 21, 2026)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.6...v2.5.0)

### NumPy 2.5.0 Release Notes

Numpy 2.5.0 is a transitional release. It drops support for Python 3.11,
marking the end of distutils, and expires a large number of deprecations
made
in the 2.0.x release. It also improves free threading and brings sorting
into
compliance with the array-api standard with the addition of descending
sorts.
There is also a fair amount of preparation for Python 3.15, which will
be
supported starting with the first rc.

This release supports Python versions 3.12-3.14.

#### Highlights

- Distutils has been removed,
- Many expired deprecations, see below,
- Many new deprecations, see below,
- Many static typing improvements.
- Improved support for free threading,
- Support for descending sorts,

See New Features below for other additions.

#### Deprecations

- `numpy.char.chararray` is deprecated. Use an `ndarray` with a string
or bytes dtype instead.

  ([gh-30605](https://redirect.github.com/numpy/numpy/pull/30605))

- `numpy.take` now correctly checks if the result can be cast to the
provided
`out=out` under the same-kind rule. A `DeprecationWarning` is given now
  when this check fails. Previously, `take` incorrectly checked if `out`
could be cast to the result (the wrong direction). This deprecation also
affects `compress` and possibly other functions. (Future versions of
NumPy
  may tighten the casting check further.)

  ([gh-30615](https://redirect.github.com/numpy/numpy/pull/30615))

- The `numpy.char.[as]array` functions are deprecated. Use an
  `numpy.[as]array` with a string or bytes dtype instead.

  ([gh-30802](https://redirect.github.com/numpy/numpy/pull/30802))

- Setting the dtype attribute is deprecated because mutating an array is
unsafe
if an array is shared, especially by multiple threads. As an
alternative,
you can create a view with a new dtype via
`array.view(dtype=new_dtype)`.

  ([gh-29244](https://redirect.github.com/numpy/numpy/pull/29244))

- Setting the `shape` attribute is deprecated because mutating an array
is
  unsafe if an array is shared, especially by multiple threads. As an
  alternative, you can create a new view via `np.reshape` or
`np.ndarray.reshape`. For example: `x = np.arange(15); x = np.reshape(x,
(3, 5))`.
To ensure no copy is made from the data, one can use `np.reshape(...,
copy=False)`.

While setting the shape on an array is discouraged, for cases where it
is
difficult to work around, e.g., in `__array_finalize__`, it is possible
  with the private method `np.ndarray._set_shape`.

  ([gh-29536](https://redirect.github.com/numpy/numpy/pull/29536))

- Using the `generic` unit in `numpy.timedelta64` is deprecated since
this
  can lead to unexpected behavior such as non-transitive comparison, see
[gh-28287](https://redirect.github.com/numpy/numpy/issues/28287) for
details. As
an alternative, specify an explicit unit such as `'s'` (seconds) or
`'D'`
(days) when constructing `numpy.timedelta64`. Due to this change,
operations
  that implicitly rely on the `generic` unit are also deprecated. For
  example:

  ```
  arr = np.array([1, 2, 3], dtype="m8[s]")
  ```

### `1` is implicitly converted to generic timedelta64

```
  arr + 1
```

([gh-29619](https://redirect.github.com/numpy/numpy/pull/29619))

- Resizing a Numpy array in place is deprecated since mutating an array
is
  unsafe if an array is shared, especially by multiple threads. As an
  alternative, you can create a resized array via `np.resize`.

  ([gh-30181](https://redirect.github.com/numpy/numpy/pull/30181))

- `numpy.fix` is deprecated, use `numpy.trunc` instead. It is faster and
  follows the Array API standard. Both functions provide identical
  functionality: rounding array elements towards zero.

  ([gh-30644](https://redirect.github.com/numpy/numpy/pull/30644))

- `numpy.ma.round_` is deprecated. `numpy.ma.round` can be used as a
  replacement.

  ([gh-30738](https://redirect.github.com/numpy/numpy/pull/30738))

- `numpy.typename` is deprecated because the names returned by it were
  outdated and inconsistent. `numpy.dtype.name` can be used as a
  replacement.

  ([gh-30774](https://redirect.github.com/numpy/numpy/pull/30774))

- Inputs other than integers are deprecated for `numpy.triu_indices` and
  `numpy.tril_indices`. Non-integer values for the `M`, `k` and `N`
parameters of `numpy.tri` are deprecated. Non-integer values for the `k`
parameter of both `numpy.tril_indices_from` and
`numpy.triu_indices_from`
  are deprecated.

  ([gh-30869](https://redirect.github.com/numpy/numpy/pull/30869))

- Deprecations in custom `dtype` property and `__array_finalize__`.

  Previously `arr.view(dtype=new_dtype)` called `arr.dtype = new_dtype`
  also for subclasses, i.e., the attribute setting. That path is now
deprecated and refined, meaning that even subclasses that do not see
this
  `DeprecationWarning` may wish to update their code.

A subclass that does any `dtype` specific logic (i.e. verifying the
dtype
  in `__array_finalize__` or has a `dtype` property) should now:

  - Set `_set_dtype = None` in which case `arr.view(dtype=new_dtype)`
    will call `__array_finalize__` with the new dtype, ensuring that
    any validation `__array_finalize__` will run is done.
  - Or, for a quick fix, define `_set_dtype` as a function (calling
    `ndarray._set_dtype()` to avoid `DeprecationWarnings`.
(Future versions might migrate towards the `_set_dtype = None` path.)

Ideally, follow NumPy's deprecation to prevent `dtype` mutation by
users.
  The use of `ndarray._set_dtype()` may be necessary for some subclass
  finalization patterns, but should otherwise be avoided.

  ([gh-31293](https://redirect.github.com/numpy/numpy/pull/31293))

#### Expired deprecations

- `numpy.distutils` has been removed

  ([gh-30340](https://redirect.github.com/numpy/numpy/pull/30340))

- Passing `None` as dtype to `np.finfo` will now raise a `TypeError`
  (deprecated since 1.25)

  ([gh-30460](https://redirect.github.com/numpy/numpy/pull/30460))

- `numpy.cross` no longer supports 2-dimensional vectors.
  (Deprecated since 2.0)

  ([gh-30461](https://redirect.github.com/numpy/numpy/pull/30461))

- `numpy._core.numerictypes.maximum_sctype` has been removed.
  (deprecated since 2.0)

  ([gh-30462](https://redirect.github.com/numpy/numpy/pull/30462))

- `numpy.row_stack` has been removed in favor of `numpy.vstack`.
  (deprecated since 2.0)

  ([gh-30463](https://redirect.github.com/numpy/numpy/pull/30463))

- `get_array_wrap` has been removed.
  (deprecated since 2.0)

  ([gh-30463](https://redirect.github.com/numpy/numpy/pull/30463))

- `recfromtxt` and `recfromcsv` have been removed from
`numpy.lib._npyio`
  in favor of `numpy.genfromtxt`.
  (deprecated since 2.0)

  ([gh-30467](https://redirect.github.com/numpy/numpy/pull/30467))

- The `numpy.chararray` re-export of `numpy.char.chararray` has been
removed.
  (deprecated since 2.0)

  ([gh-30604](https://redirect.github.com/numpy/numpy/pull/30604))

- `bincount` now raises a `TypeError` for non-integer inputs.
  (deprecated since 2.1)

  ([gh-30610](https://redirect.github.com/numpy/numpy/pull/30610))

- The `numpy.lib.math` alias for the standard library `math` module has
  been removed.
  (deprecated since 1.25)

  ([gh-30612](https://redirect.github.com/numpy/numpy/pull/30612))

- Data type alias `'a'` was removed in favor of `'S'`.
  (deprecated since 2.0)

  ([gh-30613](https://redirect.github.com/numpy/numpy/pull/30613))

- `_add_newdoc_ufunc(ufunc, newdoc)` has been removed in favor of
  `ufunc.__doc__ = newdoc`.
  (deprecated since 2.2)

  ([gh-30614](https://redirect.github.com/numpy/numpy/pull/30614))

#### Compatibility notes

##### `linalg.eig` and `linalg.eigvals` now always return complex arrays

Previously, the return values depended on whether the eigenvalues happen
to lie
on the real line (which, for a general, non-symmetric matrix, is not
guaranteed).

This change makes consistent what was a value-dependent result. To
retain the
previous behavior, do:

```
w = eigvals(a)
if np.any(w.imag == 0):  # this is what NumPy used to do
    w = w.real
```

If your matrix is symmetrix/hermitian, use `eigh` and `eigvalsh` instead
of
`eig` and `eigvals`. These are guaranteed to return real values. A
common
case is covariance matrices, which are symmetric and positive definite
by
construction.

([gh-30411](https://redirect.github.com/numpy/numpy/pull/30411))

##### MSVC support

NumPy now requires minimum MSVC 19.35 toolchain version on Windows
platforms.
This corresponds to Visual Studio 2022 version 17.5 Preview 2 or newer.

([gh-30489](https://redirect.github.com/numpy/numpy/pull/30489))

##### Cython support

NumPy's Cython headers (accessed via `cimport numpy`) now require Cython
3.0
or newer to build. If you try to compile a project that depends on
NumPy's
Cython headers using Cython 0.29 or older, you will see a message like
this:

```
Error compiling Cython file:
------------------------------------------------------------
...
```

### versions.

```

#
```

### See **init**.cython-30.pxd for the real Cython header

```

#

DEF err = int('Build aborted: the NumPy Cython headers require Cython 3.0.0 or newer.')
  ------------------------------------------------------------

  /path/to/site-packages/numpy/__init__.pxd:11:13: Error in compile-time expression:
  ValueError: invalid literal for int() with base 10: 
  'Build aborted: the NumPy Cython headers require Cython 3.0.0 or newer.'
```

Note that the invalid integer is not a bug in NumPy - we are
intentionally
generating this error to avoid triggering a more obscure error later in
the
build when an older Cython version tries to use a Cython feature that
was not
available in the old Cython version.

([gh-30770](https://redirect.github.com/numpy/numpy/pull/30770))

##### `numpy.where` no longer truncates Python integers

Previously, if the `x` or `y` argument of `numpy.where` was a Python
integer that was out of range of the output type, it would be silently
truncated. Now, an `OverflowError` will be raised instead.

This change also applies to the underlying C API function
`PyArray_Where`.

([gh-30803](https://redirect.github.com/numpy/numpy/pull/30803))

##### Default memory allocator change

NumPy now uses `PyMem_RawMalloc` and `PyMem_RawFree` as the default
memory
allocator, instead of system's `malloc` and `free` directly.

([gh-30846](https://redirect.github.com/numpy/numpy/pull/30846))

##### `from_dlpack` raises `BufferError` instead of `RuntimeError`

`np.from_dlpack` now raises `BufferError` instead of `RuntimeError` when
the incoming DLPack tensor has an unsupported device, dtype, or exceeds
the
maximum number of dimensions. This aligns with the DLPack and Array API
specifications, which recommend `BufferError` for data that cannot be
imported.

([gh-30937](https://redirect.github.com/numpy/numpy/pull/30937))

##### Corrections to the BTPE binomial sampler

Two independent errors in the Stirling series of the
acceptance/rejection step
of the BTPE algorithm used by `numpy.random.Generator.binomial` have
been
corrected:

- The third and fourth error terms were added rather than subtracted.
This sign
  error was inherited from section 5.3 of the original 1988 paper by
  Kachitvichyanukul & Schmeiser, which incorrectly adds all four terms.
- The leading coefficient had a digit-swap typo (`13680` instead of
  `13860`) that was introduced in the initial implementation.

As a result, `Generator.binomial` and `Generator.multinomial`, which
uses
binomial internally, may now return different samples for the same seed.

The legacy `numpy.random.RandomState.binomial` and
`numpy.random.RandomState.multinomial` are not affected: they preserve
the
original (incorrect) behavior, so existing streams remain reproducible.

([gh-31238](https://redirect.github.com/numpy/numpy/pull/31238))

##### `datetime64`/`timedelta64` arithmetic raises on overflow

Addition, subtraction, and integer multiplication of `datetime64` and
`timedelta64` values now raise `OverflowError` when the result would
overflow `int64` or land on the `NaT` sentinel value. Previously these
operations silently wrapped, often producing a value that was
indistinguishable
from `NaT`. This matches the overflow checking already performed by
unit-conversion casts.

([gh-31378](https://redirect.github.com/numpy/numpy/pull/31378))

#### C API changes

- It is now possible to register `"real"` and `"imag"` ArrayMethods via
  `PyUFunc_AddLoopsFromSpecs`. These will be used for `imag` and `real`
  and should normally set `*view_offset` in their `resolve_descriptors`
  function to allow the array attributes to return views.

  ([gh-30984](https://redirect.github.com/numpy/numpy/pull/30984))

- New `PyDataType_TYPE`, `PyDataType_KIND`, `PyDataType_BYTEORDER` and
`PyDataType_TYPEOBJ` accessor macros to the C API. Together with the
other
accessor macros added for the NumPy 2.0 transition, these allow
accessing the
  fields of `PyArray_Descr` structs without any direct field accesses.

  ([gh-30994](https://redirect.github.com/numpy/numpy/pull/30994))

- NumPy now supports the stable ABI for free-threaded Python as
described in
  `803`{.interpreted-text role="pep"}.

  ([gh-31091](https://redirect.github.com/numpy/numpy/pull/31091))

- `PyArray_DescrFromScalar` now returns the full dtype descriptor for
scalars
  of user-defined parametric data types, including any dtype parameters.
Parameters were previously silently discarded, which could cause
incorrect
  results in operations like `astype` on scalar objects. Internally, the
function now delegates to `discover_descr_from_pyobject`, which handles
  parametric dtypes correctly.

  ([gh-31067](https://redirect.github.com/numpy/numpy/pull/31067))

#### New Features

- It is now possible to register user-dtypes for dlpack export and
import
via `numpy.dtypes.register_dlpack_dtype`. This functionality is meant to
  be used with care by user-dtype authors.

  ([gh-31256](https://redirect.github.com/numpy/numpy/pull/31256))

##### Pixi package definitions

Pixi package definitions have been added for different kinds
of from-source builds of NumPy. These can be used in
downstream Pixi workspaces via the `pixi-build` feature.

Definitions for both `default` and AddressSanitizer-instrumented
(`asan`) builds are available in the source code under the
`pixi-packages/` directory.

`linux-64` and `osx-arm64` platforms are supported.

([gh-30381](https://redirect.github.com/numpy/numpy/pull/30381))

##### `numpy.ndarray` now supports structural pattern matching

`numpy.ndarray` and its subclasses now have the `Py_TPFLAGS_SEQUENCE`
flag
set, enabling structural pattern matching (PEP 634) with `match`/`case`
statements. This also enables Cython to optimize integer indexing
operations.
See `` `arrays.ndarray.pattern-matching ``{.interpreted-text
role="ref"}\` for details.

([gh-30653](https://redirect.github.com/numpy/numpy/pull/30653))

##### Added N-D evaluation functions to the polynomial package

New functions `polyvalnd`, `chebvalnd`, `legvalnd`, `hermvalnd`,
`hermevalnd`, and `lagvalnd` have been added to evaluate polynomials
in arbitrary dimensions, analogous to the existing 2D and 3D evaluators.

([gh-30857](https://redirect.github.com/numpy/numpy/pull/30857))

##### New "descending" keyword argument for `numpy.sort` and
`numpy.argsort`

Users can now pass the `descending=True` keyword argument to
`numpy.sort`
and `numpy.argsort` to sort and argsort arrays in descending order. NaN
values, if present, are sorted to the end of the array in both ascending
and
descending sorts. This feature is available for all built-in dtypes
except
`void`, `object`, and `generic`. Note that SIMD optimizations for
sorting
are currently not available for descending sorts, so performance may be
slower.

([gh-31345](https://redirect.github.com/numpy/numpy/pull/31345))

#### Improvements

For `f2py`, the behaviour of `intent(inplace)` has improved. Previously,
if an input array did not have the right dtype or order, the input array
was
modified in-place, changing its dtype and replacing its data by a
corrected
copy. Now, instead, the corrected copy is kept a separate array, which,
after
being passed and presumably modified by the fortran routine, is copied
back to
the input routine. The above means one no longer has the risk that
pre-existing views or slices of the input array start pointing to
unallocated
memory (at the price of increased overhead for the write-back copy at
the end
of the call).

A potential problem would be that one might get very different results
if one,
e.g., previously passed in an integer array where a double array was
expected:
the writeback to integer would likely give wrong results. To avoid such
situations, `intent(inplace)` will now only allow arrays that have
equivalent
type to that used in the fortran routine, i.e., `dtype.kind` is the
same. For
instance, a routine expecting double would be able to receive float, but
would
raise on integer input.

([gh-29929](https://redirect.github.com/numpy/numpy/pull/29929))

##### `f2py` modules now show allocatable arrays in `dir()`

Allocatable module variables wrapped by `f2py` now appear in `dir()`
output, matching their accessibility by name.

([gh-30965](https://redirect.github.com/numpy/numpy/pull/30965))

##### `StringDType` comparisons now correctly handle embedded NULL
bytes.

([gh-31662](https://redirect.github.com/numpy/numpy/pull/31662))

#### Performance improvements and changes

##### Improved performance of `numpy.searchsorted`

The C++ binary search implementation used by `numpy.searchsorted` now
has a
much better performance when searching for multiple keys. The new
implementation batches binary search steps across all keys to leverage
cache
locality and out-of-order execution. Benchmarks show the new
implementation can
be up to 20 times faster for hundreds of thousands keys while single-key
performance remains comparable to previous versions.

([gh-30517](https://redirect.github.com/numpy/numpy/pull/30517))

##### Improved scaling of ufuncs on free-threading

NumPy's ufuncs now scale significantly better on free-threading builds
of CPython due to the following optimizations:

- **Lock-free dispatch table:** The ufuncs dispatch table is now
implemented as
a lock-free concurrent hash map, allowing multiple threads to call
ufuncs
  without contention.
- **Immortal shared objects:** Certain shared objects, such as global
memory
  handlers, have been made immortal. This effectively reduces reference
  counting contention across threads.
- **Optimized memory allocation:** NumPy now utilizes `PyMem_RawMalloc`
and
  `PyMem_RawFree` for memory allocation. On Python 3.15 and newer, this
leverages `mimalloc` and significantly reduces memory allocation
overhead
  in multi-threaded workloads.

([gh-30846](https://redirect.github.com/numpy/numpy/pull/30846))

##### Faster reductions on small/medium contiguous arrays

`numpy.sum`, `numpy.prod`, `numpy.any`, `numpy.all`, and other
reductions with an identity value now use a fast path when the input is
a
contiguous, aligned, non-object array and the reduction covers all axes
(`axis=None`) with no special arguments. Typical speedup is \~1.3x on
small
arrays; `numpy.any` / `numpy.all` on contiguous boolean arrays can see
speedup up to 1.9x.

([gh-31274](https://redirect.github.com/numpy/numpy/pull/31274))

#### Typing improvements and changes

##### `numpy.linalg` typing improvements and preliminary shape-typing
support

Input and output dtypes for `numpy.linalg` functions are now more
precise.
Several of these functions also gain preliminary shape-typing support
while
remaining backward compatible. For example, the return type of
`numpy.linalg.matmul` now depends on the shape-type of its inputs, or
fall
back to the backward-compatible return type if the shape-types are
unknown at
type-checking time. Because of limitations in Python's type system and
current
type-checkers, shape-typing cannot cover every situation and is often
only
implemented for the most common lower-rank cases.

([gh-30480](https://redirect.github.com/numpy/numpy/pull/30480))

##### `numpy.ma` typing annotations

The `numpy.ma` module is now fully covered by typing annotations. This
includes annotations for masked arrays, masks, and various functions and
methods. With this, NumPy has achieved 100% typing coverage across all
its
submodules.

([gh-30566](https://redirect.github.com/numpy/numpy/pull/30566))

##### Shape-typing support for many functions and methods

Many functions and methods now have shape-aware return type annotations.
Type-checkers can now infer the number of dimensions of the returned
array
through common operations. For example, `np.linspace(0, 1)` is now typed
as a
1-d `float64` array, and `np.sum(x, keepdims=True)` has the same number
of
dimensions as `x`.

This covers `numpy.linalg` functions, array creation functions (like
`asarray`, `from{buffer,string,file,iter,regex}`), range functions
(`linspace`, `logspace`, `geomspace`), aggregation functions and methods
(`sum`, `mean`, `std`, `var`, `min`, `max`, `all`, `any`,
etc.), sorting (`sort`, `argsort`, `argpartition`), cumulative
operations
(`cumsum`, `cumprod`, etc.), set operations (`unique_values`,
`intersect1d`, `union1d`, etc.), and various other functions including
`nonzero`, `transpose`, `diagonal`, `atleast_{1,2,3}d`, `clip`,
`round`, `inner`, `bincount`, and `fft.fftfreq`. Several of these also
gained more precise return dtype annotations as part of this work.

Shape-typing is still a work-in-progress, so coverage is not yet
complete.
Because of limitations in Python's type system and current
type-checkers,
shape-typing is often only implemented for the most common lower-rank
cases.

([gh-31172](https://redirect.github.com/numpy/numpy/pull/31172))

##### `numpy.fft` typing improvements and preliminary shape-typing
support

The `numpy.fft` functions now support non-`float64`/`complex128` dtypes
and gain preliminary shape-typing support. For example, the return type
of
`numpy.fft.fft` now depends on the shape-type of its inputs, falling
back to
the backward-compatible return type when the shape-types are unknown at
type-checking time.

([gh-31226](https://redirect.github.com/numpy/numpy/pull/31226))

#### Changes

##### Structured array copies now use `memcpy` for contiguous dtypes

Copying structured arrays with identical dtypes now uses `memcpy`
instead of
field-by-field transfer when the dtype has a contiguous layout (no gaps
between
fields). A new `NPY_NOT_TRIVIALLY_COPYABLE` dtype flag is set on
structured
dtypes that have gaps in their memory layout, such as those created with
explicit `offsets` or via multi-field indexing. Only these dtypes
continue to
use the slower field-by-field copy.

This means that padding bytes in contiguous structured dtypes (e.g.
those
created without explicit `offsets`) may now be copied as part of the
`memcpy`, whereas previously they were left untouched. Code that relies
on
padding bytes being preserved during structured array copies may be
affected.

([gh-29270](https://redirect.github.com/numpy/numpy/pull/29270))

##### `numpy.ctypeslib.as_ctypes` now does not support scalar types

The function `numpy.ctypeslib.as_ctypes` has been updated to only accept
`numpy.ndarray`. Passing a scalar type (e.g., `numpy.int32(5)`) will now
raise a `TypeError`. This change was made to avoid the issue
[gh-30354](https://redirect.github.com/numpy/numpy/issues/30354) and to
enforce the
readonly nature of scalar types in NumPy. The previous behavior relied
on
undocumented implicit temporary arrays and was not well-defined. Users
who
need to convert scalar types to ctypes should first convert them to an
array
(e.g., `numpy.asarray`) before passing them to
`numpy.ctypeslib.as_ctypes`.

([gh-30538](https://redirect.github.com/numpy/numpy/pull/30538))

##### `__array_interface__` changes on scalars

Scalars now export the `__array_interface__` directly rather than
including
an array copy as a `__ref` entry. This means that scalars are now
exported as
read-only while they previously exported as writeable. The path via
`__ref`
was undocumented and not consistently used even within NumPy itself.

([gh-30538](https://redirect.github.com/numpy/numpy/pull/30538))

##### `meshgrid` now always returns a tuple

`np.meshgrid` previously used to return a list when `sparse` was true
and
`copy` was false. Now, it always returns a tuple regardless of the
arguments.

([gh-30707](https://redirect.github.com/numpy/numpy/pull/30707))

##### `numpy.triu_indices` now accepts `unsigned integers`

`numpy.triu_indices` previously used to error in some cases when
`unsigned integers`
were given as arguments. Now, it accepts them in all cases.

([gh-30869](https://redirect.github.com/numpy/numpy/pull/30869))

##### `object` dtype in `.real` and `.imag` and related functions

The array attributes `.real` and `.imag` now behave differently for
object
arrays and return `getattr(element, "real", element)` or
`getattr(element, "imag", 0)`
elementwise. Additionally, the return for both is now read-only to avoid
possible
in-place changes having no effect.

This change also affects `np.isreal()` which uses `arr.imag`.

Previously, `.imag` always returned `0` while `.real` returned the
original array unmodified. The new behavior now returnes the correct
values
for complex Python objects but may also lead to surprises for example if
`element.real()` is a method and not a property.

([gh-30984](https://redirect.github.com/numpy/numpy/pull/30984))

##### NumPy's internal memory allocations now use `PyMem_RawMalloc`

NumPy's internal memory allocations now use `PyMem_RawMalloc` instead of
`malloc` and can be tracked by `tracemalloc`.

([gh-31503](https://redirect.github.com/numpy/numpy/pull/31503))

###
[`v2.4.6`](https://redirect.github.com/numpy/numpy/compare/v2.4.5...v2.4.6)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.5...v2.4.6)

###
[`v2.4.5`](https://redirect.github.com/numpy/numpy/releases/tag/v2.4.5):
(May 15, 2026)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.4...v2.4.5)

##### NumPy 2.4.5 Release Notes

NumPy 2.4.5 is a patch release that fixes bugs discovered after the
2.4.4
release, has some typing improvements, and maintains infrastructure.

This release supports Python versions 3.11-3.14

##### Contributors

A total of 17 people contributed to this release. People with a "+" by
their
names contributed a patch for the first time.

- Aleksei Nikiforov
- Anarion Zuo +
- Ankit Ahlawat
- Breno Favaretto +
- Charles Harris
- Igor Krivenko +
- Ijtihed Kilani +
- Joren Hammudoglu
- Maarten Baert +
- Matti Picus
- Nathan Goldbaum
- Praneeth Kodumagulla +
- Ralf Gommers
- RoomWithOutRoof +
- Sebastian Berg
- Warren Weckesser
- div +

##### Pull requests merged

A total of 28 pull requests were merged for this release.

- [#&#8203;31093](https://redirect.github.com/numpy/numpy/pull/31093):
MAINT: Prepare 2.4.x for further development
- [#&#8203;31182](https://redirect.github.com/numpy/numpy/pull/31182):
TYP: fix `np.shape` assignability issue for python lists
([#&#8203;31171](https://redirect.github.com/numpy/numpy/issues/31171))
- [#&#8203;31197](https://redirect.github.com/numpy/numpy/pull/31197):
ENH: Return rank 0 for empty matrices in matrix\_rank
([#&#8203;30422](https://redirect.github.com/numpy/numpy/issues/30422))
- [#&#8203;31198](https://redirect.github.com/numpy/numpy/pull/31198):
CI/BUG: add native jobs for s390x, fix bug in `pack_inner`...
- [#&#8203;31199](https://redirect.github.com/numpy/numpy/pull/31199):
BUG: f2py map complex\_long\_double to NPY\_CLONGDOUBLE
- [#&#8203;31205](https://redirect.github.com/numpy/numpy/pull/31205):
MAINT: f2py: Stop setting re.\_MAXCACHE to 50.
- [#&#8203;31206](https://redirect.github.com/numpy/numpy/pull/31206):
BUG: fix heap buffer overflow in timedelta to string casts
- [#&#8203;31207](https://redirect.github.com/numpy/numpy/pull/31207):
MAINT: Rename ppc64le and s390x workflow
([#&#8203;31121](https://redirect.github.com/numpy/numpy/issues/31121))
- [#&#8203;31208](https://redirect.github.com/numpy/numpy/pull/31208):
BUG: Fix matvec/vecmat in-place aliasing (out=input produces...
- [#&#8203;31209](https://redirect.github.com/numpy/numpy/pull/31209):
TYP: `tile`: accept numpy scalars and arrays as second argument...
- [#&#8203;31211](https://redirect.github.com/numpy/numpy/pull/31211):
DEP: Undo deprecation for np.dtype() signature used by old pickles...
- [#&#8203;31212](https://redirect.github.com/numpy/numpy/pull/31212):
REV: Manual revert of float16 svml use
([#&#8203;31178](https://redirect.github.com/numpy/numpy/issues/31178))
- [#&#8203;31222](https://redirect.github.com/numpy/numpy/pull/31222):
TYP: `ix_` fix for boolean and non-1d input
([#&#8203;31218](https://redirect.github.com/numpy/numpy/issues/31218))
- [#&#8203;31329](https://redirect.github.com/numpy/numpy/pull/31329):
BUG: incorrect temp elision for new-style (NEP 43) user-defined...
- [#&#8203;31330](https://redirect.github.com/numpy/numpy/pull/31330):
TYP: fix sliding\_window\_view axis parameter typing
- [#&#8203;31335](https://redirect.github.com/numpy/numpy/pull/31335):
BUG: Prevent deadlock due to downstream importing NumPy in dlopen...
- [#&#8203;31336](https://redirect.github.com/numpy/numpy/pull/31336):
BUG: Fix segfault in nditer.multi\_index when \_\_getitem\_\_ raises...
- [#&#8203;31338](https://redirect.github.com/numpy/numpy/pull/31338):
TYP: Fix ruff lint error
- [#&#8203;31357](https://redirect.github.com/numpy/numpy/pull/31357):
BUG: fix memory leak in np.zeros when fill-zero loop raises
([#&#8203;31320](https://redirect.github.com/numpy/numpy/issues/31320))
- [#&#8203;31358](https://redirect.github.com/numpy/numpy/pull/31358):
BUG: np.einsum() fails with a 0-dimensional out argument and...
- [#&#8203;31379](https://redirect.github.com/numpy/numpy/pull/31379):
BUG: Fix signed overflow issue in npy\_gcd for INT\_MIN on s390x...
- [#&#8203;31383](https://redirect.github.com/numpy/numpy/pull/31383):
CI: remove Cirrus CI FreeBSD job
([#&#8203;31380](https://redirect.github.com/numpy/numpy/issues/31380))
- [#&#8203;31390](https://redirect.github.com/numpy/numpy/pull/31390):
BUILD: newer MKL uses so.3
- [#&#8203;31391](https://redirect.github.com/numpy/numpy/pull/31391):
BLD/MAINT: improve support for Intel LLVM compilers
- [#&#8203;31401](https://redirect.github.com/numpy/numpy/pull/31401):
BUG: Avoid UB in [safe]()\[add,sub,mul] helpers
([#&#8203;31396](https://redirect.github.com/numpy/numpy/issues/31396))
- [#&#8203;31402](https://redirect.github.com/numpy/numpy/pull/31402):
BUG: exclude \_\_pycache\_\_ directories from wheels
([#&#8203;31397](https://redirect.github.com/numpy/numpy/issues/31397))
- [#&#8203;31404](https://redirect.github.com/numpy/numpy/pull/31404):
TYP: `_NestedSequence` type parameter default to work around...
- [#&#8203;31426](https://redirect.github.com/numpy/numpy/pull/31426):
TYP: Fix `DTypeLike` runtime type-checker support
([#&#8203;31425](https://redirect.github.com/numpy/numpy/issues/31425))

###
[`v2.4.4`](https://redirect.github.com/numpy/numpy/releases/tag/v2.4.4):
2.4.4 (Mar 29, 2026)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.3...v2.4.4)

### NumPy 2.4.4 Release Notes

The NumPy 2.4.4 is a patch release that fixes bugs discovered after the
2.4.3
release. It should finally close issue
[#&#8203;30816](https://redirect.github.com/numpy/numpy/issues/30816),
the OpenBLAS threading problem
on ARM.

This release supports Python versions 3.11-3.14

#### Contributors

A total of 8 people contributed to this release. People with a "+" by
their
names contributed a patch for the first time.

- Charles Harris
- Daniel Haag +
- Denis Prokopenko +
- Harshith J +
- Koki Watanabe
- Marten van Kerkwijk
- Matti Picus
- Nathan Goldbaum

#### Pull requests merged

A total of 7 pull requests were merged for this release.

- [#&#8203;30978](https://redirect.github.com/numpy/numpy/pull/30978):
MAINT: Prepare 2.4.x for further development
- [#&#8203;31049](https://redirect.github.com/numpy/numpy/pull/31049):
BUG: Add test to reproduce problem described in
[#&#8203;30816](https://redirect.github.com/numpy/numpy/issues/30816)
([#&#8203;30818](https://redirect.github.com/numpy/numpy/issues/30818))
- [#&#8203;31052](https://redirect.github.com/numpy/numpy/pull/31052):
BUG: fix FNV-1a 64-bit selection by using NPY\_SIZEOF\_UINTP
([#&#8203;31035](https://redirect.github.com/numpy/numpy/issues/31035))
- [#&#8203;31053](https://redirect.github.com/numpy/numpy/pull/31053):
BUG: avoid warning on ufunc with where=True and no output
- [#&#8203;31058](https://redirect.github.com/numpy/numpy/pull/31058):
DOC: document caveats of ndarray.resize on 3.14 and newer
- [#&#8203;31079](https://redirect.github.com/numpy/numpy/pull/31079):
TST: fix POWER VSX feature mapping
([#&#8203;30801](https://redirect.github.com/numpy/numpy/issues/30801))
- [#&#8203;31084](https://redirect.github.com/numpy/numpy/pull/31084):
MAINT: numpy.i: Replace deprecated `sprintf` with `snprintf`...

###
[`v2.4.3`](https://redirect.github.com/numpy/numpy/compare/v2.4.2...v2.4.3)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.2...v2.4.3)

###
[`v2.4.2`](https://redirect.github.com/numpy/numpy/compare/v2.4.1...v2.4.2)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.1...v2.4.2)

###
[`v2.4.1`](https://redirect.github.com/numpy/numpy/releases/tag/v2.4.1):
2.4.1 (Jan 10, 2026)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.4.0...v2.4.1)

### NumPy 2.4.1 Release Notes

The NumPy 2.4.1 is a patch release that fixes bugs discoved after the
2.4.0 release. In particular, the typo `SeedlessSequence` is preserved
to
enable wheels using the random Cython API and built against NumPy <
2.4.0
to run without errors.

This release supports Python versions 3.11-3.14

#### Contributors

A total of 9 people contributed to this release. People with a "+" by
their
names contributed a patch for the first time.

- Alexander Shadchin
- Bill Tompkins +
- Charles Harris
- Joren Hammudoglu
- Marten van Kerkwijk
- Nathan Goldbaum
- Raghuveer Devulapalli
- Ralf Gommers
- Sebastian Berg

#### Pull requests merged

A total of 15 pull requests were merged for this release.

- [#&#8203;30490](https://redirect.github.com/numpy/numpy/pull/30490):
MAINT: Prepare 2.4.x for further development
- [#&#8203;30503](https://redirect.github.com/numpy/numpy/pull/30503):
DOC: `numpy.select`: fix `default` parameter docstring...
- [#&#8203;30504](https://redirect.github.com/numpy/numpy/pull/30504):
REV: Revert part of
[#&#8203;30164](https://redirect.github.com/numpy/numpy/issues/30164)
([#&#8203;30500](https://redirect.github.com/numpy/numpy/issues/30500))
- [#&#8203;30506](https://redirect.github.com/numpy/numpy/pull/30506):
TYP: `numpy.select`: allow passing array-like `default`...
- [#&#8203;30507](https://redirect.github.com/numpy/numpy/pull/30507):
MNT: use if constexpr for compile-time branch selection
- [#&#8203;30513](https://redirect.github.com/numpy/numpy/pull/30513):
BUG: Fix leak in flat assignment iterator
- [#&#8203;30516](https://redirect.github.com/numpy/numpy/pull/30516):
BUG: fix heap overflow in fixed-width string multiply
([#&#8203;30511](https://redirect.github.com/numpy/numpy/issues/30511))
- [#&#8203;30523](https://redirect.github.com/numpy/numpy/pull/30523):
BUG: Ensure summed weights returned by np.average always are...
- [#&#8203;30527](https://redirect.github.com/numpy/numpy/pull/30527):
TYP: Fix return type of histogram2d
- [#&#8203;30594](https://redirect.github.com/numpy/numpy/pull/30594):
MAINT: avoid passing ints to random functions that take double...
- [#&#8203;30595](https://redirect.github.com/numpy/numpy/pull/30595):
BLD: Avoiding conflict with pygit2 for static build
- [#&#8203;30596](https://redirect.github.com/numpy/numpy/pull/30596):
MAINT: Fix msvccompiler missing error on FreeBSD
- [#&#8203;30608](https://redirect.github.com/numpy/numpy/pull/30608):
BLD: update vendored Meson to 1.9.2
- [#&#8203;30620](https://redirect.github.com/numpy/numpy/pull/30620):
ENH: use more fine-grained critical sections in array coercion...
- [#&#8203;30623](https://redirect.github.com/numpy/numpy/pull/30623):
BUG: Undo result type change of quantile/percentile but keep...

###
[`v2.4.0`](https://redirect.github.com/numpy/numpy/releases/tag/v2.4.0):
2.4.0 (Dec 20, 2025)

[Compare
Source](https://redirect.github.com/numpy/numpy/compare/v2.3.5...v2.4.0)

### NumPy 2.4.0 Release Notes

The NumPy 2.4.0 release continues the work to improve free threaded
Python
support, user dtypes implementation, and annotations. There are many
expired
deprecations and bug fixes as well.

This release supports Python versions 3.11-3.14

#### Highlights

Apart from annotations and `same_value` kwarg, the 2.4 highlights are
mostly
of interest to downstream developers. They should help in implementing
new user
dtypes.

- Many annotation improvements. In particular, runtime signature
introspection.
- New `casting` kwarg `'same_value'` for casting by value.
- New `PyUFunc_AddLoopsFromSpec` function that can be used to add user
sort
  loops using the `ArrayMethod` API.
- New `__numpy_dtype__` protocol.

#### Deprecations

##### Setting the `strides` attribute is deprecated

Setting the strides attribute is now deprecated since mutating
an array is unsafe if an array is shared, especially by multiple
threads. As an alternative, you can create a new view (no copy) via:

- `np.lib.stride_tricks.strided_window_view` if applicable,
- `np.lib.stride_tricks.as_strided` for the general case,
- or the `np.ndarray` constructor (`buffer` is the original array) for a
  light-weight version.

([gh-28925](https://redirect.github.com/numpy/numpy/pull/28925))

##### Positional `out` argument to `np.maximum`, `np.minimum` is
deprecated

Passing the output array `out` positionally to `numpy.maximum` and
`numpy.minimum` is deprecated. For example, `np.maximum(a, b, c)` will
emit
a deprecation warning, since `c` is treated as the output buffer rather
than
a third input.

Always pass the output with the keyword form, e.g. `np.maximum(a, b,
out=c)`.
This makes intent clear and simplifies type annotations.

([gh-29052](https://redirect.github.com/numpy/numpy/pull/29052))

##### `align=` must be passed as boolean to `np.dtype()`

When creating a new `dtype` a `VisibleDeprecationWarning` will be given
if
`align=` is not a boolean. This is mainly to prevent accidentally
passing a
subarray align flag where it has no effect, such as `np.dtype("f8", 3)`
instead of `np.dtype(("f8", 3))`. We strongly suggest to always pass
`align=` as a keyword argument.

([gh-29301](https://redirect.github.com/numpy/numpy/pull/29301))

##### Assertion and warning control utilities are deprecated

`np.testing.assert_warns` and `np.testing.suppress_warnings` are
deprecated. Use `warnings.catch_warnings`, `warnings.filterwarnings`,
`pytest.warns`, or `pytest.filterwarnings` instead.

([gh-29550](https://redirect.github.com/numpy/numpy/pull/29550))

##### `np.fix` is pending deprecation

The `numpy.fix` function will be deprecated in a future release. It is
recommended to use `numpy.trunc` instead, as it provides the same
functionality of truncating decimal values to their integer parts.
Static type
checkers might already report a warning for the use of `numpy.fix`.

([gh-30168](https://redirect.github.com/numpy/numpy/pull/30168))

##### in-place modification of `ndarray.shape` is pending deprecation

Setting the `ndarray.shape` attribute directly will be deprecated in a
future
release. Instead of modifying the shape in place, it is recommended to
use the
`numpy.reshape` function. Static type checkers might already report a
warning for assignments to `ndarray.shape`.

([gh-30282](https://redirect.github.com/numpy/numpy/pull/30282))

##### Deprecation of `numpy.lib.user_array.container`

The `numpy.lib.user_array.container` class is deprecated and will be
removed
in a future version.

([gh-30284](https://redirect.github.com/numpy/numpy/pull/30284))

#### Expired deprecations

##### Removed deprecated `MachAr` runtime discovery mechanism.

([gh-29836](https://redirect.github.com/numpy/numpy/pull/29836))

##### Raise `TypeError` on attempt to convert array with `ndim > 0` to
scalar

Conversion of an array with `ndim > 0` to a scalar was deprecated in
NumPy
1.25. Now, attempting to do so raises `TypeError`. Ensure you extract a
single element from your array before performing this operation.

([gh-29841](https://redirect.github.com/numpy/numpy/pull/29841))

##### Removed numpy.linalg.linalg and numpy.fft.helper

The following were deprecated in NumPy 2.0 and have been moved to
private
modules:

- `numpy.linalg.linalg`
  Use `numpy.linalg` instead.
- `numpy.fft.helper`
  Use `numpy.fft` instead.

([gh-29909](https://redirect.github.com/numpy/numpy/pull/29909))

##### Removed `interpolation` parameter from quantile and percentile
functions

The `interpolation` parameter was deprecated in NumPy 1.22.0 and has
been
removed from the following functions:

- `numpy.percentile`
- `numpy.nanpercentile`
- `numpy.quantile`
- `numpy.nanquantile`

Use the `method` parameter instead.

([gh-29973](https://redirect.github.com/numpy/numpy/pull/29973))

##### Removed `numpy.in1d`

`numpy.in1d` has been deprecated since NumPy 2.0 and is now removed in
favor of `numpy.isin`.

([gh-29978](https://redirect.github.com/numpy/numpy/pull/29978))

##### Removed `numpy.ndindex.ndincr()`

The `ndindex.ndincr()` method has been deprecated since NumPy 1.20 and
is now
removed; use `next(ndindex)` instead.

([gh-29980](https://redirect.github.com/numpy/numpy/pull/29980))

##### Removed `fix_imports` parameter from `numpy.save`

The `fix_imports` parameter was deprecated in NumPy 2.1.0 and is now
removed.
This flag has been ignored since NumPy 1.17 and was only needed to
support
loading files in Python 2 that were written in Python 3.

([gh-29984](https://redirect.github.com/numpy/numpy/pull/29984))

##### Removal of four undocumented `ndarray.ctypes` methods

Four undocumented methods of the `ndarray.ctypes` object have been
removed:

- `_ctypes.get_data()` (use `_ctypes.data` instead)
- `_ctypes.get_shape()` (use `_ctypes.shape` instead)
- `_ctypes.get_strides()` (use `_ctypes.strides` instead)
- `_ctypes.get_as_parameter()` (use `_ctypes._as_parameter_` instead)

These methods have been deprecated since NumPy 1.21.

([gh-29986](https://redirect.github.com/numpy/numpy/pull/29986))

##### Removed `newshape` parameter from `numpy.reshape`

The `newshape` parameter was deprecated in NumPy 2.1.0 and has been
removed from `numpy.reshape`. Pass it positionally or use `shape=`
on newer NumPy versions.

([gh-29994](https://redirect.github.com/numpy/numpy/pull/29994))

##### Removal of deprecated functions and arguments

The following long-deprecated APIs have been removed:

- `numpy.trapz` --- deprecated since NumPy 2.0 (2023-08-18). Use
`numpy.trapezoid` or
  `scipy.integrate` functions instead.
- `disp` function --- deprecated from 2.0 release and no longer
functional. Use
  your own printing function instead.
- `bias` and `ddof` arguments in `numpy.corrcoef` --- these had no
effect
  since NumPy 1.10.

([gh-29997](https://redirect.github.com/numpy/numpy/pull/29997))

##### Removed `delimitor` parameter from
`numpy.ma.mrecords.fromtextfile()`

The `delimitor` parameter was deprecated in NumPy 1.22.0 and has been
removed from `numpy.ma.mrecords.fromtextfile()`. Use `delimiter`
instead.

([gh-30021](https://redirect.github.com/numpy/numpy/pull/30021))

##### `numpy.array2string` and `numpy.sum` deprecations finalized

The following long-deprecated APIs have been removed or converted to
errors:

- The `style` parameter has been removed from `numpy.array2string`.
This argument had no effect since Numpy 1.14.0. Any arguments following
  it, such as `formatter` have now been made keyword-only.
- Calling `np.sum(generator)` directly on a generator object now raises
a
  `TypeError`. This behavior was deprecated in NumPy 1.15.0. Use
  `np.sum(np.fromiter(generator))` or the python `sum` builtin instead.

([gh-30068](https://redirect.github.com/numpy/numpy/pull/30068))

#### Compatibility notes

- NumPy's C extension modules have begun to use multi-phase
initialisation, as
defined by PEP 489. As part of this, a new explicit check has been added
that
each such module is only imported once per Python process. This comes
with
the side-effect that deleting `numpy` from `sys.modules` and
re-importing
it will now fail with an `ImportError`. This has always been unsafe,
with
  unexpected side-effects, though did not previously raise an error.

  ([gh-29030](https://redirect.github.com/numpy/numpy/pull/29030))

- `numpy.round` now always returns a copy. Previously, it returned a
view
  for integer inputs for `decimals >= 0` and a copy in all other cases.
  This change brings `round` in line with `ceil`, `floor` and `trunc`.

  ([gh-29137](https://redirect.github.com/numpy/numpy/pull/29137))

- Type-checkers will no longer accept calls to `numpy.arange` with
  `start` as a keyword argument. This was done for compatibility with
  the Array API standard. At runtime it is still possible to use
  `numpy.arange` with `start` as a keyword argument.

  ([gh-30147](https://redirect.github.com/numpy/numpy/pull/30147))

- The Macro NPY\_ALIGNMENT\_REQUIRED has been removed The macro was
defined in
the `npy_cpu.h` file, so might be regarded as semi public. As it turns
out,
  with modern compilers and hardware it is almost always the case that
alignment is required, so numpy no longer uses the macro. It is unlikely
anyone uses it, but you might want to compile with the `-Wundef` flag or
  equivalent to be sure.

  ([gh-29094](https://redirect.github.com/numpy/numpy/pull/29094))

#### C API changes

##### The NPY\_SORTKIND enum has been enhanced with new variables

This is of interest if you are using `PyArray_Sort` or
`PyArray_ArgSort`.
We have changed the semantics of the old names in the `NPY_SORTKIND`
enum and
added new ones. The changes are backward compatible, and no
recompilation is
needed. The new names of interest are:

- `NPY_SORT_DEFAULT` -- default sort (same value as `NPY_QUICKSORT`)
- `NPY_SORT_STABLE` -- the sort must be stable (same value as
`NPY_MERGESORT`)
- `NPY_SORT_DESCENDING` -- the sort must be descending

The semantic change is that `NPY_HEAPSORT` is mapped to `NPY_QUICKSORT`
when used.
Note that `NPY_SORT_DESCENDING` is not yet implemented.

([gh-29642](https://redirect.github.com/numpy/numpy/pull/29642))

##### New `NPY_DT_get_constant` slot for DType constant retrieval

A new slot `NPY_DT_get_constant` has been added to the DType API,
allowing
dtype implementations to provide constant values such as machine limits
and
special values. The slot function has the signature:

```
int get_constant(PyArray_Descr *descr, int constant_id, void *ptr)
```

It returns 1 on success, 0 if the constant is not available, or -1 on
error.
The function is always called with the GIL held and may write to
unaligned memory.

Integer constants (marked with the `1 << 16` bit) return `npy_intp`
values,
while floating-point constants return values of the dtype's native type.

Implementing this can be used by user DTypes to provide `numpy.finfo`
values.

([gh-29836](https://redirect.github.com/numpy/numpy/pull/29836))

##### A new `PyUFunc_AddLoopsFromSpecs` convenience function has been
added to the C API.

This function allows adding multiple ufunc loops from their specs in one
call
using a NULL-terminated array of `PyUFunc_LoopSlot` structs. It allows
registering sorting and argsorting loops using the new ArrayMethod API.

([gh-29900](https://redirect.github.com/numpy/numpy/pull/29900))

#### New Features

- Let `np.size` accept multiple axes.

  ([gh-29240](https://redirect.github.com/numpy/numpy/pull/29240))

- Extend `numpy.pad` to accept a dictionary for the `pad_width`
argument.

  ([gh-29273](https://redirect.github.com/numpy/numpy/pull/29273))

##### `'same_value'` for casting by value

The `casting` kwarg now has a `'same_value'` option that checks the
actual
values can be round-trip cast without changing value. Currently it is
only
implemented in `ndarray.astype`. This will raise a `ValueError` if any
of the
values in the array would change as a result of the cast, including
rounding of
floats or overflowing of ints.

([gh-29129](https://redirect.github.com/numpy/numpy/pull/29129))

##### `StringDType` fill\_value support in `numpy.ma.MaskedArray`

Masked arrays now accept and preserve a Python `str` as their
`fill_value`
when using the variable‑width `StringDType` (kind `'T'`), including
through
slicing and views. The default is `'N/A'` and may be overridden by any
valid
string. This fixes issue
[gh‑29421](https://redirect.github.com/numpy/numpy/issues/29421)
and was implemented in pull request
[gh‑29423](https://redirect.github.com/numpy/numpy/pull/29423).

([gh-29423](https://redirect.github.com/numpy/numpy/pull/29423))

##### `ndmax` option for `numpy.array`

The `ndmax` option is now available for `numpy.array`.
It explicitly limits the maximum number of dimensions created from
nested sequences.

This is particularly useful when creating arrays of list-like objects
with `dtype=object`.
By default, NumPy recurses through all nesting levels to create the
highest possible
dimensional array, but this behavior may not be desired when the intent
is to preserve
nested structures as objects. The `ndmax` parameter provides explicit
control over
this recursion depth.

```python

# Default behavior: Creates a 2D array
>>> a = np.array([[1, 2], [3, 4]], dtype=object)
>>> a
array([[1, 2],
       [3, 4]], dtype=object)
>>> a.shape
(2, 2)

# With ndmax=1: Creates a 1D array
>>> b = np.array([[1, 2], [3, 4]], dtype=object, ndmax=1)
>>> b
array([list([1, 2]), list([3, 4])], dtype=object)
>>> b.shape
(2,)
```

([gh-29569](https://redirect.github.com/numpy/numpy/pull/29569))

##### Warning emitted when using `where` without `out`

Ufuncs called with a `where` mask and without an `out` positional or
kwarg will
now emit a warning. This usage tends to trip up users who expect some
value in
output locations where the mask is `False` (the ufunc will not touch
those
locations). The warning can be suppressed by using `out=None`.

([gh-29813](https://redirect.github.com/numpy/numpy/pull/29813))

##### DType sorting and argsorting supports the ArrayMethod API

User-defined dtypes can now implement custom sorting and argsorting
using the
`ArrayMethod` API. This mechanism can be used in place of the
`PyArray_ArrFuncs` slots which may be deprecated in the future.

The sorting and argsorting methods are registered by passing the
arraymethod
specs that implement the operations to the new
`PyUFunc_AddLoopsFromSpecs`
function. See the `ArrayMethod` API documentation for details.

([gh-29900](https://redirect.github.com/numpy/numpy/pull/29900))

##### New `__numpy_dtype__` protocol

NumPy now has a new `__numpy_dtype__` protocol. NumPy will check
for this attribute when converting to a NumPy dtype via `np.dtype(obj)`
or any `dtype=` argument.

Downstream projects are encouraged to implement this for all dtype like
objects which may previously have used a `.dtype` attribute that
returned
a NumPy dtype.
We expect to deprecate `.dtype` in the future to prevent interpreting
array-like objects with a `.dtype` attribute as a dtype.
If you wish you can implement `__numpy_dtype__` to ensure an earlier
warning or error (`.dtype` is ignored if this is found).

([gh-30179](https://redirect.github.com/numpy/numpy/pull/30179))

#### Improvements

##### Fix `flatiter` indexing edge cases

The `flatiter` object now shares the same index preparation logic as
`ndarray`, ensuring consistent behavior and fixing several issues where
invalid indices were previously accepted or misinterpreted.

Key fixes and improvements:

- Stricter index validation

  - Boolean non-array indices like `arr.flat[[True, True]]` were
    incorrectly treated as `arr.flat[np.array([1, 1], dtype=int)]`.
    They now raise an index error. Note that indices that match the
    iterator's shape are expected to not raise in the future and be
    handled as regular boolean indices. Use `np.asarray(<index>)` if
    you want to match that behavior.
  - Float non-array indices were also cast to integer and incorrectly
    treated as `arr.flat[np.array([1.0, 1.0], dtype=int)]`. This is now
    deprecated and will be removed in a future version.
  - 0-dimensional boolean indices like `arr.flat[True]` are also
    deprecated and will be removed in a future version.

- Consistent error types:

  Certain invalid `flatiter` indices that previously raised `ValueError`
  now correctly raise `IndexError`, aligning with `ndarray` behavior.

- Improved error messages:

  The error message for unsupported index operations now provides more
  specific details, including explicitly listing the valid index types,
  instead of the generic `IndexError: unsupported index operation`.

([gh-28590](https://redirect.github.com/numpy/numpy/pull/28590))

##### Improved error handling in `np.quantile`

\[np.quantile]{.title-ref} now raises errors if:

- All weights are zero
- At least one weight is `np.nan`
- At least one weight is `np.inf`

([gh-28595](https://redirect.github.com/numpy/numpy/pull/28595))

##### Improved error message for `assert_array_compare`

The error message generated by `assert_array_compare` which is used by
functions
like `assert_allclose`, `assert_array_less` etc. now also includes
information
about the indices at which the assertion fails.

([gh-29112](https://redirect.github.com/numpy/numpy/pull/29112))

##### Show unit information in `__repr__` for `datetime64("NaT")`

When a `datetime64` object is "Not a Time" (NaT), its `__repr__` method
now
includes the time unit of the datetime64 type. This makes it consistent
with
the behavior of a `timedelta64` object.

([gh-29396](https://redirect.github.com/numpy/numpy/pull/29396))

##### Performance increase for scalar calculations

The speed of calculations on scalars has been improved by about a factor
6 for
ufuncs that take only one input (like `np.sin(scalar)`), reducing the
speed
difference from their `math` equivalents from a factor 19 to 3 (the
speed
for arrays is left unchanged).

([gh-29819](https://redirect.github.com/numpy/numpy/pull/29819))

##### `numpy.finfo` Refactor

The `numpy.finfo` class has been completely refactored to obtain
floating-point
constants directly from C compiler macros rather than deriving them at
runtime.
This provides better accuracy, platform compatibility and corrected
several attribute calculations:

- Constants like `eps`, `min`, `max`, `smallest_normal`, and
`smallest_subnormal` now come directly from standard C macros
(`FLT_EPSILON`,
  `DBL_MIN`, etc.), ensuring platform-correct values.
- The deprecated `MachAr` runtime discovery mechanism has been removed.
- Derived attributes have been corrected to match standard definitions:
  `machep` and `negep` now use `int(log2(eps))`; `nexp` accounts for
  all exponent patterns; `nmant` excludes the implicit bit; and `minexp`
  follows the C standard definition.
- longdouble constants, Specifically `smallest_normal` now follows the
  C standard definitions as per respecitive platform.
- Special handling added for PowerPC's IBM double-double format.
- New test suite added in `test_finfo.py` to validate all
  `finfo` properties against expected machine arithmetic values for
  float16, float32, and float64 types.

([gh-29836](https://redirect.gi

>  **Important**
> 
> ✂ PR body was truncated to here.


</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-10 20:18:56 +00:00
renovate[bot] 322f94e849 chore(deps): update dependency scipy to v1.18.1 (#1128)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [scipy](https://redirect.github.com/scipy/scipy) | `==1.15.3` →
`==1.18.1` |
![age](https://developer.mend.io/api/mc/badges/age/pypi/scipy/1.18.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/scipy/1.15.3/1.18.1?slim=true)
|

---

### Release Notes

<details>
<summary>scipy/scipy (scipy)</summary>

###
[`v1.18.1`](https://redirect.github.com/scipy/scipy/releases/tag/v1.18.1):
SciPy 1.18.1

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.18.0...v1.18.1)

# SciPy 1.18.1 Release Notes

SciPy `1.18.1` is a bug-fix release with no new features
compared to `1.18.0`. This release includes binaries on
PyPI for Python `3.15`, and the minimum required version
of the GCC toolchain has been increased to `10.3.0`.

# Authors

- Name (commits)
- Wasim Akram (2) +
- Jake Bowhay (1)
- Michael Bratsch (1)
- Dietrich Brunn (1)
- Evgeni Burovski (1)
- Aadya Chinubhai (1)
- Lucas Colley (3)
- Tekin Ertekin (1) +
- Fuyugithub (2) +
- Ralf Gommers (11)
- Joren Hammudoglu (1)
- Ijtihed Kilani (1) +
- Andrew Nelson (2)
- Ilhan Polat (1)
- Tyler Reddy (39)
- romao05 (1) +
- Michael Simacek (1) +
- Jacob Vanderplas (2)

A total of 18 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

Note that the source and binary assets associated with this release were
published to PyPI using [trusted
publishing](https://docs.pypi.org/trusted-publishers/), and so the
trusted assets and their hashes are made available more securely at
<https://pypi.org/project/scipy/1.18.1/> rather than providing them here
in a less secure manner.

A complete list of issues and pull requests associated with this release
is available in the associated
[`README.txt`](https://redirect.github.com/scipy/scipy/releases/download/v1.18.1/README.txt).

###
[`v1.18.0`](https://redirect.github.com/scipy/scipy/compare/v1.17.1...v1.18.0)

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.17.1...v1.18.0)

###
[`v1.17.1`](https://redirect.github.com/scipy/scipy/releases/tag/v1.17.1):
SciPy 1.17.1

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.17.0...v1.17.1)

# SciPy 1.17.1 Release Notes

SciPy `1.17.1` is a bug-fix release with no new features compared to
`1.17.0`.

# Authors

- Name (commits)
- Evgeni Burovski (5)
- Lucas Colley (1)
- Christoph Gohlke (1)
- Ralf Gommers (6)
- Matt Haberland (5)
- Matthias Koeppe (1)
- Nick ODell (1)
- Ilhan Polat (10)
- Tyler Reddy (44)
- Martin Schuck (3)
- Dan Schult (3)
- stratakis (1) +
- ਗਗਨਦੀਪ ਸਿੰਘ (Gagandeep Singh) (1)

A total of 13 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

Complete issue list, PR list, and release asset hashes are available in
the associated
[`README.txt`](https://redirect.github.com/scipy/scipy/releases/download/v1.17.1/README.txt).

###
[`v1.17.0`](https://redirect.github.com/scipy/scipy/releases/tag/v1.17.0):
SciPy 1.17.0

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.16.3...v1.17.0)

# SciPy 1.17.0 Release Notes

SciPy `1.17.0` is the culmination of 6 months of hard work. It contains
many new features, numerous bug-fixes, improved test coverage and better
documentation. There have been a number of deprecations and API changes
in this release, which are documented below. All users are encouraged to
upgrade to this release, as there are a large number of bug-fixes and
optimizations. Before upgrading, we recommend that users check that
their own code does not use deprecated SciPy functionality (to do so,
run your code with `python -Wd` and check for `DeprecationWarning` s).
Our development attention will now shift to bug-fix releases on the
`1.17.x` branch, and on adding new features on the main branch.

This release requires Python `3.11`-`3.14` and NumPy `1.26.4` or
greater.

# Highlights of this release

- Many SciPy functions have gained native support for batching of
N-dimensional
array input and additional support for the array API standard. An
overall
summary of the latter is now available in a [set of
tables](https://scipy.github.io/devdocs/dev/api-dev/array_api.html#api-coverage).
- In `scipy.sparse`, `coo_array` now supports indexing. This includes
integers,
  slices, arrays, `np.newaxis`, `Ellipsis`, in 1D, 2D and the relatively
new nD. In `scipy.sparse.linalg`, ARPACK and PROPACK rewrites from
Fortran77
to C now empower the use of external pseudorandom number generators,
e.g.
  from numpy.
- In `scipy.spatial`, `transform.Rotation` and
`transform.RigidTransform`
have been extended to support N-D arrays. `geometric_slerp` now has
support
  for extrapolation.
- `scipy.stats` has gained the matrix t and logistic distributions and
many
  performance and accuracy improvements.
- Initial support for 64-bit integer (ILP64) BLAS and LAPACK libraries
has
been added, including for MKL and Apple Accelerate. Please report any
issues with
  ILP64 you encounter.

# New features

# `scipy.integrate` improvements

- The integration routines `dopri5`, `dopri853`, `LSODA`, `vode`, and
  `zvode` have been ported from Fortran77 to C.
- `scipy.integrate.quad` now has a fast path for returning 0 when the
integration
  interval is empty.
- The `BDF`, `DOP853`, `RK23`, `RK45`, `OdeSolver`, `DenseOutput`,
  `ode`, and `complex_ode` classes now support subscription, making them
  generic types, for compatibility with `scipy-stubs`.

# `scipy.cluster` improvements

- `scipy.cluster.hierarchy.is_isomorphic` has improved performance and
array
  API support.

# `scipy.interpolate` improvements

- A new `bc_type` argument has been added to
`scipy.interpolate.make_splrep`,
`scipy.interpolate.make_splprep`, and `scipy.interpolate.generate_knots`
to
  control the boundary conditions for spline fitting. Allowed values are
  `"not-a-knot"` (default) and `"periodic"`.
- A new `derivative` method has been added to the
`scipy.interpolate.NdBSpline` class, to construct a new spline
representing a
  partial derivative of the given spline. This method is similar to the
  `BSpline.derivative` method of 1-D spline objects. In addition, the
`NdBSpline` mutable instance attribute `.c` was changed into a read-only
  `@property`.
- Performance of `"cubic"` and `"quintic"` modes of
`scipy.interpolate.RegularGridInterpolator` has been improved.
Furthermore,
the (mutable) instance attributes `.grid` and `.values` were changed
into
  (read-only) properties.
- Numerical stability of `scipy.interpolate.AAA` has been improved and
it has
  gained a new `axis` parameter.
- `scipy.interpolate.FloaterHormannInterpolator` added support for
  multidimensional, batched inputs and gained a new `axis` parameter to
  select the interpolation axis.
- `RBFInterpolator` has gained an array API standard compatible backend,
with an
  improved support for GPU arrays.
- The `AAA`, `*Interpolator`, `*Poly`, and `*Spline` classes now
support subscription, making them generic types, for compatibility with
  `scipy-stubs`.

# `scipy.linalg` improvements

- `scipy.linalg.inv` routine has been improved:

- it now attempts to detect the structure of its argument and selects an
appropriate low-level matrix inversion routine. A new `assume_a` keyword
allows to bypass the structure detection if the structure is known. For
batched inputs, the detection is run for each 2D slice, unless an
explicit
    value for `assume_a` is provided (in which case, the structure is
    assumed to be the same for all 2-D slices of the batch);
  - the new `lower={True,False}` keyword argument has been added to help
    select the upper or lower triangle of the input matrix for symmetric
    inputs; refer to the docstring of `scipy.linalg.inv` for details;
  - the routine emits a `LinAlgWarning` if it detects an ill-conditioned
    input;
  - performance for batched inputs has been improved.
- `scipy.linalg.fiedler` has gained native support for batched inputs.
- performance has improved for `scipy.linalg.solve` with batched inputs
  for certain matrix structures.

# `scipy.optimize` improvements

- `optimize.minimize(method="trust-exact")` now accepts a
solver-specific `"subproblem_maxiter"` option. This option can be used
to
assure that the algorithm converges for functions with an
ill-conditioned
  Hessian.
- Callback functions used by `optimize.minimize(method="slsqp")` can
opt into the new callback interface by accepting a single keyword
argument
  `intermediate_result`.
- The `BroydenFirst`, `*Jacobian`, and `Bounds` classes now support
  subscription, making them generic types, for compatibility with
  `scipy-stubs`.

# `scipy.signal` improvements

- `scipy.signal.abcd_normalize` gained more informative error messages
and the
  documentation was improved.
- `scipy.signal.get_window` now accepts the suffixes `'_periodic'` and
  `'_symmetric'` to distinguish between periodic and symmetric windows
  (overriding the `fftbin` parameter). This benefits the functions
  `coherence`, `csd`, `periodogram`, `welch`, `spectrogram`,
  `stft`, `istft`, `resample`, `resample_poly`, `firwin`,
  `firwin2`, `firwin_2d`, `check_COLA` and `check_NOLA`, which utilize
  `get_window` but do not expose the `fftbin` parameter.
- `scipy.signal.hilbert2` gained the new keyword `axes` for specifying
the
axes along which the two-dimensional analytic signal should be
calculated.
  Furthermore, the documentation of `scipy.signal.hilbert` and
  `scipy.signal.hilbert2` was significantly improved.
- The `ShortTimeFFT` and `LinearTimeInvariant` classes now support
  subscription, making them generic types, for compatibility with
  `scipy-stubs`.

# `scipy.sparse` improvements

- `coo_array` now supports indexing. This includes slices, arrays,
  `np.newaxis`, `Ellipsis`, in 1D, 2D and the new nD. So COO format now
  has full support for nD and COO now allows indexing without converting
  formats.
- Additional sparse construction functions include `expand_dims`,
  `swapaxes`, `permute_dims`, and nD support for the `kron` function.
- ARPACK Fortran77 library is ported to C. Among many changes, it is now
  possible to use external random generators including NumPy PRNGs for
reproducible runs. Previously this was not the case due to internal
seeding
  behavior of the original ARPACK code.
- Similarly, PROPACK Fortran77 library is also ported to C with the same
PRNG
  enhancements and other improvements.
- `scipy.sparse.dok_array` now supports an `update` method which can be
used to update the sparse array using a dict, `dict.items()`-like
iterable,
or another `dok_array` matrix. It performs additional validation that
keys
  are valid index tuples.
- `scipy.sparse.dia_array.tocsr` is approximately three times faster and
  some unnecessary copy operations have been removed from sparse format
  interconversions more broadly.
- Added `scipy.sparse.linalg.funm_multiply_krylov`, a restarted Krylov
method
  for evaluating `y = f(tA) b`.
- In `sparse.linalg`, the `LinearOperator`, `LaplacianNd`, and `SuperLU`
  classes now support subscription, making them generic types, for
  compatibility with `scipy-stubs`.
- In `sparse.linalg` the `eigs` and `eigsh` functions now accept a new
  `rng` parameter.

# `scipy.spatial` improvements

- The `spatial.transform` module has gained an array API standard
compatible
  backend.

- `transform.Rotation` and `transform.RigidTransform` have been extended
from 0D single values and 1D arrays to N-D arrays, with standard
indexing and
  broadcasting rules. Both now have the following additions:

  - A `shape` property.
- A `shape` argument to their `identity()` constructors, which should be
preferred over the existing `num` argument. This has also been added as
an
argument for `Rotation.random()` (`RigidTransform` does not currently
    have a `random` constructor).
  - An `axis` argument to their `mean()` functions.

- The resulting shapes for `transform.Rotation.from_euler` /
`from_davenport` have changed to make them consistent with broadcasting
rules. Angle inputs to Euler angles must now strictly match the number
of
provided axes in the last dimension. The resulting `Rotation` has the
shape
`np.atleast_1d(angles).shape[:-1]`. Angle inputs to Davenport angles
must
also match the number of axes in the last dimension. The resulting
`Rotation`
  has the shape `np.broadcast_shapes(np.atleast_2d(axes).shape[:-2],
  np.atleast_1d(angles).shape[:-1])`.

- `Rotation.from_matrix` has gained an `assume_valid` argument that
allows for
  performance improvements when users can guarantee valid matrix inputs.
`from_matrix` is now also faster in cases where a known orthogonal
matrix
  is used.

- The `scipy.spatial.geometric_slerp` function can now extrapolate. When
given a
value outside the range \[0, 1], `geometric_slerp()` will continue with
  the same rotation outside this range. For example, if spherically
  interpolating with `start` being a point on the equator, and `end`
being a point at the north pole, then a value of `t=-1` would give you a
  point at the south pole.

- `Rotation.as_euler` and `Rotation.as_davenport` methods have gained a
`suppress_warnings` parameter to enable suppression of gimbal lock
warnings.

- `Rotation.__init__` has gained a new optional `scalar_first` parameter
and
  there is a new `Rotation.__setitem__` method.

# `scipy.special` improvements

- The following functions for statistical applications have
significantly
improved parameter ranges and reduced error rates: `btdtria`, `btdtrib`,
  `chdtriv`, `chndtr`, `chndtrix`, `chndtridf`, `chndtrinc`, `fdtr`,
  `fdtrc`, `fdtri`, `gdtria`, `gdtrix`, `pdtrik`, `stdtr` and
  `stdtrit`.
- The incomplete beta functions `betainc`, `betaincc`, `betaincinv` and
  `betainccinv` are improved for extreme parameter ranges.

# `scipy.stats` improvements

- `scipy.stats.matrix_t` has been added to represent the matrix t
distribution.
  It supports methods `pdf` (and `logpdf`) for computing the probability
  density function and `rvs` for generating random variates.
- `scipy.stats.Logistic` was added for modeling random variables that
follow a
  logistic distribution.
- `scipy.stats.quantile` now accepts a `weights` argument to specify
  frequency weights.
- `scipy.stats.quantile` is now faster on large arrays as it no longer
uses
  stable sort internally.
- `scipy.stats.quantile` supports three new values of the `method`
argument,
`'round_inward'`, `'round_outward'`, and `'round_neareast'`, for use in
  the context of trimming and winsorizing data.
- `scipy.stats.truncpareto` now accepts negative values for the exponent
shape
  parameter, enabling use of `truncpareto` as a more general power law
  distribution.
- `scipy.stats.logser` now provides a distribution-specific
implementation of
  the `sf` method, improving speed and accuracy.
- Implementations of the following function have been vectorized:
  `scipy.stats.ansari`, `scipy.stats.cramervonmises`,
`scipy.stats.cramervonmises_2samp`, `scipy.stats.epps_singleton_2samp`,
`scipy.stats.fligner`, `scipy.stats.friedmanchisquare`,
`scipy.stats.kruskal`,
  `scipy.stats.ks_1samp`, `scipy.stats.levene`, and `scipy.stats.mood`.
Typically, this improves performance with multidimensional (batch)
input.
- The critical value tables of `scipy.stats.anderson` have been updated.
- A new `method` parameter of `scipy.stats.anderson` allows the user
to compute p-values by interpolating between tabulated values or using
Monte
  Carlo simulation. The `method` parameter must be passed explicitly
  to add a `pvalue` attribute to the result object and avoid a warning
  about the upcoming removal of `critical_value`, `significance_level`,
  and `fit_result` attributes.
- A new `variant` parameter of `scipy.stats.anderson_ksamp` allows the
user
to select between three different variants of the statistic, superseding
the
`midrank` parameter which allowed toggling between two. The new
`'continuous'`
variant is equivalent to `'discrete'` when there are no ties in the
sample, but
the calculation is faster. The `variant` parameter must be passed
explicitly to
avoid a warning about the deprecation of the `midrank` attribute and the
upcoming
  removal of `critical_values` from the result object.
- The speed and accuracy of most `scipy.stats.zipfian` methods has been
  improved.
- The accuracies of the `scipy.stats.Binomial` methods `logcdf` and
  `logccdf` have been improved in the tails.
- The default guess of `scipy.stats.trapezoid.fit` has been improved.
- The accuracy and range of the `cdf`, `sf`, `isf`, and `ppf` methods
  of `scipy.stats.binom` and `scipy.stats.nbinom` has been improved.
- The `Covariance`, `Uniform`, `Normal`, `Binomial`, `Mixture`,
  `rv_frozen`, and `multi_rv_frozen` classes now support subscription,
  making them generic types, for compatibility with `scipy-stubs`.
- The `multivariate_t` and `multivariate_normal` distributions have
gained
  a new `marginal` method.
- `yeojohnson_llf` gained new parameters `axis`, `nan_policy`,
and `keepdims`, and now returns a numpy scalar where it would previously
  return a 0D array.
- The new `spearmanrho` function is an array API compatible substitute
for
  `spearmanr`.
- The `median_abs_deviation` function has gained a `keepdims` parameter.
- The `trim_mean` function has gained new `nan_policy` and `keepdims`
  parameters.

# Array API Standard Support

- An overall summary table for our array API standard support/coverage
is
[now
available](https://scipy.github.io/devdocs/dev/api-dev/array_api.html#api-coverage).
- The overhead associated with array namespace determination has been
reduced,
  providing improved performance in dispatching to different backends.
- `scipy.cluster.hierarchy.is_isomorphic` has gained support.
- `scipy.interpolate.make_lsq_spline`,
`scipy.interpolate.make_smoothing_spline`,
  `scipy.interpolate.make_splrep`, `scipy.interpolate.make_splprep`,
`scipy.interpolate.generate_knots`, and
`scipy.interpolate.make_interp_spline`
  have gained support.
- `scipy.signal.bilinear`, `scipy.signal.iircomb`,
`scipy.signal.iirdesign`,
`scipy.signal.iirfilter`, `scipy.signal.iirpeak`,
`scipy.signal.iirnotch`,
`scipy.signal.gammatone`, and `scipy.signal.group_delay` have gained
support.
- `scipy.signal.butter`, `scipy.signal.buttap`, `scipy.signal.buttord`,
`scipy.signal.cheby1`, `scipy.signal.cheb1ap`, `scipy.signal.cheb1ord`,
`scipy.signal.cheby2`, `scipy.signal.cheb2ap`, `scipy.signal.cheb2ord`,
  `scipy.signal.bessel`, `scipy.signal.besselap`, `scipy.signal.ellip`,
`scipy.signal.ellipap`, and `scipy.signal.ellipord` have gained support.
- `scipy.signal.savgol_filter`, `scipy.signal.savgol_coeffs`, and
  `scipy.signal.abcd_normalize` have gained support.
- `spatial.transform` has gained support.
- `scipy.integrate.qmc_quad`, `scipy.integrate.cumulative_simpson`,
`scipy.integrate.cumulative_trapezoid`, and `scipy.integrate.romb` have
  gained support.
- `scipy.linalg.block_diag`, `scipy.linalg.fiedler`, and
  `scipy.linalg.orthogonal_procrustes` have gained support.
- `scipy.interpolate.BSpline`, `scipy.interpolate.NdBSpline`,
  `scipy.interpolate.RegularGridInterpolator`, and
  `scipy.interpolate.RBFInterpolator` gained support.
- Support added for `scipy.stats.alexandergovern`,
`scipy.stats.bootstrap`,
  `scipy.stats.brunnermunzel`, `scipy.stats.chatterjeexi`,
  `scipy.stats.cramervonmises`, `scipy.stats.cramervonmises_2samp`,
`scipy.stats.epps_singleton_2samp`,
`scipy.stats.false_discovery_control`,
`scipy.stats.fligner`, `scipy.stats.friedmanchisquare`,
`scipy.stats.iqr`,
  `scipy.stats.kruskal`, `scipy.stats.ks_1samp`, `scipy.stats.levene`,
  `scipy.stats.lmoment`, `scipy.stats.mannwhitneyu`,
`scipy.stats.median_abs_deviation`, `scipy.stats.mode`,
`scipy.stats.mood`,
  `scipy.stats.ansari`,
`scipy.stats.power`, `scipy.stats.permutation_test`,
`scipy.stats.sigmaclip`,
  `scipy.stats.wilcoxon`, and `scipy.stats.yeojohnson_llf`.
- `scipy.stats.pearsonr` has gained support for JAX and Dask backends.
- `scipy.stats.variation` has gained support for the Dask backend.
- `marray` support was added for `stats.gtstd`,
`stats.directional_stats`,
  `stats.bartlett`, `stats.variation`, `stats.pearsonr`, and
  `stats.entropy`.

# Deprecated features and future changes

- The `scipy.odr` module is deprecated in v1.17.0 and will be completely
removed in v1.19.0. Users are suggested to use the `odrpack` package
instead.
- The default dype behavior of `scipy.sparse.diags` and
  `scipy.sparse.diags_array` will change in v1.19.0.
- In v1.19.0, `scipy.linalg.hankel` will no longer ravel
multidimensional
  inputs and instead will treat them as a batch.
- The `precenter` argument of `scipy.signal.lombscargle` is deprecated
and
will be removed in v1.19.0. Furthermore, some arguments will become
keyword
  only.
- For `scipy.stats.anderson`, the tuple-unpacking behavior of the return
object
  and attributes `critical_values`, `significance_level`, and
`fit_result` are deprecated. Use the new `method` parameter to avoid the
  deprecation warning. Beginning in SciPy 1.19.0, these features will
  no longer be available, and the object returned will have attributes
  `statistic` and `pvalue`.
- For `scipy.stats.anderson_ksamp`, the `midrank` parameter is
deprecated
and the new `variant` parameter should be preferred. This also means
that
  the presence of the `critical_values` return array is deprecated.

# Expired deprecations

- `scipy.stats.find_repeats` has been removed. Please use
  `numpy.unique`/`numpy.unique_counts` instead.
- `scipy.linalg` functions for Toeplitz matrices no longer ravel n-d
input
  arguments; instead, multidimensional input is treated as a batch.
- The `seed` and `rand` functions from `scipy.linalg.interpolative` have
  been removed. Use the `rng` argument instead.
- Complex inputs to `scipy.spatial.distance.cosine` and
  `scipy.spatial.distance.correlation` now raise an error.
- Support for object arrays and longdoubles has been removed from
`scipy.signal.correlate`, `scipy.signal.convolve`,
`scipy.signal.lfilter`,
  and `scipy.signal.sosfilt`.
- `kulczynski1` and `sokalmichener` have been removed from
  `scipy.spatial.distance`.
- `kron` has been removed from `scipy.linalg`. Please use `numpy.kron`.
- Accidentally exposed functions have been removed from
  `scipy.interpolate.interpnd`.
- The `random_state` and `permutation` arguments of
  `scipy.stats.ttest_ind` have been removed.
- `sph_harm`, `clpmn`, `lpn`, and `lpmn` have been removed from
  `scipy.special`.

# Backwards incompatible changes

- The resulting shapes for `transform.Rotation.from_euler` /
`from_davenport` have changed to make them consistent with broadcasting
rules. Angle inputs to Euler angles must now strictly match the number
of
provided axes in the last dimension. The resulting `Rotation` has the
shape
`np.atleast_1d(angles).shape[:-1]`. Angle inputs to Davenport angles
must
also match the number of axes in the last dimension. The resulting
`Rotation`
  has the shape `np.broadcast_shapes(np.atleast_2d(axes).shape[:-2],
  np.atleast_1d(angles).shape[:-1])`.

# Other changes

- The version of the Boost Math library leveraged by SciPy has been
  increased from `1.88.0` to `1.89.0`.
- On POSIX operating systems, SciPy will now use the `'forkserver'`
multiprocessing context on Python 3.13 and older for `workers=<an-int>`
calls if the user hasn't configured a default method themselves. This
follows
  the default behavior on Python 3.14.
- Initial support for 64-bit integer (ILP64) BLAS and LAPACK libraries
has been
added. To enable it, build SciPy with `-Duse-ilp64=true` meson option,
and make
sure to have a LAPACK library which exposes both LP64 and ILP64 symbols.
Currently supported LAPACK libraries are MKL and Apple Accelerate. Note
that:

- the ILP64 support is optional, and is in addition to the
always-available
    LP64 interface;
  - at runtime, you can select the ILP64 variants via the
    `get_{blas,lapack}_funcs` functions:
`scipy.linalg.lapack.get_lapack_funcs(..., use_ilp64="preferred")`
selects
    the ILP64 variant if available and LP64 variant otherwise;
  - `cython_blas` and `cython_lapack` modules always contain the LP64
    routines for ABI compatibility.

Please report any issues with ILP64 you encounter.

# Authors

- Name (commits)
- h-vetinari (3)
- Joshua Alexander (1) +
- Amit Aronovitch (1) +
- Ayush Baranwal (1) +
- Cristrian Batrin (1) +
- Marco Berzborn (1) +
- Ole Bialas (1) +
- Om Biradar (1) +
- Florian Bourgey (2)
- Jake Bowhay (103)
- Matteo Brivio (1) +
- Dietrich Brunn (34)
- Johannes Buchner (2) +
- Evgeni Burovski (292)
- Nicholas Carlini (1) +
- Luca Cerina (1) +
- Christine P. Chai (35)
- Saransh Chopra (1)
- Lucas Colley (121)
- Björn Ingvar Dahlgren (2) +
- Sumit Das (1) +
- Hans Dembinski (1)
- John M Dusel (1) +
- DWesl (4)
- Pieter Eendebak (6)
- Kian Eliasi (2)
- Rob Falck (1)
- Abdullah Fayed (3) +
- Emmanuel Ferdman (2) +
- Filipe Laíns (1) +
- Daniel Fremont (1) +
- Neil Girdhar (1)
- Ilan Gold (35)
- Nathan Goldbaum (3) +
- Ralf Gommers (124)
- Nicolas Guidotti (1) +
- Geoffrey Gunter (1) +
- Matt Haberland (183)
- Joren Hammudoglu (60)
- Jacob Hass (2) +
- Nick Hodgskin (1) +
- Stephen Huan (1) +
- Guido Imperiale (41)
- Gert-Ludwig Ingold (1)
- Jaime Rodríguez-Guerra (2) +
- Jan Möseritz-Schmidt (2) +
- JBlitzar (1) +
- Adam Jones (2)
- Dustin Kenefake (1) +
- Robert Kern (3)
- Gleb Khmyznikov (1) +
- Daniil Kiktenko (1) +
- Pascal Klein (2) +
- kleiter (1) +
- Oliver Kovacs (1) +
- Koven (1) +
- Abhishek Kumar (2) +
- Arthur Lacote (2) +
- Eric Larson (7)
- Mouad Leachouri (1) +
- Tristan Leclercq (1) +
- Antony Lee (5)
- Jesse Livezey (8)
- Philip Loche (1)
- Yuxi Long (4) +
- Christian Lorentzen (1)
- Joshua Markovic (1) +
- Gabryel Mason-Williams (1) +
- mcdigman (1) +
- Rafael Menezes (1) +
- Stefano Miccoli (1) +
- Michał Górny (2)
- Jost Migenda (7) +
- Suriyaa MM (1) +
- Andrew Nelson (72)
- newyork\_loki (2) +
- Nick ODell (34)
- Dimitri Papadopoulos Orfanos (2)
- Drew Parsons (1)
- Gilles Peiffer (3) +
- Matti Picus (1)
- Jonas Pleyer (2) +
- Ilhan Polat (119)
- Akshay Priyadarshi (2) +
- Mohammed Abdul Rahman (1) +
- Daniele Raimondi (2) +
- Ritesh Rana (1) +
- Adrian Raso (1) +
- Dan Raviv (1) +
- Tyler Reddy (136)
- Lucas Roberts (4)
- Bernard Roesler (1) +
- Mikhail Ryazanov (27)
- Daniel Schmitz (25)
- Martin Schuck (25)
- Dan Schult (33)
- Mugunthan Selvanayagam (1) +
- Scott Shambaugh (14)
- Rodrigo Silva (1) +
- Samaresh Kumar Singh (8) +
- Kartik Sirohi (1) +
- Albert Steppi (179)
- Matthias Straka (1) +
- Theo Teske (1) +
- Noam Teyssier (1) +
- tommie979 (1) +
- Christian Veenhuis (1)
- Pierre Veron (1) +
- Shuhei Watanabe (1) +
- Warren Weckesser (25)
- WhimsyHippo (7) +
- Rory Yorke (2)
- Will Zhang (1) +
- Eric Zitong Zhou (1)
- Tingwei Zhu (1) +
- Zhenyu Zhu (1) +
- ਗਗਨਦੀਪ ਸਿੰਘ (Gagandeep Singh) (38)

A total of 117 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

Complete issue list, PR list, and release asset hashes are available in
the associated
[`README.txt`](https://redirect.github.com/scipy/scipy/releases/download/v1.17.0/README.txt).

###
[`v1.16.3`](https://redirect.github.com/scipy/scipy/releases/tag/v1.16.3):
SciPy 1.16.3

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.16.2...v1.16.3)

# SciPy 1.16.3 Release Notes

SciPy `1.16.3` is a bug-fix release with no new features compared to
`1.16.2`.

# Authors

- Name (commits)
- ChrisAB (1) +
- Lucas Colley (1)
- Ralf Gommers (3)
- Matt Haberland (8)
- Nick ODell (2)
- Ilhan Polat (1)
- Tyler Reddy (28)
- Lucas Roberts (2)

A total of 8 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

The full issue and pull request lists, and the release asset hashes are
available
in the associated `README.txt` file.

###
[`v1.16.2`](https://redirect.github.com/scipy/scipy/releases/tag/v1.16.2):
SciPy 1.16.2

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.16.1...v1.16.2)

# SciPy 1.16.2 Release Notes

SciPy `1.16.2` is a bug-fix release with no new features
compared to `1.16.1`. This is the first stable release of
SciPy to provide Windows on ARM wheels on PyPI.

# Authors

- Name (commits)
- Dietrich Brunn (1)
- Ralf Gommers (6)
- Adam Jones (1)
- Gleb Khmyznikov (1) +
- Jost Migenda (1) +
- newyork\_loki (1)
- Nick ODell (3)
- Dimitri Papadopoulos Orfanos (1)
- Ilhan Polat (2)
- Tyler Reddy (26)
- Mugunthan Selvanayagam (1) +
- Shuhei Watanabe (1) +

A total of 12 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

The full issue and pull request lists, and the release asset hashes are
available
in the associated `README.txt` file.

###
[`v1.16.1`](https://redirect.github.com/scipy/scipy/releases/tag/v1.16.1):
SciPy 1.16.1

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.16.0...v1.16.1)

# SciPy 1.16.1 Release Notes

SciPy `1.16.1` is a bug-fix release that adds support for Python
`3.14.0rc1`,
including PyPI wheels.

# Authors

- Name (commits)
- Evgeni Burovski (1)
- Rob Falck (1)
- Ralf Gommers (7)
- Geoffrey Gunter (1) +
- Matt Haberland (2)
- Joren Hammudoglu (1)
- Andrew Nelson (2)
- newyork\_loki (1) +
- Ilhan Polat (1)
- Tyler Reddy (25)
- Daniel Schmitz (1)
- Dan Schult (2)

A total of 12 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

The full issue and pull request lists, and the release asset hashes are
available
in the associated `README.txt` file.

###
[`v1.16.0`](https://redirect.github.com/scipy/scipy/releases/tag/v1.16.0):
SciPy 1.16.0

[Compare
Source](https://redirect.github.com/scipy/scipy/compare/v1.15.3...v1.16.0)

# SciPy 1.16.0 Release Notes

SciPy `1.16.0` is the culmination of 6 months of hard work. It contains
many new features, numerous bug-fixes, improved test coverage and better
documentation. There have been a number of deprecations and API changes
in this release, which are documented below. All users are encouraged to
upgrade to this release, as there are a large number of bug-fixes and
optimizations. Before upgrading, we recommend that users check that
their own code does not use deprecated SciPy functionality (to do so,
run your code with `python -Wd` and check for `DeprecationWarning` s).
Our development attention will now shift to bug-fix releases on the
1.16.x branch, and on adding new features on the main branch.

This release requires Python `3.11-3.13` and NumPy `1.25.2` or greater.

# Highlights of this release

- Improved experimental support for the Python array API standard,
including
new support in `scipy.signal`, and additional support in `scipy.stats`
and
`scipy.special`. Improved support for JAX and Dask backends has been
added,
  with notable support in `scipy.cluster.hierarchy`, many functions in
  `scipy.special`, and many of the trimmed statistics functions.
- `scipy.optimize` now uses the new Python implementation from the
[`PRIMA`](https://www.libprima.net) package for COBYLA. The PRIMA
implementation [fixes many
bugs](https://redirect.github.com/libprima/prima#bug-fixes)
in the old Fortran 77 implementation with [a better performance on
average](https://redirect.github.com/libprima/prima#improvements).
- `scipy.sparse.coo_array` now supports n-D arrays with reshaping,
arithmetic and
  reduction operations like sum/mean/min/max. No n-D indexing or
  `scipy.sparse.random_array` support yet.
- Updated guide and tools for migration from sparse matrices to sparse
arrays.
- Nearly all functions in the `scipy.linalg` namespace that accept array
  arguments now support N-dimensional arrays to be processed as a batch.
- Two new `scipy.signal` functions, `scipy.signal.firwin_2d` and
`scipy.signal.closest_STFT_dual_window`, for creation of a 2-D FIR
filter and
  `scipy.signal.ShortTimeFFT` dual window calculation, respectively.
- A new class, `scipy.spatial.transform.RigidTransform`, provides
functionality
to convert between different representations of rigid transforms in 3-D
  space.
- A new function `scipy.ndimage.vectorized_filter` for generic filters
that
  take advantage of a vectorized Python callable was added.

# New features

# `scipy.io` improvements

- `scipy.io.savemat` now provides informative warnings for invalid field
names.
- `scipy.io.mmread` now provides a clearer error message when provided
with
  a source file path that does not exist.
- `scipy.io.wavfile.read` can now read non-seekable files.

# `scipy.integrate` improvements

- The error estimate of `scipy.integrate.tanhsinh` was improved.

# `scipy.interpolate` improvements

- Batch support was added to `scipy.interpolate.make_smoothing_spline`.

# `scipy.linalg` improvements

- Nearly all functions in the `scipy.linalg` namespace that accept array
  arguments now support N-dimensional arrays to be processed as a batch.
See
[`linalg_batch`](https://scipy.github.io/devdocs/tutorial/linalg_batch.html)
for details.
- `scipy.linalg.sqrtm` is rewritten in C and its performance is
improved. It
also tries harder to return real-valued results for real-valued inputs
if
possible. See the function docstring for more details. In this version
the
  input argument `disp` and the optional output argument `errest` are
  deprecated and will be removed four versions later. Similarly, after
changing the underlying algorithm to recursion, the `blocksize` keyword
  argument has no effect and will be removed two versions later.
- Wrappers for `?stevd`, `?langb`, `?sytri`, `?hetri` and
  `?gbcon` were added to `scipy.linalg.lapack`.
- The default driver of `scipy.linalg.eigh_tridiagonal` was improved.
- `scipy.linalg.solve` can now estimate the reciprocal condition number
and
  the matrix norm calculation is more efficient.

# `scipy.ndimage` improvements

- A new function `scipy.ndimage.vectorized_filter` for generic filters
that
  take advantage of a vectorized Python callable was added.
- `scipy.ndimage.rotate` has improved performance, especially on ARM
platforms.

# `scipy.optimize` improvements

- COBYLA was updated to use the new Python implementation from the
  [`PRIMA`](https://www.libprima.net)package.
The PRIMA implementation [fixes many
bugs](https://redirect.github.com/libprima/prima#bug-fixes)
in the old Fortran 77 implementation. In addition, it results in [fewer
function evaluations on
average](https://redirect.github.com/libprima/prima#improvements)
  but it depends on the problem and for some
  problems it can result in more function evaluations or a less optimal
result. For those cases the user can try modifying the initial and final
  trust region radii given by `rhobeg` and `tol` respectively. A larger
  `rhobeg` can help the algorithm take bigger steps initially, while a
  smaller `tol` can help it continue and find a better solution.
For more information, see the [PRIMA
documentation](https://www.libprima.net).
- Several of the `scipy.optimize.minimize` methods, and the
  `scipy.optimize.least_squares` function, have been given a `workers`
keyword. This allows parallelization of some calculations via a map-like
  callable, such as `multiprocessing.Pool`. These parallelization
opportunities typically occur during numerical differentiation. This can
greatly speed up minimization when the objective function is expensive
to
  calculate.
- The `lm` method of `scipy.optimize.least_squares` can now accept
  `3-point` and `cs` for the `jac` keyword.
- The SLSQP Fortran 77 code was ported to C. When this method is used
now the
constraint multipliers are exposed to the user through the `multiplier`
  keyword of the returned `scipy.optimize.OptimizeResult` object.
- NNLS code has been corrected and rewritten in C to address the
performance
  regression introduced in 1.15.x
- `scipy.optimize.root` now warns for invalid inner parameters when
using the
  `newton_krylov` method
- The return value of minimization with `method='L-BFGS-B'` now has
a faster `hess_inv.todense()` implementation. Time complexity has
improved
  from cubic to quadratic.
- `scipy.optimize.least_squares` has a new `callback` argument that is
applicable
  to the `trf` and `dogbox` methods. `callback` may be used to track
  optimization results at each step or to provide custom conditions for
  stopping.

# `scipy.signal` improvements

- A new function `scipy.signal.firwin_2d` for the creation of a 2-D FIR
Filter
  using the 1-D window method was added.
- `scipy.signal.cspline1d_eval` and `scipy.signal.qspline1d_eval` now
provide
an informative error on empty input rather than hitting the recursion
limit.
- A new function `scipy.signal.closest_STFT_dual_window` to calculate
the
  `scipy.signal.ShortTimeFFT` dual window of a given window closest to a
  desired dual window.
- A new classmethod `scipy.signal.ShortTimeFFT.from_win_equals_dual` to
create a `scipy.signal.ShortTimeFFT` instance where the window and its
dual
are equal up to a scaling factor. It allows to create short-time Fourier
  transforms which are unitary mappings.
- The performance of `scipy.signal.convolve2d` was improved.

# `scipy.sparse` improvements

- `scipy.sparse.coo_array` now supports n-D arrays using binary and
reduction
  operations.
- Faster operations between two DIA arrays/matrices for: add, sub,
multiply,
  matmul.
- `scipy.sparse.csgraph.dijkstra` shortest\_path is more efficient.
- `scipy.sparse.csgraph.yen` has performance improvements.
- Support for lazy loading of `sparse.csgraph` and `sparse.linalg` was
  added.

# `scipy.spatial` improvements

- A new class, `scipy.spatial.transform.RigidTransform`, provides
functionality
to convert between different representations of rigid transforms in 3-D
  space, its application to vectors and transform composition.
It follows the same design approach as
`scipy.spatial.transform.Rotation`.
- `scipy.spatial.transform.Rotation` now has an appropriate `__repr__`
method,
and improved performance for its
`scipy.spatial.transform.Rotation.apply`
  method.

# `scipy.stats` improvements

- A new function `scipy.stats.quantile`, an array API compatible
function for
  quantile estimation, was added.
- `scipy.stats.make_distribution` was extended to work with existing
discrete
distributions and to facilitate the creation of custom distributions in
the
  new random variable infrastructure.
- A new distribution, `scipy.stats.Binomial`, was added.
- An `equal_var` keyword was added to `scipy.stats.tukey_hsd` (enables
the
  Games-Howell test) and `scipy.stats.f_oneway` (enables Welch ANOVA).
- The moment calculation for `scipy.stats.gennorm` was improved.
- The `scipy.stats.mode` implementation was vectorized, for faster batch
  calculation.
- Support for `axis`, `nan_policy`, and `keepdims` keywords was added to
  `scipy.stats.power_divergence`, `scipy.stats.chisquare`,
  `scipy.stats.pointbiserialr`, `scipy.stats.kendalltau`,
  `scipy.stats.weightedtau`, `scipy.stats.theilslopes`,
  `scipy.stats.siegelslopes`, `scipy.stats.boxcox_llf`, and
  `scipy.stats.linregress`.
- Support for `keepdims` and `nan_policy` keywords was added to
  `scipy.stats.gstd`.
- The performance of `scipy.stats.special_ortho_group` and
`scipy.stats.pearsonr`
  was improved.
- Support for an `rng` keyword argument was added to the `logcdf` and
`cdf` methods of `multivariate_normal_gen` and
`multivariate_normal_frozen`.

# Array API Standard Support

Experimental support for array libraries other than NumPy has been added
to
multiple submodules in recent versions of SciPy. Please consider testing
these features by setting the environment variable `SCIPY_ARRAY_API=1`
and
providing PyTorch, JAX, CuPy or Dask arrays as array arguments.

Many functions in `scipy.stats`, `scipy.special`, `scipy.optimize`, and
`scipy.constants` now provide tables documenting compatible array and
device
types as well as support for lazy arrays and JIT compilation. New
features with
support and old features with support added for SciPy 1.16.0 include:

- Most of the `scipy.signal` functionality
- `scipy.ndimage.vectorized_filter`
- `scipy.special.stdtrit`
- `scipy.special.softmax`
- `scipy.special.log_softmax`
- `scipy.stats.quantile`
- `scipy.stats.gstd`
- `scipy.stats.rankdata`

Features with extended array API support (generally, improved support
for JAX and Dask) in SciPy 1.16.0 include:

- many of the `scipy.cluster.hierarchy` functions
- many functions in `scipy.special`
- many of the trimmed statistics functions in `scipy.stats`

SciPy now has a CI job that exercises GPU (CUDA) support, and as a
result
using PyTorch, CuPy or JAX arrays on GPU with SciPy is now more
reliable.

# Deprecated features

- The unused `atol` argument of `scipy.optimize.nnls` is deprecated and
will
  be removed in SciPy 1.18.0.
- The `disp` argument of `scipy.linalg.signm`, `scipy.linalg.logm`, and
  `scipy.linalg.sqrtm` will be removed in SciPy 1.18.0.
- `scipy.stats.multinomial` now emits a `FutureWarning` if the rows of
`p`
do not sum to `1.0`. This condition will produce NaNs beginning in SciPy
  1.18.0.
- The `disp` and `iprint` arguments of the `l-bfgs-b` solver of
`scipy.optimize`
  have been deprecated, and will be removed in SciPy 1.18.0.

# Expired Deprecations

- `scipy.sparse.conjtransp` has been removed. Use `.T.conj()` instead.
- The `quadrature='trapz'` option has been removed from
`scipy.integrate.quad_vec`, and `scipy.stats.trapz` has been removed.
Use
  `trapezoid` in both instances instead.
- `scipy.special.comb` and `scipy.special.perm` now raise when
`exact=True`
  and arguments are non-integral.
- Support for inference of the two sets of measurements from the single
  argument `x` has been removed from `scipy.stats.linregress`. The data
  must be specified separately as `x` and `y`.
- Support for NumPy masked arrays has been removed from
  `scipy.stats.power_divergence` and `scipy.stats.chisquare`.
- A significant number of functions from non-public namespaces
  (e.g., `scipy.sparse.base`, `scipy.interpolate.dfitpack`) were cleaned
  up. They were previously already emitting deprecation warnings.

# Backwards incompatible changes

- Several of the `scipy.linalg` functions for solving a linear system
(e.g.
`scipy.linalg.solve`) documented that the RHS argument must be either
1-D or
2-D but did not always raise an error when the RHS argument had more the
two dimensions. Now, many-dimensional right hand sides are treated
according
to the rules specified in
[`linalg_batch`](https://scipy.github.io/devdocs/tutorial/linalg_batch.html).
- `scipy.stats.bootstrap` now explicitly broadcasts elements of `data`
to the
  same shape (ignoring `axis`) before performing the calculation.
- Several submodule names are no longer available via `from scipy.signal
import *`,
but may still be imported directly, as detailed at
[scipy/scipy-stubs#549](https://redirect.github.com/scipy/scipy-stubs/pull/549).

# Build and packaging related changes

- The minimum supported version of Clang was bumped from 12.0 to 15.0.
- The lowest supported macOS version for wheels on PyPI is now 10.14
instead of
  10.13.
- The sdist contents were optimized, resulting in a size reduction of
about 50%,
  from 60 MB to 30 MB.
- For `Cython>=3.1.0`, SciPy now uses the new `cython --generate-shared`
functionality, which reduces the total size of SciPy's wheels and
on-disk
  installations significantly.
- SciPy no longer contains an internal shared library that requires
RPATH support,
  after `sf_error_state` was removed from `scipy.special`.
- A new build option `-Duse-system-libraries` has been added. It allows
  opting in to using system libraries instead of using vendored sources.
  Currently `Boost.Math` and `Qhull` are supported as system build
  dependencies.

# Other changes

- A new accompanying release of `scipy-stubs` (`v1.16.0.0`) is
available at
<https://github.com/scipy/scipy-stubs/releases/tag/v1.16.0.0>
- The internal dependency of `scipy._lib` on `scipy.sparse` was removed,
  which reduces the import time of a number of other SciPy submodules.
- Support for free-threaded CPython was improved: the last known
thread-safety
issues in `scipy.special` were fixed, and `pytest-run-parallel` is now
used
  in a CI job to guard against regressions.
- Support for
[`spin`](https://redirect.github.com/scientific-python/spin) as a
developer
CLI was added, including support for editable installs. The
SciPy-specific
`python dev.py` CLI will be removed in the next release cycle in favor
of
  `spin`.
- The vendored Qhull library was upgraded from version 2019.1 to 2020.2.
- A large amount of the C++ code in `scipy.special` was moved to the new
header-only [`xsf`](https://redirect.github.com/scipy/xsf) library. That
library was
  included back in the SciPy source tree as a git submodule.
- The `namedtuple`-like bunch objects returned by some SciPy functions
  now have improved compatibility with the `polars` library.
- The output of the `rvs` method of `scipy.stats.wrapcauchy` is now
mapped to
  the unit circle between 0 and `2 * pi`.
- The `lm` method of `scipy.optimize.least_squares` now has a different
behavior
for the maximum number of function evaluations, `max_nfev`. The default
for
  the `lm` method is changed to `100 * n`, for both a callable and a
numerically estimated jacobian. This limit on function evaluations
excludes
those used for any numerical estimation of the Jacobian. Previously the
default when using an estimated jacobian was `100 * n * (n + 1)`,
because
the method included evaluations used in the estimation. In addition, for
the
`lm` method the number of function calls used in Jacobian approximation
is no longer included in `OptimizeResult.nfev`. This brings the behavior
  of `lm`, `trf`, and `dogbox` into line.

# Authors

- Name (commits)
- h-vetinari (4)
- aiudirog (1) +
- Anton Akhmerov (2)
- Thorsten Alteholz (1) +
- Gabriel Augusto (1) +
- Backfisch263 (1) +
- Nickolai Belakovski (5)
- Peter Bell (1)
- Benoît W. (1) +
- Evandro Bernardes (1)
- Gauthier Berthomieu (1) +
- Maxwell Bileschi (1) +
- Sam Birch (1) +
- Florian Bourgey (3) +
- Charles Bousseau (2) +
- Richard Strong Bowen (2) +
- Jake Bowhay (127)
- Matthew Brett (1)
- Dietrich Brunn (53)
- Evgeni Burovski (254)
- Christine P. Chai (12) +
- Gayatri Chakkithara (1) +
- Saransh Chopra (2) +
- Omer Cohen (1) +
- Lucas Colley (91)
- Yahya Darman (3) +
- Benjamin Eisele (1) +
- Donnie Erb (1)
- Sagi Ezri (58) +
- Alexander Fabisch (2) +
- Matthew H Flamm (1)
- Karthik Viswanath Ganti (1) +
- Neil Girdhar (1)
- Ralf Gommers (162)
- Rohit Goswami (4)
- Saarthak Gupta (4) +
- Matt Haberland (326)
- Sasha Hafner (1) +
- Joren Hammudoglu (11)
- Chengyu Han (1) +
- Charles Harris (1)
- Kim Hsieh (4) +
- Yongcai Huang (2) +
- Lukas Huber (1) +
- Yuji Ikeda (2) +
- Guido Imperiale (105) +
- Robert Kern (2)
- Harin Khakhi (2) +
- Agriya Khetarpal (4)
- Daniil Kiktenko (1) +
- Kirill R. (2) +
- Tetsuo Koyama (1)
- Jigyasu Krishnan (1) +
- Abhishek Kumar (2) +
- Pratham Kumar (3) +
- David Kun (1) +
- Eric Larson (3)
- lciti (1)
- Antony Lee (1)
- Kieran Leschinski (1) +
- Thomas Li (2) +
- Yuxi Long (2) +
- Christian Lorentzen (2)
- Loïc Estève (4)
- Panos Mavrogiorgos (1) +
- Nikolay Mayorov (2)
- Melissa Weber Mendonça (10)
- Michał Górny (1)
- Miguel Cárdenas (2) +
- Swastik Mishra (1) +
- Sturla Molden (2)
- Andreas Nazlidis (1) +
- Andrew Nelson (209)
- Parth Nobel (1) +
- Nick ODell (9)
- Giacomo Petrillo (1)
- Victor PM (10) +
- pmav99 (1) +
- Ilhan Polat (74)
- Tyler Reddy (128)
- Érico Nogueira Rolim (1) +
- Pamphile Roy (10)
- Mikhail Ryazanov (6)
- Atsushi Sakai (9)
- Marco Salathe (1) +
- sanvi (1) +
- Neil Schemenauer (2) +
- Daniel Schmitz (20)
- Martin Schuck (1) +
- Dan Schult (33)
- Tomer Sery (19)
- Adrian Seyboldt (1) +
- Scott Shambaugh (4)
- ShannonS00 (1) +
- sildater (3) +
- Param Singh (1) +
- G Sreeja (7) +
- Albert Steppi (133)
- Kai Striega (3)
- Anushka Suyal (2)
- Julia Tatz (1) +
- Tearyt (1) +
- Elia Tomasi (1) +
- Jamie Townsend (2) +
- Edgar Andrés Margffoy Tuay (4)
- Matthias Urlichs (1) +
- Mark van Rossum (1) +
- Jacob Vanderplas (2)
- David Varela (2) +
- Christian Veenhuis (3)
- vfdev (1)
- Stefan van der Walt (2)
- Warren Weckesser (5)
- Jason N. White (1) +
- windows-server-2003 (5)
- Zhiqing Xiao (1)
- Pavadol Yamsiri (1)
- Rory Yorke (3)
- Irwin Zaid (4)
- Austin Zhang (1) +
- William Zijie Zhang (1) +
- Zaikun Zhang (1) +
- Zhenyu Zhu (1) +
- Eric Zitong Zhou (11) +
- Case Zumbrum (2) +
- ਗਗਨਦੀਪ ਸਿੰਘ (Gagandeep Singh) (45)

A total of 126 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully
complete.

Complete issue list, PR list, and release asset hashes are available in
the associated `README.txt`.

</details>

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNzkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-10 17:34:34 +00:00
Bo 5e874b55cf Evaluate installed skills on isolated Go work (#1125)
AgentOps previously relied on behavioral probes and retrospective
summaries to assess skills. This adds a development-only evaluator that
runs a frozen installed skill package on isolated Go tasks, preserves
failed and interrupted attempts, and rebuilds a comparison readout from
native results without another model call.

The suite contains six task families, separate executable verifiers,
frozen launch identities, native session accounting, and a focused
`skill-eval` maintenance workflow. The readout separates passing code
from completed trials, retains incomplete cost information, and reports
missing evidence without claiming equivalence or uplift. `ao eval`
remains retired; no new runtime controller or required core skill is
introduced.

Validation: Go build/vet/race checks and all repository CI passed.
Focused reader/statistics, receipt integrity, verifier integrity,
fixture calibration, generated projections, and the local aggregate
runner passed. A real two-variant Docker preparation check verifies that
frozen worker and verifier images survive later staging.

The bounded coding pilot retained all 24 starts and produced eight
comparable pairs across six task families, with no observed paired
endpoint difference. The separate eight-start memory experiment did not
demonstrate incremental benefit and does not promote another guidance
rule. Individual runtime limits were enforced; aggregate desktop
deadline enforcement remains unproven. Raw trial evidence and
credentials stay outside Git.
2026-09-10 13:29:10 -04:00
Bo 9eb4aed225 Tighten RPI handoffs and exercise them on a Go gate repair (#1124)
## What

Clarify the existing RPI and Implement skills so delegated work
preserves consumer input selection, carries a short check list, uses
task-only runtime dispatch, and leaves final subject evidence to the
integrating caller. Exact identity, required checks, affected evidence
handling, and fresh independent judgment remain required.

Exercise the revised guidance on one real Go defect: learning-file read
errors now fail the gate with the affected path, while genuinely deleted
files retain their existing skip behavior. Routing, learning roots,
exclusions, and frontmatter rules are preserved.

## Why

The prior repair run finished successfully but repeatedly loaded context
and assembled overlapping evidence. This change refines existing skill
instructions and their architecture/projections, then tests observable
behavior with a bounded coding task. It adds no scheduler, skill,
schema, or benchmark framework; one trial does not establish general
token savings.

## How I tested

- Existing skill contract checks pass before and after; generated
projections are current.
- Go regression is RED for unreadable learning paths under both roots;
repaired tests and deletion controls pass.
- Combined Go build/race-shuffle coverage tests, coverage floor,
complexity, and local aggregate pass. Exact-source worker lint and hook
vet results are reused.
- All 52 selected gates pass. Authoritative CI passed after one
unchanged rerun of a timeout-test fixture failure; the original failure
and uncertain cause remain retained. No test tolerance or source change
was used to obtain green.
- Fresh author-distinct Codex/OpenAI validation passed every criterion
and all 13 changed paths at `dd7714ea4eee2f6525656fb70c2ac8b264a39a03`;
no actionable findings or unchecked acceptance.

## Checklist

- [x] Go build and tests pass
- [x] No secrets or credentials added
- [x] Changed skill output boundary documented in architecture and
generated copies
2026-09-10 09:51:08 -04:00
Bo 8a9a01a70a Fix Go recovery, gate routing, evidence, and handoff defects (#1123)
## What

Repair 13 audited Go CLI defects across doctor recovery, gate routing,
evidence ingestion, and session handoffs. Doctor preserves recoverable
snapshots and reports unresolved findings; gates retain exact
changed-file scope and advisory semantics; malformed evidence fails
closed; handoffs report observed Git state and chronological recency.

## Why

These failures could overwrite recovery data, skip required checks,
admit malformed evidence, or restore stale context. Each defect has a
regression witness. Existing skill contracts remain unchanged for this
bounded workflow evaluation.

## How I tested

- Regression witnesses failed before repair and pass after repair.
- Combined Go build, vet, race/shuffle tests with coverage, coverage
floor, pinned lint, and complexity checks pass.
- Generated projections are current; local aggregate reports 10 passed,
0 failed, 1 optional skip.
- All 52 selected gates pass. Authoritative Linux/Windows correctness,
security, full registry, and installation CI pass.
- Fresh author-distinct OpenAI/Codex review verified all 13 repairs and
all 33 changed paths on `84029ee533be0a73ac6c882eb9cf7369d52a0055`,
including independent critical race regressions; no findings or
unchecked acceptance.
- Directory reverse moves retain the existing advisory-lock concurrency
boundary; this does not claim exhaustive hostile filesystem-race
coverage.

## Checklist

- [x] Go build and tests pass, including race detection
- [x] No secrets or credentials added
- [x] Compatibility behavior documented in the changed contract where
applicable
2026-09-10 00:13:04 -04:00
Bo 3b9a68e5e7 Find component-owned checks before implementation edits (#1122)
Implement previously told workers to choose a useful first check without
explicitly finding the edited component's own validators or test
consumers. During the preceding skill rewrite, the component validators
were discovered only after the full integration suite reported
contract-wording failures.

The skill now directs workers to find nearby validation scripts and
tests consuming edited paths or contract wording, and run the smallest
applicable existing check before and after editing. Required integration
checks, RED/green baseline distinctions, acceptance and fresh final
validation remain intact. Only Implement and its generated companions
change.

Validation: the unchanged component validator passes on the original and
edited skills, and rejects a controlled missing-contract fixture in
under 0.02 seconds on the local host. This demonstrates the check's
usefulness, not guaranteed future agent behavior or token savings. The
aggregate runner, regeneration check, applicable gates, full CI
(including Linux Bats) and fresh independent final review passed. The
reviewer independently replayed the 0/1/0 probes, verified all five
changed paths and found no unchecked acceptance.
2026-09-09 20:33:18 -04:00
Bo 600c2eb1f7 Simplify core skills and reduce repeated context work (#1121)
The core skills repeated context, bookkeeping and review instructions,
and Implement required verbatim check output in handoffs. That
encouraged unnecessary reading and repeated logs during longer work.

This change simplifies RPI, Plan, Implement and Validate and regenerates
their Codex/Gemini projections. It asks agents to resolve consequential
uncertainty, use task-specific context and evidence references, repair
known failures directly, and stop at accepted completion. Exact
intent/subject identity, required checks, scope disclosure,
author-distinct freshness and independent final judgment remain
required. Optional mechanics stay in existing references.

The four canonical files shrink from 4,102 to 2,740 whitespace-delimited
words (about 33%). That measures source length, not proven savings in
task tokens or cost. No CLI, CI or Makefile behavior changes.

Validation: the final full Bats suite, aggregate runner, regeneration
checks, applicable gates and all required CI checks pass. Fresh
author-distinct review passed every criterion and all 17 changed paths
with no unchecked acceptance. Five failure-based reasoning scenarios
preserved direct implementation, compact evidence handoff, direct
repair, refusal to excuse failed acceptance, and respect for skills-only
scope. These scenarios judge the guidance; they are not live runtime
cost measurements. The initial rewrite broke existing literal
contract-sentence and documented-invocation checks; the checked wording
was restored, preserving the tests and the failure history.
2026-09-09 19:39:52 -04:00
Bo 17849bbc24 Improve CLI checkpoint recovery, evidence status, and skill search (#1120)
A failed mining-checkpoint write could truncate the saved watermark and
cause retry to replay older events. The CLI also wrote evidence to
external roots that status could not inspect. This batch fixes those
behaviors and removes duplicate normalization from skill search.

- Mining checkpoints use the existing atomic storage writer. A real
partial-write regression test proves old bytes survive and retry retains
stable event IDs. Existing mode bits are preserved; new checkpoints use
0600. Symlink and special-file destinations are rejected before reading.
Before replacement, an empty same-directory probe checks ownership and
permission metadata, including ACLs and inherited permissions.
Unverifiable or different metadata returns an error and leaves the prior
checkpoint intact. This is a conservative refusal, not ACL migration. A
directory-sync error after rename can leave the new state visible.
- `ao status --evidence-root PATH` inspects an explicit existing non-Git
store, with matching text/JSON/YAML reports, no fallback on invalid
roots, and no reads through evidence symlinks. Omitted-flag behavior
remains unchanged.
- Skill-query normalization has one implementation, preserving
repetition versus first-occurrence semantics. Nine fixed shipped-catalog
queries remain byte-identical against a source-pinned baseline.

Validation: Go build, vet, tests, race/shuffle with atomic coverage,
repository Bats and aggregate suites, regeneration, applicable gates and
lint passed. Final Linux and Windows correctness CI and all required
checks passed. A fresh author-distinct review verified every acceptance
criterion across all 23 changed paths with no unchecked scope. Nine
production-query outputs match the source-pinned baseline.

The first CI attempt exposed a test-child coverage flush under its
temporary file-size limit; the test now restores that limit before exit.
Fresh review then exposed ACL loss despite green CI. The permission
guard and native regression tests repair that defect while preserving
the original access requirement. The failure cases and repair costs are
retained in the evaluation.
2026-09-09 18:48:58 -04:00
Bo 6f499fb259 Apply coding-trial lessons to the existing workflow (#1119)
Coding trials exposed late lint failures, reviews started while code was
still changing, and a completed worker that did not resume when only
sent a message. This update puts the existing lint checks earlier,
requires completed checks and frozen content before final judgment, and
clarifies the native worker resume boundary. Comparative refactor
evaluations also pin their baseline before edits.

Changes stay in seven existing workflow sources and their generated
projections. No new skill, gate, framework or timeout is added.

Validation: fresh author-distinct review PASS over all 23 changed paths;
full Bats suite, aggregate runner, regeneration check and worktree gates
passed. The reviewed content digest remains unchanged after rebasing
onto current main. These are workflow guidance changes; the following
three bounded Go cases will test their application.
2026-09-09 17:41:41 -04:00
renovate[bot] 4afe8c5439 chore(deps): update anthropics/claude-code-action digest to 19dda84 (#1118)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/5ccc3a35a6367cdb8e6fbd0728287467540ecfe2..19dda84776b3518d98b8798e591daee763049ed3))
| action | digest | `5ccc3a3` → `19dda84` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC43MS4wIiwidXBkYXRlZEluVmVyIjoiNDQuNzEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-09 21:35:31 +00:00
Bo 1091de1670 Fix OKF frontmatter boundary and reduce checksum allocations (#1117)
## What

Fix the inclusive 64 KiB frontmatter limit in `ao provenance check-okf`,
which rejected valid near-limit LF/CRLF headers. Stream session prefix
checksums through a fixed buffer while preserving existing digests,
events and watermark state.

## Why

The boundary now measures header payload bytes correctly. Checksum
allocation for synthetic 1 MiB and 8 MiB tool outputs drops from
approximately 2.1 MB and 16.8 MB to 4.4 KB. Small inputs incur the
fixed-buffer cost; this is not a total-CLI memory claim.

## How I tested

Regression tests demonstrated the boundary failure before its fix.
Thirteen frozen checksum cases passed before and after the refactor; ten
actual CLI scenarios preserved exact event/error/state bytes. Go build,
vet, full tests, race/shuffle, lint, Bats, aggregate checks,
regeneration verification and applicable worktree gates passed. Fresh
author-distinct reviews covered each exact change. Existing optional
Bats skips are retained.

## Checklist

- [x] Go build and tests pass
- [x] No secrets or credentials in changes
- [x] Public APIs and output contracts preserved
2026-09-09 17:28:06 -04:00
Bo e1fae0dae6 Make the engineering harness lean and add optional topic memory (#1116)
RPI now owns the authorized outcome through finish, with Plan and Memory
loaded only when useful. Known defects get direct repair, and evidence
can change the approach under unchanged acceptance. Fresh exact-content
validation remains required. Memory provides optional recall, mining and
curation of reviewed topic pages; specialists and the fixed-dispatch
adapter remain optional.

The change reconciles current documentation and generated skill
projections. It preserves native budget and permission authority, BD
work ownership, protected external evidence storage and the distinction
between a supported lesson and demonstrated later benefit. It adds no
scheduler, work store, Go command or evidence schema.

Validation: required local Go/build/vet/race checks, aggregate suite,
generated-output check and 72 gates pass. The complete 44-test executor
suite passes; its shared-deadline fixture now tolerates CI scheduling
jitter while still requiring deadline exhaustion and preventing a third
launch. Fresh author-distinct review passed all 112 changed paths with
no findings; all seven exact-head CI checks passed at bfce33cce. Native
restricted-source enforcement and reduced token use are not established
by this change.
2026-09-09 10:10:29 -04:00
Bo db1a0573ea Add bounded source reads and pinned OKF profile checks (#1114)
Adds two explicit read-only operations for the context delivery
lifecycle: bounded raw source reads with reversible bytes and integrity
checks, and structural checking of the pinned AgentOps OKF page profile.

Source reads require independently selected context policy and enforce a
measured serialized-output bound before emitting content. Emitted bytes
do not establish host delivery or understanding; restricted-source
processing remains unavailable without native enforcement. The OKF
checker rejects missing status and incompatible profiles, and never
grants truth, disclosure, or usefulness approval.

Validation: focused tests and Linux/Windows source-reader builds passed.
The combined candidate is undergoing the required full repository checks
and fresh independent review before landing.
2026-09-09 09:37:34 -04:00
renovate[bot] 2c09814a27 chore(deps): update anthropics/claude-code-action digest to 5ccc3a3 (#1115)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/0d0e0876d3eaa933f45dc692f7a4312c83caf36f..5ccc3a35a6367cdb8e6fbd0728287467540ecfe2))
| action | digest | `0d0e087` → `5ccc3a3` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNjkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-09 02:18:30 +00:00
renovate[bot] 1953c3cf13 chore(deps): update anthropics/claude-code-action digest to 0d0e087 (#1113)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/9c5ddab2e6d17b83ea679153b31f1d5f023cf636..0d0e0876d3eaa933f45dc692f7a4312c83caf36f))
| action | digest | `9c5ddab` → `0d0e087` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNjkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-08 23:04:48 +00:00
Bo 57ece9fb7b Restore private context routes and verify native judgment receipts (#1112)
Add explicit, recoverable private context routing through `ao config
context`, binding native source, owner, task, model and destination to
existing policy and external storage. Recovery reads the original Beads
maintenance anchor; configuration reports native access enforcement as
unattested.

Add `ao provenance verify-judgments` to check required review profiles
against exact native transcript receipts, independent subject and
acceptance, distinct contexts, completion and permitted providers.
Requested identity and unreported effort do not count as runtime
evidence. The verdict schema is unchanged.

Repair the existing cleanup test: a 0.3-second budget could expire
during preparation before either fixture process started. A separate
controlled-delay test now proves preparation cannot renew that deadline.
The running-cleanup case requires parent/child readiness, preserved
partial output, the postlaunch cleanup result and both processes stopped
within its existing four-second bound. Production timeout behavior is
unchanged.

Validation: fresh author-distinct review passed the exact 55-path final
subject and all T05/T21 acceptance. The complete local Bats run passed
(1,333 passed, two existing skips), as did Go build/vet/test/race, all
72 full-mode gates, the aggregate and generated-output checks.
Ubuntu/Windows CI, security and both installation jobs passed on the
final commit. The final evidence scan found no new orphaned bindings; 73
historical bindings remain preserved. Earlier failed results and private
evidence remain outside the PR.
2026-09-08 18:57:08 -04:00
Bo 8061085c89 Ship native evidence helpers and fresh-family review defaults (#1110)
AO now performs intent snapshots, subject manifests, strict evidence
verification, atomic verdict storage, and orphan inspection through the
Go binary. The command handler keeps verification separate from
presentation so it meets the existing complexity limit. These operations
preserve the existing evidence formats, require explicit protected
storage where applicable, and run outside a checkout without Python. The
unchanged Python implementation remains a developer oracle; agents still
provide semantic judgment.

Codex and Claude skills now default to a fresh reviewer from the
author’s model family. Callers can explicitly request cross-model review
or pin its model. Reviewer adapters use a finite caller timeout or
remaining deadline instead of a fixed ten-minute default, while
retaining output limits and abnormal-termination cleanup.

Validation: Go build, vet, tests and race/shuffle tests; 1,334 shell
tests; aggregate runner; regeneration check; 72 full-mode gates.
Independent checks exercised 84 storage-boundary rejections and 21
evidence operations with an empty PATH. Both canonical and generated RPI
reference suites pass all 48 tests after updating the migrated oracle
import without weakening assertions.

Change-sensitive checks explicitly compare the final committed candidate
with the original PR base. Linux, Windows, installer, security, and
required summary checks are green.
2026-09-08 16:06:33 -04:00
renovate[bot] 10ac80e6f2 fix(deps): update module golang.org/x/text to v0.42.0 (#1111)
This PR contains the following updates:

| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [golang.org/x/text](https://pkg.go.dev/golang.org/x/text) | [`v0.41.0`
→
`v0.42.0`](https://cs.opensource.google/go/x/text/+/refs/tags/v0.41.0...refs/tags/v0.42.0)
|
![age](https://developer.mend.io/api/mc/badges/age/go/golang.org%2fx%2ftext/v0.42.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/go/golang.org%2fx%2ftext/v0.41.0/v0.42.0?slim=true)
|

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNjkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-08 20:06:23 +00:00
Bo fa6b0b075a Preserve work-session associations before handoff (#1109)
Interrupted agents can lose their connection to work when that
connection is recorded only in the final handoff. The RPI, Implement,
native dispatch, Handoff and CASS skills now carry the work identity
into startup and preserve observed session, child and resume
relationships through caller-owned native records. Unknown identities
and unrelated work spans remain explicit, and retrieval follows the
source’s access and disclosure policy.

The generated Codex and Gemini projections are updated from the source
skills. Validation exercised the installed skills with fresh, forked and
resumed native sessions interrupted before handoff, checked source
injection and access denials, and reconstructed startup facts from
native work records. The supported installation used repository links;
portable package acceptance remains separate.

Local verification: full Go build/vet/tests and race/shuffle, all Bats
suites, the aggregate runner, regeneration check, and all 72 AO gates
passed on the final subject.
2026-09-07 20:32:02 -04:00
Bo af1e530159 Adopt CDLC contracts and reconcile BD tooling (#1108)
AgentOps now describes the selected Context Delivery Lifecycle alongside
standalone RPI: external reviewed memory, native work and runtime
ownership, independent validation, and explicit limits on what the
pilots proved. The active ADRs name which historical prescriptions are
superseded and which invariants remain.

This integrates the BD foundation, including doctor diagnostics that
distinguish BD from BR and protection against private tracker data
entering outgoing Git history. It also fixes skills audit resolution of
explicit relative reference paths. Source-owned projections were
regenerated, and the landed stopping behavior is preserved.

Validation: Go build/vet/test and race/shuffle, 1,325 Bats cases, the
local aggregate, and full AO gates. The gate registry reports 71 passes
and one nonblocking preamble-adoption failure on the existing report
script; that advisory remains disclosed. Historical probe receipts whose
source hashes changed remain historical evidence.

This is foundation adoption. It does not claim that the later memory,
goal, background, privacy-release, or benefit-measurement work is
implemented.

Independent Astra and Fable judgments both PASS over the exact
integrated content. Earlier negative results and their factual
resolution remain preserved in private work evidence.
2026-09-07 19:07:21 -04:00
Bo baa24e1b04 Bound headless execution and require acceptance-linked repair progress (#1107)
Headless invocations could run without a finite bound, and repair loops
could count changed digests or finding counts as progress. The existing
adapter now enforces positive finite deadlines, an optional inherited
absolute deadline, bounded output capture and cleanup of its owned
process group, refusing execution when protection is unavailable.

The existing goal, RPI and validation skills now require
acceptance-linked progress, distinguish newly discovered failures from
regressions, and bound Andon recovery. Review effort follows the effect
on acceptance and enforcement. These contracts do not claim native
aggregate goal-budget or pause enforcement.

Validation on the clean main baseline:
- 1,317 Bats cases, zero failures, two skips; 46 RPI reference cases.
- Go build, vet, tests and race/shuffle tests; local aggregate runner.
- Generated projections current; all 72 AO gates pass.
- Fresh independent Astra and Fable 5.1 xhigh judgments passed the exact
clean source.

Earlier uncommitted CDLC adoption, private work/evidence, and unrelated
Go changes are excluded from this PR.
2026-09-07 13:51:38 -04:00
renovate[bot] 00fbabe981 chore(deps): update anthropics/claude-code-action digest to 9c5ddab (#1106)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/d75b94d5ad426cb8546e6628b6f5f19b84e5cce1..9c5ddab2e6d17b83ea679153b31f1d5f023cf636))
| action | digest | `d75b94d` → `9c5ddab` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42MS4zIiwidXBkYXRlZEluVmVyIjoiNDQuNjEuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-06 05:00:33 +00:00
Bo 021b41c951 Skills only: cut the RPI workflow script and the machinery around the loop (#1105)
## Skills only: cut the RPI workflow script and the machinery around the
loop

#1104 landed the right ideas in the wrong form. This repository is
skills only: a skill is an instruction to a system, models route and
judge, and deterministic checks exist where reality is deterministic
(digests, tests, gates, "is this file tracked"). #1104 built a workflow
script and a set of schemas, enums, and engines where instruction was
wanted, and then spent four judge rounds hardening them. This PR deletes
that and keeps the ideas as instruction.

**Deleted.** `workflows/rpi.js` and everything that existed only to
exercise it: its probe harness in the product-boundary suite, the
convergence-law and glob-intersection fixture corpora, the cathedral
canaries that pinned its mechanisms, and the pointers to it.

**Reverted to the #1099 form.** `skills/rpi/scripts/run_once.py` and its
tests: the repair law as accepted in the loop restore, without the
class-law machinery, the snapshot verification, or the cross-leg checks.

**Kept.** `docs.claims-tracked` (a blocking gate that caught a real
stale claim on its first run), `scripts/evidence-orphans.sh` (a receipt
a shell script computes), the optional `findings[].class` field on
`verdict.v2` (a word a validator writes), and the corrected harvest-note
sentence.

**Kept as instruction.** The rpi, plan, implement, validate, council,
learn, and boundaries contracts and `docs/architecture/rpi-traversal.md`
now say, in plain sentences a model follows: a risky change gets one
fresh judge on the frozen plan before Implement; validators name a class
per finding and a returning class means go back to Plan; two judges
disagreeing is the orchestrator's decision made in the open, with both
reads in the report and a risky surface still needing both to pass; the
orphan receipt runs after Implement and each repair and rides in the
check receipts; a doc sentence that says published, pinned, or proven is
a claim to check; Learn proposes a check for any repeating finding
class.

**Evidence on the tip.** Regen check clean; rpi unit tests; cathedral
gate; routing goldens; token budgets; coverage 1 of 12; Go bar; full
gate green with a HEAD-built binary; CI's bats command green;
gate-tightening ratchet. One fresh read by Fable 5.1, asked in plain
language for what it found, recorded in the PR thread.
2026-09-06 01:32:51 +00:00
Bo 2ef932b617 RPI flow: premortem on risky plans, finding class in the law, adjudicated splits, orphaned evidence, doc claims gated (#1104)
## RPI flow: premortem on risky plans, finding class in the law,
adjudicated splits, orphaned evidence, doc claims gated

Provenance: running the loop for real across three trains on 2026-09-03
(#1099, #1100, #1101). The spine held; the flow around it did not. A
risky-surface design shipped with no premortem and needed six repair
passes. The open finding set grew three rounds running inside one class
while the id-counting law watched. A same-family PASS and a cross-family
FAIL had no tie-break until the caller named one afterwards. Every
harness edit orphaned bound evidence with no warning until verify
failed. A doc called an egress log published while the repository's
`*.log` rule kept it out of the tree, and the same overclaim class came
back four rounds.

**What changes.**
- **Premortem at plan exit.** When the write scope hits a risky surface,
one fresh judge reads the frozen plan before Implement; a blocking
finding returns NOT_PLANNED with the findings. The caller may declare
`premortem: skip`; the report says so.
- **A split is recorded, never elected and never closed inside the
loop.** The law stands: a risky surface converges only when both legs
PASS, and no finding leaves the open set because someone chose a judge.
Plan declares `binding_judge` as the caller's disposition for a split
that survives repair; it is bound in the plan identity, carried in the
report, and never mutates the verdict. On a risky split that survives
the repair budget (never after a law stop), one council leg receives a
bounded packet marked untrusted and returns per-finding rulings, exactly
one per id, which the traversal validates and records under
`council.rulings` for the caller's next intent; the verdict and the open
finding set stay exactly as repair left them. A council closure
mechanism was built, drew a new finding class in three consecutive judge
rounds (path containment, digest exclusion, presence-as-evidence,
partial closure downgrading a FAIL), and was cut under the train's own
class rule rather than hardened again. A non-risky split stays worst-of.
- **Finding class in the convergence law.** Findings carry an optional
stable `class`. A class carried by a resolved id that reappears on a new
id with no surviving prior id carrying it is `class_reopened`, whether
or not a classless round sits between; a blank class is an invalid
round; a round can carry both a reopened id and a reopened class and
stops on either. Repair stops, the traversal returns NOT_PROVEN, and the
caller goes back to Plan, because the design is wrong, not the patch.
Same rule in `run_once.py` and `workflows/rpi.js`, driven by one shared
fixture file, with executed canaries in the cathedral gate.
- **Plan identity, and the premortem's risky test.** On a risky scope
the Plan carries `binding_judge` and the evidence it expects to orphan;
`plan_digest`, when the plan declares one, must equal the script's
digest over the acceptance, the write scope, the binding judge, and the
intent-source digest, or the traversal stops before Implement. The risky
test over a declared scope is glob intersection: witness paths, the
risky regexes over the glob with wildcards instantiated, and any literal
prefix that reaches a risky root; a bare `**` or `*` is risky.
- **Intent is verified before anything is built.** An `intent-snapshot`
receipt re-derives the digest and compares the snapshot bytes to the
caller intent before premortem or Implement; absent, mis-hashed, or
wrong stops the traversal with `plan_identity_mismatch`. The Python
reference refuses on the same rule. Declared scopes are canonicalized
(repeated `./` collapsed; absolute paths and `..` refused at plan exit),
and the four spellings of `tests/**` share one plan digest while
`tests/` does not.
- **Orphaned evidence is a receipt, not a surprise.** After Implement
and after every repair round the workflow runs
`scripts/evidence-orphans.sh` over the runtime-derived path union, keyed
on the round so a same-set repair still reruns it and appends every
scorecard and fixture set whose bound evaluator or skill digests cover
them to the check receipts the validator reads, each with a cause
(`changed_path`, `digest_drift`, `both`, `skill_changed`). Plan budgets
that recapture up front. On today's tree the receipt already lists the
08-16 and 08-26 sets whose bound harness digests moved long ago.
- **Doc claims are gated.** The stronger scan already caught one stale
claim in the tree (a 2026-06-22 harvest note calling evidence committed
after Train 2 had removed that tree); the sentence now says where the
evidence went. `docs.claims-tracked` (blocking) requires backticked repo
paths in `evals/` and `docs/evals/` markdown to be tracked, and
sentences that say published, tracked, or committed to name files that
exist.
- **Risky scope is a glob intersection, not a heuristic.** One
segment-wise `globsIntersect` over one list of risky segment globs
answers both the declared-scope question at Plan exit and the
changed-path question for the cross-family rule; two heuristic designs
missed in opposite directions and were replaced rather than patched.
- **Contracts.** rpi gains a judgment dispatch table: risky scope routes
to premortem, a risky split to council, an irreversible landing to
one-way-door as a caller choice. plan, implement, validate, premortem,
council, and learn carry their halves; learn proposes a deterministic
check for any finding class that repeats.
`docs/architecture/rpi-traversal.md` is the source of record and was
updated with the flow.

**Evidence on the tip.** Regen check clean; Go bar; full gate green with
a HEAD-built binary (the new gate fires and passes); CI's literal bats
command green; rpi unit tests; cathedral gate with executed canaries for
the class law; routing goldens; token budgets; gate-tightening ratchet;
coverage 1 of 12 unchanged.

**Judgment, stated plainly.** Six judging rounds, each on a frozen tip.
The caller elected Fable 5.1 as the binding validator; its round-6
verdict is PASS with no verdict-driving findings (lows: a council
payload outside the schema throws a raw error instead of recording
`invalid-rulings`; two stale comments; a dead parameter; a dead fixture
element; the contracts say exactly one ruling per finding while the code
enforces at most one). The cross-family Codex read of the same tip
failed on three input-validation items, which the final commit closes:
control characters are now refused on the original scope value with the
full Unicode control class and the caller scope is canonicalized in
place so one spelling reaches every prompt; the intent receipt no longer
forgives a trailing-newline difference; and the Python reference accepts
a digest string only from a verifier callback and matches digests with
`fullmatch`. One half of one Codex item stays open and is disclosed: the
workflow does not itself hash the caller intent's bytes to compare with
the plan's declared digest (it relies on the receipt's exact-bytes match
plus digest equality); binding that locally means every probe fixture
carries a real digest of its intent text, which is the next pass. Also
open, pre-existing and outside this train: the risky-surface list names
`lib/**` while the preamble every gate sources lives under
`scripts/lib/`. Across the rounds the loop behaved as designed once: the
council closure mechanism drew a fresh finding class three rounds
running and was cut under the train's own class rule instead of hardened
a fourth time.
2026-09-05 23:03:51 +00:00
renovate[bot] 71d9ccf4ad chore(deps): update anthropics/claude-code-action digest to d75b94d (#1103)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/ef8bb1e43bf303cff727a1dd0b8837029fe982a2..d75b94d5ad426cb8546e6628b6f5f19b84e5cce1))
| action | digest | `ef8bb1e` → `d75b94d` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42MS4zIiwidXBkYXRlZEluVmVyIjoiNDQuNjEuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-04 22:11:16 +00:00
renovate[bot] d96a7e4f40 chore(deps): update anthropics/claude-code-action digest to ef8bb1e (#1102)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/fa2b2666b747000bf42767d1f332065b375e3c8f..ef8bb1e43bf303cff727a1dd0b8837029fe982a2))
| action | digest | `fa2b266` → `ef8bb1e` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC42MS4zIiwidXBkYXRlZEluVmVyIjoiNDQuNjEuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-04 01:48:42 +00:00
Bo 1cebfee94d Measure one skill: sealed probe dispatch and the first current ledger row (#1101)
## Measure one skill: filesystem-sealed probe dispatch and the first
current ledger row

Provenance: the instrument-panel roadmap
(`docs/plans/2026-08-26-instrument-panel-roadmap.md`) closed out with
zero skills measured because control-arm reps read
`skills/<skill>/SKILL.md` from the checkout and the operator's skill
roots mid-run. Its named successor was filesystem-sealed dispatch. This
PR builds the seal, then uses it, and the instrument caught one more
leak on the way.

**The seal.** Codex's own seatbelt does not nest inside an outer
`sandbox-exec` profile, so a rep now runs under an outer profile with
Codex's sandbox bypassed for exactly that reason: `file-read*` denied on
the checkout and every skill root (`~/.agents`, `~/.claude/skills`,
`~/.gemini/skills`, `~/.codex/skills`), `file-write*` denied everywhere
except the rep's workspace, a scratch HOME, and the temp roots. HOME and
CODEX_HOME are scratch (auth symlinked). Dispatch refuses without
`sandbox-exec` unless `PROBE_SEAL=none` is set, which marks the run
coverage-ineligible. The seal is recorded in the capture contract
(`agentops-skill-probe-capture.v3`, a `seal` block), coverage
eligibility requires `seal.mode == seatbelt`, and `verify-scorecard`
re-checks that the denied roots include the repository and the four
skill roots. Existing 08-26 sets become `legacy-unsealed` and
ineligible, which changes nothing they were counting.

**The leak the seal did not cover.** The first sealed capture showed the
xhigh control-2 rep listing the shared live workspace, finding
`treatment-1.prompt`, and reading it; the treatment prompt embeds the
skill. So every rep now gets its own empty workspace, prompts reach a
rep on stdin only, raw JSONL and stderr live in a harness-private
dispatch directory the rep can only stat, and a `sibling-prompt-read`
trap degrades any rep whose successful command names a prompt, contract,
seal, or stage file or whose output lists a sibling's artifacts.
Replaying the contaminated set under the new trap turns its REGRESSIVE
into INERT with the contaminated rep degraded; that set is superseded
and not committed.

**The second pass, after the judges read the first.** A Fable validator
passed the first sealed capture with four findings and a Codex read
failed it with seven, all real: the whole per-user temp tree stayed
readable (hundreds of stale probe directories held prompt files with the
canonical skill bytes), sibling checkouts and the real `~/.codex`
sessions were readable because seatbelt matches the traversed path and
the skill roots are symlinks into the main checkout, the dispatch
directory was writable so a rep could rename an earlier prompt into its
workspace, the contract trusted asserted seal metadata (a hand-made
Linux record was coverage-eligible), the only real-Darwin test nested
seatbelt and proved nothing, and the operator's `config.toml` was
symlinked in whole, so every rep started the operator's MCP servers. The
seal is now one run directory removed on exit (`home/ ws/ tmp/
dispatch/`, reset per rep); reads are denied under the real HOME, the
real TMPDIR, `/tmp`, the checkout, the git common directory, and each
skill root's resolved target; `dispatch/` is write-denied with
metadata-only reads; `file-link` and `file-clone` are denied on every
denied root; the rep's config is rebuilt from top-level scalars only and
`auth.json` is copied, not linked. The contract binds platform,
mechanism, wrapper, the denied and allowed roots, the rep environment,
and the sanitization, and coverage refuses any record that omits them;
the Darwin test performs its reads inside the seal. One recorded hole
remains by necessity: the codex launcher under `~/.local/bin` and
`~/dev/dotfiles/bin` is re-allowed by literal path, and coverage refuses
any allowed path inside the checkout.

**The third pass, after the judges read the second.** Both judges failed
the hardened tip again, and the headline was network: bypassing codex's
own sandbox to nest the outer seal had dropped every inner deny, not
only the filesystem ones, so a rep could fetch the canonical skill from
GitHub while the disk was sealed. A rep now reaches the network only
through a harness-owned CONNECT proxy
(`scripts/lib/probe-connect-proxy.py`) with a host allowlist discovered
from real runs (`chatgpt.com`, `ab.chatgpt.com`, the rotating
`.oaiusercontent.com` suffix, and the API-key hosts), behind a seatbelt
`network*` deny that admits only the proxy; every attempt is logged, a
refused one degrades the rep, and web search is disabled in the rep's
config. The profile is now rendered from the bound seal block by one
function, so `verify-scorecard` reconstructs it and requires the digest
to match; the recorded launcher chain is the only allowed read under a
denied root; the wrap invokes `/usr/bin/sandbox-exec` by absolute path;
the real CODEX_HOME and the Darwin cache directory are denied and bound;
every non-stdio descriptor is closed and `/dev` writes narrowed to four
devices; each rep runs in its own process group that must be empty
before the next reset; one minimal config is generated per run, bound by
text and digest, and re-parsed after each rep; one guarded trap covers
the run root and any unpublished stage; and the coverage gate prints an
eligibility row for every ledger row that names a scorecard. What stays
open is stated in the README: allow-default still governs what the
profile does not deny.

**The fourth pass, after the judges read the third.** Both judges failed
the third tip on properties the record carried but the verifier did not
check. GNU `timeout` sets its own process group and ran outside the
seal, so the per-rep reap was vacuous (four sleeping survivors after the
test passed); the seal is now the outermost process, timeout runs inside
it with `--foreground`, its absolute path is bound, and the reap counts
survivors before signalling. The verifier now pins, not merely records:
the egress host set (a module constant), port 443 only, no unix sockets,
a loopback proxy, the generated config text equal to the renderer's
output, the real CODEX_HOME and cache root inside the denied roots,
writable roots under the run root, the four device paths, the
environment allowlist, the launcher chain's digest against the producer
identity, and it refuses unknown record fields. The proxy logs an
attempt before dialing, captures the rep at accept time, refuses names
that resolve to private or loopback ranges, and its source joins the
evaluator hash set; the per-rep egress log is published with the fixture
set. Withdrawn ledger rows get their own eligibility reason. The README
lists which seal fields the verifier pins and which it only records; the
cross-capture aggregate is recounted to 4 of 14. Still open and
disclosed: Mach IPC and Apple Events beyond the filesystem and network
seals, exact-byte environment sealing beyond the allowlist, and cleanup
ownership by inode.

**The fifth pass, after the judges read the fourth.** Both judges found
the seal, proxy, reap ordering, transcripts, and scorecards sound and
failed the tip on claims the tree did not hold: the egress log the docs
called published was caught by the repository's `*.log` ignore rule, a
`setsid()` child escaped the process-group reap, and one ledger sentence
said no rep ran a command when a control rep had run `rg` over its empty
workspace. The log is now tracked and required, strictly parsed, with
both allowed and refused counts recomputed per rep; the reap is fatal to
the capture when it cannot prove emptiness and an `lsof` sweep of the
run root catches a session escape; the rep launches through a real `env
-i` boundary; the timeout budget, the launcher chain's adjacency, every
required root in both read and link denies, the evaluator match, and the
trust-table value are pinned by the verifier; and every sentence in the
ledger, README, and runbook names the check that enforces it. The
remaining gap is stated: a child that both escapes the session and holds
nothing under the run root is not detected.

**The sixth pass, after CI read the fifth.** The first CI run of this PR
failed on Linux: the launcher-chain pin walked the capturing Mac's
filesystem, so on the runner both sets read as unsealed and the coverage
headline fell to zero. A pin that holds on one host is not a pin. The
chain is now bound as structure in the seal record (each link's path,
kind, symlink target, and the final file's digest, with the invoked path
as the head), the verifier checks that record on any host, and it
cross-checks the live filesystem only where the head exists, reporting
which happened. A gate-level test runs the coverage gate twice, once
with the chain made absent, and requires byte-identical output.

**The measurement.** `premortem-plan-shape-t2` (two seeded structural
defects, band [1,4]) captured seven times on 2026-09-03, once under each
seal; the first six sets were deleted with their scorecards when a judge
or CI broke that seal. The rows that count are the seventh capture: low
INERT (control 0/2, treatment 0/2) and xhigh INERT (control 1/2,
treatment 1/2); no rep ran a command, no egress was refused, both
per-rep egress logs are tracked and verified, and both scorecards verify
with every pinned field, the launcher chain checked as a record and
cross-checked on the capturing host. The superseded captures read, at
low, BEHAVIORAL 1/1, INERT, INERT, BEHAVIORAL 1/2, INERT, BEHAVIORAL 1/2
and, at xhigh, INERT, BEHAVIORAL 2/2, INERT, INERT, INERT (control 1/2),
INERT. The reversals across captures are recorded as an unresolved N=2
observation, not variance; across all seven the treatment arm put the
marks in band in 7 of 26 usable reps and the control arm in 2 of 28, and
the ledger marks that aggregate as disclosure, not a row. Headroom is
SEPARATED at both levels. This is the first current, manifest-backed
ledger row; it records response-shape behavior change, never quality
uplift, and what it records today is INERT at both levels.

**Evidence on the tip.** Probe, exec-lib, metadata, coverage, headroom,
and adapter bats suites green with the Darwin seal, survivor,
session-escape, and environment-boundary tests running;
`verify-scorecard` on both scorecards; `check-skill-probe-coverage.sh`
reports measured 1 of 12 with the 2026-08-26 row labelled
`verdict-withdrawn`; regen check clean; full gate green with a
HEAD-built binary; CI's bats command green; Go bar, lint, security, and
the gate-tightening ratchet green.

**Judgment, stated plainly.** The caller elected Fable 5.1 as the
binding validator. Its fifth-round verdict on the pre-CI tip was PASS
with no verdict-driving findings; its read of the portability delta
failed on one test-only point (the coverage test had dropped the
`measured` pin that CI tripped on) which this tip restores. The
cross-family Codex reads of the same tips are FAIL. They closed the
network seal, the environment boundary, the fatal reap, the data roots,
the config binding, and the documentation, and they keep these open,
recorded here as the next pass rather than hidden: the evaluator
identity check still accepts the pre-proxy four-file shape for legacy
sets; an inherited absolute `CODEX_EXEC_TIMEOUT_BIN` is trusted without
a probe; a refusal logged under a rep label outside the expected set is
not rejected; an empty top-level `[projects]` table passes the drift
check; the `lsof` sweep treats a failing `lsof` as a clean result; and
the launcher chain, now bound as a record that any host can check, is
corroborated against the filesystem only on the capturing host, so a
record whose head does not exist there is taken on its word (the docs
say so; Codex wants the live walk required at capture and the invoked
head bound into the producer identity). Fable also noted a test that
mis-resolves when TMPDIR sits under `/private/tmp`, a `2026-09-04` date
in one refusal message, and that the low control replies used a `S2:
FINDING <reason>` shape the discriminator scores as "plan not walked"
rather than by band (outcome-invariant). Each of those changes a harness
or verifier file and would orphan the two rows again, so they are filed
as the follow-up instead of an eighth capture today. Across six judging
rounds the open set shrank only from round four on; the convergence
law's stop signal was reached at round three and the run continued on
the caller's instruction to land the instrument. The two ledger rows are
honest about what they measure, and the seal they ran under is the one
this tree can verify on any host.
2026-09-04 01:40:41 +00:00
Bo 10f0277bdb Legible membrane, Train 2: what a stranger meets (#1100)
## Legible membrane, Train 2: what a stranger meets

Provenance: the 2026-09-02 field audit of this repo against
mattpocock/skills, compound-engineering, and the jsm corpus, findings F5
through F9. This train is sized by a consumer inventory built with `rg`
on the tip before any lane was written; the promoted-set directory move
the audit proposed is deferred because that inventory shows
skill-builder backing two blocking gates, swarm pinned by the cathedral
gate and a routing golden, using-gc required by Go code, and `ao skills
link` unable to install a second root. That inventory is the plan for a
later train.

**What changes.**
- **Archival sweep by consumer disposition.** 172 audit snapshots, 29
pawl receipts, the `evals/workbench` and `evals/membrane` trees with
their two bats consumers, four stray scratch docs, four retired eval
contracts, and nine caller-less `scripts/check-*.sh` are deleted; git
history is the archive. Every machine list that referenced them is
pruned (evidence-grounding baseline, preamble grandfather, broken-links
allowlist, `.gitattributes`, `.gitignore`, two eval fixtures, the
workflow-coverage deferred list). `docs/audits/manifests/` and
`.agents/ao/config.yaml` survive because they have live readers. About
48,000 lines.
- **Three skills retired.** `goals` (alias of fitness), `shared`
(tombstone), and `scope` (folded into plan step 3 as five write-scope
checks). Consumers edited; the probe denominator exclusion for goals
pruned; Codex package and golden count pins updated.
- **Negative routing** on research, codebase-recon, reverse-engineer,
premortem, one-way-door, and council, all within the 180-char budget,
with a teardown golden (`rq-08`). One wording was changed after the
router's prefix stemming showed "repository teardown" leaking into the
wrong skill.
- **Every promoted skill answers "It's working if"** with observable
tells in backticks, and carries a paste-ready `## Prompt` with a
concrete subject. Two fictional `ao` subcommands a draft prompt named
were caught by the body-ref validator and replaced with real commands.
- **Doctrine diet on the core five.** rpi, plan, implement, validate,
and anti-ceremony drop from about 5,100 words to 3,600 (bodies from
4,700 to 3,150) by moving the shared ownership boundary, dated
incidents, and mechanics tables into step-loaded references
(`skills/rpi/references/boundaries.md`,
`skills/validate/references/mechanics.md`,
`skills/plan/references/ground-truth-routing.md`). Every cathedral
canary and every skill validator grep survives unchanged.

- **ADR-0018** records the goals, shared, and scope retirement; the
cathedral gate tombstone and the routing goldens cite it instead of
ADR-0017.
- **Router and twins.** `ao skills find` holds a description's "Not for
X; that is <sibling>." sentence out of its haystack, so premortem no
longer ranks first for "is this live decision reversible" (golden
`rq-10` pins the reciprocal of `rq-02`); a penalty variant was tried and
reverted because it suppressed skills the caller named outright. A
declared trigger phrase of two or more words quoted whole in the query
now earns the name weight once, so "check this change" lands on validate
rather than on reality-check's name token; a live-catalog test pins
seven such queries. Single-quoted YAML descriptions unescape `''`. The
Codex catalog keeps the exclusion sentence, and a closing `>` no longer
turns `<run-id>/codebase-recon.json` into an invocation.
- **Residue the judges found.** handoff, learn, and status open a `##
Contract` heading after their tells; validate's prompt names its helper
at `skills/validate/scripts/validate.py`; the explicit-skill prompt
catalog names only live skills (five stale prompts replaced by nine,
floor 20 restored, TESTING.md names the suite); the corpus-delta receipt
binds the runner's path and SHA-256 and labels a `live_agent` claim as
an unverified caller declaration; the probe README and ledger describe
the 12-skill denominator; SKILL-API counts 30 of 54.

**Evidence on the tip.** Regen check clean; full gate green with a
HEAD-built binary; CI's bats command green; Go build/vet/test green;
lint clean; security gate quick PASS; docs-build warnings did not rise.
Fresh validation by Fable 5.1 (caller-elected) and a cross-family read
by Codex, both recorded in the PR thread.

---------

Co-authored-by: Bo <bofuller55@gmail.com>
2026-09-03 19:52:55 +00:00
Bo 568e99d436 Loop restore: converge and crank as control flow under the verdict contract (ADR-0017) (#1099)
## Loop restore: converge and crank as control flow under the verdict
contract (ADR-0017)

Intent source: `docs/plans/2026-09-03-loop-restore.md` (in this PR).
Decision record:
`docs/adr/ADR-0017-loop-as-control-flow-not-knowledge.md`.

**Why.** The 2026-07-14 single-pass cut (`482307762`) removed the
iterate loop (discovery, crank, converge, evolve, the learn write-half)
together with the unproven compounding claim, although ADR-0011 demoted
only the latter. The control flow was never demoted, and its absence
showed on 2026-09-02, when a three-lane fix needed eight validators and
two stops because the contract had no repair phase. This restores the
loop as control flow and nothing else: no knowledge store, no `ao
converge`/`ao crank`, no evolve, no canary. ADR-0004 and ADR-0011 stay
in force.

**What changes.**
- **RPI gains a bounded repair phase.** On `FAIL` or `NOT_PROVEN` with
findings, repair and re-validate freshly under the convergence law:
caller-declared `repair_rounds` (default 2); open finding set keyed by
stable `findings[].id`, union across validator families, non-growing; no
closed id reopens; the subject digest changed or, for `NOT_PROVEN`, new
digest-bound evidence resolved a named gap. Converged = fresh PASS plus
cross-family PASS on risky surfaces. Plan and Implement keep their
single dispatch. `skills/rpi/scripts/run_once.py` models the law as pure
data (33 tests): rounds are validated for shape (digest required, no
duplicate ids, no PASS with findings, no FAIL without findings),
condition 4's evidence branch needs a NOT_PROVEN previous round, a
non-FAIL current round, new evidence, and a resolved finding, and a PASS
over unchanged bytes after a FAIL is a flip that reports NOT_PROVEN.
`workflows/rpi.js` runs validation as legs (spawned or external primary,
plus a caller-supplied `crossFamily.command` on risky surfaces) merged
worst-of with a union of stable ids; a risky surface without a
cross-family leg is `diversity_unsatisfied` and never converges or
enters repair; a failed repair or re-validation returns NOT_PROVEN with
no stale verdict. Validators return `subjectDigest`, stable finding ids,
and `evidenceRefs`.
- **crank returns as a thin wave executor** (113 lines): the caller
selects the wave and the repair bound, crank invokes RPI per lane
(parallel only on disjoint write and regen scopes), runs the wave
acceptance once, returns evidence, and stops. No retry, budget, queue,
claim, lease, Git, closure, or next-work ownership. Routing golden
`rq-07-wave-execution` ranks it first.
- **validate is cross-family by default on risky surfaces**
(`cli/internal/gates/**`, `scripts/check-*.sh`, `tests/**`,
`skills/*/scripts/**`, hook policies, `lib/**`, security-scanned paths)
with the LAW-0 dispatch table: Claude orchestrating uses read-only
`codex exec`; Codex orchestrating uses an interactive Claude session in
an NTM pane, never `claude -p`. No live adapter means
`diversity_unsatisfied`, which on a risky surface is `NOT_PROVEN`. The
full literal CI command set runs once on the final integrated subject;
routine rounds keep the receipt-driven freshness contract.
- **Conformance assertions flipped under ADR-0017 only:**
`scripts/check-cathedral-cut-conformance.py` (crank live; "Stop
regardless" replaced by positive canaries for the law's four conditions;
a bounded `for` loop that compares against `repair_rounds` is required
in `run_repair_phase`, and the gate executes the law's canaries against
the reference behavior), `workflows/rpi.js`,
`skills/rpi/scripts/validate.sh`,
`evals/agentops-core/rpi-behavior.json`,
`skills/rpi/references/rpi.feature`. Every single-pass public surface
(README, AGENTS.md, PRODUCT.md, CI-CD, agent-workflow-reference,
rpi-traversal, cli/README, quickstart and demo commands, the
operating-contract and product-boundary bats, the Codex-description
oracle) now states repair to convergence.

**Known approximation, disclosed.** The Claude conveyor has no
deterministic shell primitive, so changed paths are derived by the fresh
validator (git status and diff against the clean pre-run tree) and
unioned with the implementer's report; risk is classified over that
union and unreported paths are coverage findings. A validator is still a
model; runtime derivation outside every agent is a follow-up. Family
distinctness of the cross-family leg is asserted by the caller's choice
of command and not verified by the script.

**Not in scope.** Premortem stays a single advisory judge and Plan still
only names the first check (phase boundaries unchanged). No `verdict.v2`
or `rpi-report.v1` change. The loop's own effect on outcomes is
unmeasured and owed a seeded-defect probe, like the rest of the corpus.

**Evidence on the tip.** Regen check clean; full gate green with a
HEAD-built binary; CI's bats command green; Go build/vet/test green;
golangci-lint clean; security gate quick PASS; one fresh validator over
the whole diff; one cross-family read of the design before
implementation (13 findings folded) and two of the integrated diff (9
findings in round one, 11 by round two, 15 by round three, each round
repaired and re-reviewed; the fresh validator passed the tip after round
two and the final tip 1e8adb72d passed a fresh validator (14-scenario
independent harness of the law, full gate 71/71 with a HEAD-built
binary, CI bats 1164/0) and a cross-family read by Gemini 3.8 via AGY,
which closed all six remaining residues with no new findings; Codex was
unreachable at push time).

**Follow-ups filed from the final reviews, not blockers:** the JS
violation check tests growth before reopen while Python tests reopen
first (same stop, different label when both occur in one round);
`cli/testdata/compatibility-baseline/families/{demo,quickstart}/case.json`
assert help-text substrings Cobra never prints (pre-existing, no
consumer); runtime derivation of changed paths outside every agent in
the Claude conveyor.
2026-09-03 15:16:08 +00:00
renovate[bot] 44451f898d chore(deps): update anthropics/claude-code-action digest to fa2b266 (#1098)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
|
[anthropics/claude-code-action](https://redirect.github.com/anthropics/claude-code-action)
([changelog](https://redirect.github.com/anthropics/claude-code-action/compare/8251c103ac8c1d761882c86aba1412c7f583c844..fa2b2666b747000bf42767d1f332065b375e3c8f))
| action | digest | `8251c10` → `fa2b266` |

---

### Configuration

📅 **Schedule**: (in timezone America/New_York)

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/boshu2/agentops).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC41Ny4zIiwidXBkYXRlZEluVmVyIjoiNDQuNTcuMyIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-02 23:36:15 +00:00
Bo e556834d3d Legible membrane, Train 1: Codex projection, executable entry points, green run-all, honest runtime docs (#1097)
## Legible membrane, Train 1: fix what ships

Intent source: `docs/plans/2026-09-02-legible-membrane-plan.md` (added
in this PR). Provenance: the 2026-09-02 field audit of this repo against
mattpocock/skills, compound-engineering, and the jsm corpus.

Three defects a stranger hits today, all verified on `main` before the
change:

1. **Codex projection truncated 51 of 56 skill descriptions mid-clause**
(`scripts/codex-sync.sh` capped prose at 44 chars, so the Codex router
read "Freshly judge whether a finished change is Triggers: …"). Now:
first sentence of the source prose plus the full `Triggers:` clause,
abbreviation- and quote-aware; the per-catalog bound is computed live as
"Codex prose average may not exceed Claude's" (cross-multiplied,
floor-free) with a 180-char hard ceiling. `using-flywheel` is exempted
from runtime-phrase rewriting so its cross-runtime text projects
verbatim. The dormant `ao codex ensure-start` emitter and the `# /x`→`#
$x` title rewrite are removed. A literal oracle pins five twins and a
rule oracle covers all 56.
2. **23 shebang-bearing shell entry points were committed
non-executable**, including `scripts/regen-all.sh` and three gate
scripts. Now `100755`, with an advisory gate `shell.exec-bits`
(fast+full, fail-closed on enumeration error, reads the index blob,
skips symlinks by stated policy).
3. **`tests/run-all.sh` was red on `main`**: the GOALS validator
asserted a pre-08-25 file shape, and validate's description exceeded the
180-char budget. The validator now parses only the `## Gates` block
(stops at any heading, like production), requires cited script paths to
exist, takes its path via argv, and fails closed on tokenization; four
negative fixtures. validate's description is 177 chars and gains the
reality-check negative. `AGENTS.md` quotes CI's authoritative bats and
Go commands.

README and `docs/install-day2-ops.md` replace "No other runtime is
required" with a runtime table derived by reading each skill's procedure
(HARD / OPTIONAL / conditional), covered by a bats test that grounds
every HARD row in an invocation line.

Evidence on the tip: full gate 71/71 (HEAD binary), CI's bats command
green across `tests/scripts/*.bats`, `tests/run-all.sh` green, Go
build/vet/test green, golangci-lint clean, security gate quick PASS,
`scripts/regen-all.sh --check` clean. Each lane was validated by a fresh
context; the integrated train had two cross-family (Codex) review rounds
and every finding is closed on this tip.

Out of scope (successor intent): promoted set / `skills-internal/`, the
process-artifact sweep, "It's working if" blocks, routing clusters,
doctrine diet. One pre-existing drift noted for a follow-up:
`packs/agentops-executor/agents/validator/skills/validate/SKILL.md`
carries a stale third description that no gate binds.
2026-09-02 23:29:33 +00:00
Bo b0c81349d0 docs(readme): add anti-ceremony guard and 3.6.0 judgment skills to the inventory (#1096)
## What

Updates the README skill inventory to match what ships since 3.6.0: the
`rpi` row now says it runs the anti-ceremony guard before Plan,
`anti-ceremony` gets its own row in the Core skills table, and the
strategies list gains `one-way-door` and `reality-check`, with a pointer
to `route` for picking the owning skill.

## Why

The Core skills table and the strategies list predated 3.6.0. `rpi`
takes `anti-ceremony` as a hard dependency (`skills/rpi/SKILL.md`), and
`one-way-door`, `reality-check`, and `route` are listed in
`docs/SKILL-ROUTER.md` but were never named in the README. Every other
README link, install path, and mode table was verified against the tree
and left unchanged.

## How I tested

- `markdownlint README.md` passes with the repo config.
- `scripts/check-honest-voice.sh` passes (216 files, no forbidden
claims).
- Every `skills/*/SKILL.md` link in the README resolves to an existing
file.

## Checklist

- [x] `make build && make test` passes (if Go changes) — no Go changes
- [x] No secrets or credentials in code
- [x] Breaking changes documented (if any) — none

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01CXPTKX8F44SGvoHB39F8zY

---
_Generated by [Claude
Code](https://claude.ai/code/session_01CXPTKX8F44SGvoHB39F8zY)_

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-02 13:08:38 -04:00