Compare commits

..
Author SHA1 Message Date
dependabot[bot] df1e9a2e2b ci(deps): bump ruff in /.github/requirements in the ci-tooling group
Bumps the ci-tooling group in /.github/requirements with 1 update: [ruff](https://github.com/astral-sh/ruff).


Updates `ruff` from 0.15.21 to 0.16.0
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.15.21...0.16.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-version: 0.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: ci-tooling
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-25 08:03:01 +00:00
14 changed files with 83 additions and 91 deletions
+1 -1
View File
@@ -12,4 +12,4 @@
#
# Regenerate:
# pip-compile --allow-unsafe --generate-hashes --no-emit-index-url --output-file=lint.txt lint.in
ruff==0.15.21
ruff==0.16.0
+19 -19
View File
@@ -4,23 +4,23 @@
#
# pip-compile --allow-unsafe --generate-hashes --no-emit-index-url --output-file=lint.txt lint.in
#
ruff==0.15.21 \
--hash=sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075 \
--hash=sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be \
--hash=sha256:01f8d5be84823c172b389e123174f781f9daf86d6c58719d603f941932195cdd \
--hash=sha256:0f212c5d7d54c01bbfe6dcab02b724a39300f3e34ed7acbe995ccb320a2c58bd \
--hash=sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86 \
--hash=sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341 \
--hash=sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd \
--hash=sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67 \
--hash=sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41 \
--hash=sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d \
--hash=sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d \
--hash=sha256:6e83115d4b9377c1cbc13abf0e051f069fab0ef815ea0504a8a008cee24dd0a8 \
--hash=sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233 \
--hash=sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8 \
--hash=sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500 \
--hash=sha256:d4b8d9a2f0f12b816b50447f6eccb9f4bb01a6b82c86b50fb3b5354b458dc6d3 \
--hash=sha256:e6312e41bc96791299614995ea3a977c5857c3b5662b1ecef6755b02b87cb646 \
--hash=sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f
ruff==0.16.0 \
--hash=sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17 \
--hash=sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d \
--hash=sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af \
--hash=sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09 \
--hash=sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522 \
--hash=sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472 \
--hash=sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0 \
--hash=sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b \
--hash=sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9 \
--hash=sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213 \
--hash=sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb \
--hash=sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed \
--hash=sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717 \
--hash=sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a \
--hash=sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81 \
--hash=sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982 \
--hash=sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e \
--hash=sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4
# via -r lint.in
+4 -4
View File
@@ -17,7 +17,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
# Hash-pinned tool install (Scorecard: Pinned-Dependencies). Pins ruff to
@@ -34,7 +34,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
- run: |
@@ -55,7 +55,7 @@ jobs:
# makes every file look born at HEAD, so every README false-fails as
# "stale". Full history makes CI match a local audit exactly.
fetch-depth: 0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- run: |
@@ -77,7 +77,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
- run: |
+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.12'
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
attestations: write
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
# Hash-pinned tool install (Scorecard: Pinned-Dependencies).
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.13"
# Upgrade pip first: pip-audit scans the whole environment, and the
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: '3.12'
@@ -26,10 +26,10 @@ from aipass.memory.apps.handlers.json import json_handler
DEFAULT_CONFIG: Dict[str, Any] = {
"enabled": True,
"threshold": 0.25,
"max_surfaces_per_session": 12,
"min_messages_between": 1,
"cooldown_seconds": 30,
"threshold": 0.3,
"max_surfaces_per_session": 5,
"min_messages_between": 10,
"cooldown_seconds": 300,
}
+7 -10
View File
@@ -142,23 +142,20 @@ class TestShouldSurfaceHappy:
def test_first_surface_ignores_spacing(self):
"""Fresh session: first prompt with high relevance surfaces immediately."""
# Explicit config: this exercises the spacing mechanism, so it must not
# move whenever DEFAULT_CONFIG is retuned.
cfg = {"min_messages_between": 10, "cooldown_seconds": 300}
state = new_state()
state["messages_since_last"] = 1
ok, reason, updated = should_surface("compass-1", 0.8, state, cfg, current_time=100.0)
ok, reason, updated = should_surface("compass-1", 0.8, state, current_time=100.0)
assert ok is True
assert "ready" in reason.lower()
for i in range(9):
updated = record_message(updated)
ok, reason, _ = should_surface("compass-2", 0.8, updated, cfg, current_time=100.0 + 400 + i)
ok, reason, _ = should_surface("compass-2", 0.8, updated, current_time=100.0 + 400 + i)
assert ok is False
assert "spacing" in reason.lower()
updated = record_message(updated)
ok, _, _ = should_surface("compass-2", 0.8, updated, cfg, current_time=600.0)
ok, _, _ = should_surface("compass-2", 0.8, updated, current_time=600.0)
assert ok is True
@@ -249,7 +246,7 @@ class TestConfigMerging:
assert "threshold" in reason.lower()
def test_default_config_values_match(self):
assert DEFAULT_CONFIG["threshold"] == 0.25
assert DEFAULT_CONFIG["max_surfaces_per_session"] == 12
assert DEFAULT_CONFIG["min_messages_between"] == 1
assert DEFAULT_CONFIG["cooldown_seconds"] == 30
assert DEFAULT_CONFIG["threshold"] == 0.3
assert DEFAULT_CONFIG["max_surfaces_per_session"] == 5
assert DEFAULT_CONFIG["min_messages_between"] == 10
assert DEFAULT_CONFIG["cooldown_seconds"] == 300
@@ -5,6 +5,11 @@
"name": ".ai_mail.local",
"path": ".ai_mail.local"
},
"d002": {
"has_branch_placeholder": false,
"name": ".pytest_cache",
"path": ".pytest_cache"
},
"d003": {
"has_branch_placeholder": false,
"name": ".aipass",
@@ -114,6 +119,16 @@
"has_branch_placeholder": false,
"name": "integrations",
"path": "apps/integrations"
},
"d025": {
"has_branch_placeholder": false,
"name": "v",
"path": ".pytest_cache/v"
},
"d026": {
"has_branch_placeholder": false,
"name": "cache",
"path": ".pytest_cache/v/cache"
}
},
"files": {
@@ -196,7 +211,7 @@
"path": ".trinity/observations.json"
},
"f014": {
"content_hash": "98f1e33dace0",
"content_hash": "d523dee2ef39",
"has_branch_placeholder": false,
"name": "passport.json",
"path": ".trinity/passport.json"
@@ -267,6 +282,12 @@
"name": "README.md",
"path": "apps/plugins/README.md"
},
"f026": {
"content_hash": "3ed731b65d06",
"has_branch_placeholder": false,
"name": ".gitignore",
"path": ".pytest_cache/.gitignore"
},
"f027": {
"content_hash": "024209a8c889",
"has_branch_placeholder": true,
@@ -381,6 +402,24 @@
"name": "requirements.project.txt",
"path": "requirements.project.txt"
},
"f046": {
"content_hash": "37dc88ef9a0a",
"has_branch_placeholder": false,
"name": "CACHEDIR.TAG",
"path": ".pytest_cache/CACHEDIR.TAG"
},
"f047": {
"content_hash": "73fd6fccdd80",
"has_branch_placeholder": false,
"name": "README.md",
"path": ".pytest_cache/README.md"
},
"f048": {
"content_hash": "0575fdabafa9",
"has_branch_placeholder": false,
"name": "nodeids",
"path": ".pytest_cache/v/cache/nodeids"
},
"f049": {
"content_hash": "5610e3ccaf8b",
"has_branch_placeholder": false,
@@ -390,7 +429,7 @@
},
"metadata": {
"description": "Template file tracking registry for ID-based updates",
"last_updated": "2026-07-27",
"last_updated": "2026-07-17",
"version": "1.0.0"
}
}
@@ -14,14 +14,12 @@
"alias": "",
"path": "{{CWD}}",
"module": "{{MODULE}}",
"email": "{{EMAIL}}",
"created": "{{DATE}}",
"git_branch": "work/{{branchname}}"
},
"identity": {
"citizen_class": "{{CITIZEN_CLASS}}",
"role": "{{ROLE}}",
"traits": "{{TRAITS}}",
"purpose": "{{PURPOSE_BRIEF}}",
"what_i_do": [],
"what_i_dont_do": []
@@ -14,14 +14,12 @@
"alias": "",
"path": "{{CWD}}",
"module": "{{MODULE}}",
"email": "{{EMAIL}}",
"created": "{{DATE}}",
"git_branch": "main"
},
"identity": {
"citizen_class": "manager",
"role": "{{ROLE}}",
"traits": "{{TRAITS}}",
"purpose": "{{PURPOSE_BRIEF}}",
"what_i_do": [],
"what_i_dont_do": []
+2 -42
View File
@@ -13,9 +13,10 @@ class-aware update, and backward compatibility.
"""
import json
from pathlib import Path
import pytest
from pathlib import Path
# =============================================================================
# CLASS REGISTRY TESTS
@@ -171,7 +172,6 @@ class TestClassAwareUpdate:
def test_update_cli_accepts_class_with_all(self):
"""update aipass_framework --all should parse correctly and call update_all with class filter."""
from unittest.mock import patch
from aipass.spawn.apps.modules.update import handle_update
# Mock update_all to isolate from real branch state
@@ -220,16 +220,6 @@ class TestTemplateStructure:
passport = json.loads((tpl / ".trinity" / "passport.json").read_text())
assert passport["identity"]["citizen_class"] == "{{CITIZEN_CLASS}}"
@pytest.mark.parametrize("class_name", ["aipass_framework", "project_agent"])
def test_template_passport_has_traits_and_email_placeholders(self, class_name):
"""Agent template passports reference TRAITS and EMAIL — unreferenced, both are built and discarded."""
from aipass.spawn.apps.handlers.class_registry import get_template_dir
tpl = get_template_dir(class_name)
passport = json.loads((tpl / ".trinity" / "passport.json").read_text())
assert passport["identity"]["traits"] == "{{TRAITS}}"
assert passport["branch_info"]["email"] == "{{EMAIL}}"
def test_no_agent_template_dir(self):
"""Old agent.template directory should not exist."""
spawn_root = Path(__file__).parents[1]
@@ -296,36 +286,6 @@ class TestAgentScaffoldContent:
passport = json.loads((target / ".trinity" / "passport.json").read_text())
assert passport["identity"]["role"] == "Data Analyst"
def test_created_agent_passport_has_traits(self, tmp_path):
"""Passport should include the agent's traits if provided."""
from aipass.spawn.apps.modules.core import _spawn_agent
target = tmp_path / "traits_test"
_spawn_agent(str(target), role="Analyst", traits="curious, terse", purpose="Reports")
passport = json.loads((target / ".trinity" / "passport.json").read_text())
assert passport["identity"]["traits"] == "curious, terse"
def test_created_agent_passport_traits_empty_without_flag(self, tmp_path):
"""Omitting traits leaves an empty string — the identity hook skips the line when falsy."""
from aipass.spawn.apps.modules.core import _spawn_agent
target = tmp_path / "no_traits_test"
_spawn_agent(str(target), purpose="Testing default")
passport = json.loads((target / ".trinity" / "passport.json").read_text())
assert passport["identity"]["traits"] == ""
def test_created_agent_passport_has_email(self, tmp_path):
"""Passport carries the branch address, so identity does not render 'Email: unknown'."""
from aipass.spawn.apps.modules.core import _spawn_agent
target = tmp_path / "email_test"
_spawn_agent(str(target), purpose="Testing email")
passport = json.loads((target / ".trinity" / "passport.json").read_text())
assert passport["branch_info"]["email"] == "@email_test"
# =============================================================================
# MULTI-AGENT COEXISTENCE TESTS