Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude/skills/visual-review-and-fix/references/the-walk.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ wording is wrong, do not edit one copy. See "If a promise is wrong" at the botto

Three top-level views, and the fragment is the address:

- `#n=sessions` is the default. Session operations leads because the exception-first Attention route
was built first and buried the reader's opening questions in live review (NUI-16 in
- `#n=projects` is the default route. The v2 design moves the entry point up to Projects so the reader
first finds the project and then its sessions (NUI-16 in
[`docs/design-next-ui.md`](../../../../docs/design-next-ui.md)).
- `#n=projects` is the complete map.
- `#n=sessions` is fleet operations.
- `#n=attention` is the gate queue and the coverage disclosure. It has a nav entry as of #287, last
of the three, and the `a` key and the reported-blocks chip in the header still reach it. That chip
appears only while a block is reported, which is why it was never a nav entry's substitute.
Expand Down
37 changes: 3 additions & 34 deletions .github/workflows/quality-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -202,20 +202,7 @@ jobs:
- name: Run the full suite on the floor
run: |
python -m unittest discover -s cargento/skills/cargento/tests -t .
python -m unittest \
scripts.tests.test_validate_plugins \
scripts.tests.test_bump_version \
scripts.tests.test_lint_embedded \
scripts.tests.test_bench_collect \
scripts.tests.test_capture_hook \
scripts.tests.test_bench_event_latency \
scripts.tests.test_derive_prompt_shapes \
scripts.tests.test_capture_team_registry \
scripts.tests.test_capture_terminal_identity \
scripts.tests.test_capture_focus_raise \
scripts.tests.test_serve_operator_cockpit \
scripts.tests.test_mark_abstention \
scripts.tests.test_score_abstention
python -m unittest discover -s scripts/tests -t scripts/tests

test:
name: Tests + coverage threshold
Expand All @@ -242,20 +229,7 @@ jobs:
run: |
coverage erase
coverage run -m unittest discover -s cargento/skills/cargento/tests -t .
coverage run -a -m unittest \
scripts.tests.test_validate_plugins \
scripts.tests.test_bump_version \
scripts.tests.test_lint_embedded \
scripts.tests.test_bench_collect \
scripts.tests.test_capture_hook \
scripts.tests.test_bench_event_latency \
scripts.tests.test_derive_prompt_shapes \
scripts.tests.test_capture_team_registry \
scripts.tests.test_capture_terminal_identity \
scripts.tests.test_capture_focus_raise \
scripts.tests.test_serve_operator_cockpit \
scripts.tests.test_mark_abstention \
scripts.tests.test_score_abstention
coverage run -a -m unittest discover -s scripts/tests -t scripts/tests

# No `coverage report` here. It reads `fail_under` from pyproject and
# exits non-zero, and it ran BEFORE the label check below, so a PR
Expand Down Expand Up @@ -388,12 +362,7 @@ jobs:
- name: Run dashboard test discovery
run: python -m unittest discover -s cargento/skills/cargento/tests -t .
- name: Run script unit tests
run: >-
python -m unittest scripts.tests.test_validate_plugins
scripts.tests.test_bump_version scripts.tests.test_lint_embedded
scripts.tests.test_bench_collect scripts.tests.test_capture_hook
scripts.tests.test_capture_terminal_identity
scripts.tests.test_capture_focus_raise
run: python -m unittest discover -s scripts/tests -t scripts/tests

# The single required status check. Branch protection requires this job, so
# every job above must succeed (a skip or failure anywhere fails the gate).
Expand Down
10 changes: 1 addition & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,15 +218,7 @@ git diff "$(git merge-base origin/main HEAD)"..HEAD \
-- '*plugin.json' '*gemini-extension.json' | grep -E '^[+-].*"version"'
coverage erase
coverage run -m unittest discover -s cargento/skills/cargento/tests -t .
coverage run -a -m unittest \
scripts.tests.test_validate_plugins scripts.tests.test_bump_version \
scripts.tests.test_lint_embedded scripts.tests.test_bench_collect \
scripts.tests.test_capture_hook scripts.tests.test_bench_event_latency \
scripts.tests.test_derive_prompt_shapes scripts.tests.test_capture_team_registry \
scripts.tests.test_capture_terminal_identity \
scripts.tests.test_capture_focus_raise \
scripts.tests.test_serve_operator_cockpit \
scripts.tests.test_mark_abstention scripts.tests.test_score_abstention
coverage run -a -m unittest discover -s scripts/tests -t scripts/tests
coverage report # enforces the fail_under threshold from pyproject.toml
# `test_capture_terminal_identity` and `test_capture_focus_raise` exercise AppleScript
# against Terminal.app, and this suite now sends nothing. It used to: measured on a macOS desk with Terminal
Expand Down
3 changes: 2 additions & 1 deletion scripts/tests/test_mark_abstention.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,8 @@ def test_the_temp_file_is_gone_and_the_mode_is_owner_only(self) -> None:
mark_abstention._write(path, {"v": 2, "marks": {}})
self.assertTrue(os.path.exists(path))
self.assertFalse(os.path.exists(f"{path}.tmp"))
self.assertEqual(0o600, os.stat(path).st_mode & 0o777)
if os.name != "nt":
self.assertEqual(0o600, os.stat(path).st_mode & 0o777)

def test_a_rewrite_replaces_rather_than_appends(self) -> None:
with tempfile.TemporaryDirectory() as root:
Expand Down
39 changes: 39 additions & 0 deletions scripts/tests/test_validate_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -1540,3 +1540,42 @@ def test_mutated_native_name_route_and_gate_mapping_are_rejected(self) -> None:
mutated.write_text(mutated.read_text().replace(before, after))
problems = validator.check_js_adapters(Path(tmp))
self.assertTrue(any(filename in problem for problem in problems), problems)


class ScriptTestsDiscoveryContractTest(unittest.TestCase):
def test_all_script_tests_are_discoverable(self) -> None:
scripts_tests_dir = validator.ROOT / "scripts" / "tests"
test_files = sorted(f.stem for f in scripts_tests_dir.glob("test_*.py"))
self.assertTrue(
len(test_files) >= 13, f"Expected at least 13 test modules, found {len(test_files)}"
)

loader = unittest.defaultTestLoader
suite = loader.discover(str(scripts_tests_dir), top_level_dir=str(scripts_tests_dir))

loaded_modules: set[str] = set()

def _walk_suite(s: Any) -> None:
for item in s:
if isinstance(item, unittest.TestSuite):
_walk_suite(item)
elif isinstance(item, unittest.TestCase):
loaded_modules.add(item.__class__.__module__)

_walk_suite(suite)
for mod in test_files:
self.assertIn(mod, loaded_modules, f"Module {mod} was not discovered by unittest")

def test_workflows_and_agents_use_discovery_not_hand_kept_lists(self) -> None:
quality_gate_path = validator.ROOT / ".github" / "workflows" / "quality-gate.yml"
quality_gate_text = quality_gate_path.read_text(encoding="utf-8")
agents_path = validator.ROOT / "AGENTS.md"
agents_text = agents_path.read_text(encoding="utf-8")

# Must not contain hand-enumerated scripts.tests module lists
self.assertNotIn("scripts.tests.test_bump_version", quality_gate_text)
self.assertNotIn("scripts.tests.test_bump_version", agents_text)

# Must use discover pattern for scripts/tests
self.assertIn("unittest discover -s scripts/tests -t scripts/tests", quality_gate_text)
self.assertIn("unittest discover -s scripts/tests -t scripts/tests", agents_text)