# Testing signals — msitarzewski/agency-agents

> Canonical page: https://codevetter.com/unpack/agency-agents/testing-signals

# Testing signals — msitarzewski/agency-agents

Scanned commit 053ddbbf392a1688fc7043d81529f47ef2cf86c8 (2026-09-21). Generated by codevetter codevetter 1.12.0 on 2026-09-22.

Tests are shell scripts and one unittest module, not a pytest or npm suite. They are designed for bash 3.2 and no jq. CI runs installer behavior on Linux and macOS, catalog consistency on every PR, and agent lint only when agent or linter paths change. The generated-output eval needs PyYAML and Python 3.11 tomllib and treats manifest drift as advisory on pull requests. Large gaps are the converter installers other than the two identity tools, and the agent prompt bodies themselves, which no test executes.
- test-install.sh is a custom bash harness (pass/fail/xfail_eq, not a framework). It sets HOME to a mktemp sandbox, refuses to touch the real home, and only installs claude-code and copilot so it does not depend on fresh convert.sh output. It checks --help, --list teams against divisions.json, --dry-run writes zero files, default ~/.claude/agents count equals the frontmatter roster, and --path overrides the default. — [scripts/test-install.sh#L1-L18](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-install.sh#L1-L18) [scripts/test-install.sh#L64-L79](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-install.sh#L64-L79) [scripts/test-install.sh#L148-L180](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-install.sh#L148-L180) [.github/workflows/test-install.yml#L12-L30](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/test-install.yml#L12-L30)
- test-install.yml also runs bash -n on every scripts/*.sh before the harness, on ubuntu-latest and macos-latest, fail-fast false, for every pull_request and every push to main. — [.github/workflows/test-install.yml#L1-L30](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/test-install.yml#L1-L30)
- test-agent-selection.sh asserts --agent definitely-not-an-agent and a bad --agents-file exit non-zero with 'Unknown agent' / 'in agents-file', and that --agent 'Developer Tooling Engineer' dry-runs as Agents: 1. check-tools.yml runs it on every PR and main push. — [scripts/test-agent-selection.sh#L1-L44](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-agent-selection.sh#L1-L44) [.github/workflows/check-tools.yml#L33-L34](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-tools.yml#L33-L34)
- test-convert-frontmatter.sh runs convert.sh for gemini-cli, opencode, and qwen into a temp dir and asserts selected frontmatter fields are single-quoted YAML scalars, including description on developer-tooling-engineer and tools on programmatic-display-buyer. — [scripts/test-convert-frontmatter.sh#L1-L39](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-convert-frontmatter.sh#L1-L39) [.github/workflows/check-tools.yml#L25-L26](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-tools.yml#L25-L26)
- test-convert-outputs.sh is the generated-product eval: round-trip of description, strict YAML/TOML parse, one output per roster agent per tool, and sha256 drift against scripts/convert-outputs.sha256. It requires python3 with yaml and tomllib. CI passes --drift=advisory on pull_request and strict mode on push to main. — [scripts/test-convert-outputs.sh#L1-L69](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-convert-outputs.sh#L1-L69) [scripts/test-convert-outputs.sh#L79-L100](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-convert-outputs.sh#L79-L100) [.github/workflows/check-tools.yml#L28-L31](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-tools.yml#L28-L31)
- check-hermes-plugin.py loads build-hermes-plugin.py, builds into a temp dir, calls register on a RecordingContext, asserts the four tool names and JSON-schema shape, and runs a live search for 'backend architecture' then inspect by the returned slug. — [scripts/check-hermes-plugin.py#L32-L77](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-hermes-plugin.py#L32-L77) [.github/workflows/check-tools.yml#L22-L23](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-tools.yml#L22-L23)
- test-hermes-plugin.py is unittest. It imports the committed integrations/hermes/agency-agents-router/__init__.py if present and drives FakeLifecycle through State.SUCCEEDED, FAILED, CANCELLED, timeouts, and launch errors. That generated __init__.py is gitignored, so a clean checkout does not contain the module the test imports until convert.sh --tool hermes has been run. — [scripts/test-hermes-plugin.py#L1-L70](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-hermes-plugin.py#L1-L70) [.gitignore#L84](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.gitignore#L84)
- check-hermes-config-rewrite.sh is a regression for the plugins.enabled indent bug. The workflow runs it on every PR and main push and documents the two symptoms: wrong indent collapsing enabled into a scalar, and non-idempotent duplicate inserts. — [scripts/check-hermes-config-rewrite.sh#L1-L17](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-hermes-config-rewrite.sh#L1-L17) [.github/workflows/check-hermes-config-rewrite.yml#L1-L24](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-hermes-config-rewrite.yml#L1-L24)
- check-divisions.sh and check-runbooks.sh are CI gates, not unit tests. Divisions must match disk, both AGENT_DIRS arrays, lint-agents.yml path filters, and each division must contain at least one frontmatter file. Runbooks must be valid JSON, have unique slugs, existing doc paths, and roster stems that git ls-files can resolve. — [scripts/check-divisions.sh#L1-L16](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-divisions.sh#L1-L16) [scripts/check-divisions.sh#L83-L129](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-divisions.sh#L83-L129) [.github/workflows/check-divisions.yml#L1-L20](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-divisions.yml#L1-L20) [.github/workflows/check-runbooks.yml#L1-L20](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/check-runbooks.yml#L1-L20) [scripts/check-runbooks.sh#L31-L82](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-runbooks.sh#L31-L82)
- lint-agents.yml runs only on pull_request, path-filtered to division trees plus scripts/lint-agents.sh, convert.sh, and lib.sh. The lint job lints git-diff changed agent files and then check-agent-originality.sh on those files. A second job lints the entire roster only when the linter, converter, or lib.sh changed. — [.github/workflows/lint-agents.yml#L3-L73](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/lint-agents.yml#L3-L73) [.github/workflows/lint-agents.yml#L75-L106](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/lint-agents.yml#L75-L106)
- check-agent-originality.sh embeds Python that builds 8-word shingles after stripping a fixed ENTITY proper-noun list, then Jaccard-compares candidates to the roster. ORIGINALITY_FAIL defaults to 40 and ORIGINALITY_WARN to 20. Exit 1 at or above the fail threshold. The header says the existing library's worst pair is about 1.5 percent. — [scripts/check-agent-originality.sh#L1-L28](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-agent-originality.sh#L1-L28) [scripts/check-agent-originality.sh#L50-L82](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-agent-originality.sh#L50-L82) [scripts/check-agent-originality.sh#L160-L173](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/check-agent-originality.sh#L160-L173)
- What is not covered: no test executes an agent prompt; test-install.sh never calls install_opencode, install_cursor, install_hermes, or install_openclaw; lint does not run on push to main; and there is no coverage tool, fixture app, or browser suite. Agent markdown under testing/ is a division of QA personas, not this repo's test suite. — [scripts/test-install.sh#L14-L16](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/scripts/test-install.sh#L14-L16) [testing/](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/testing/) [.github/workflows/lint-agents.yml#L3-L4](https://github.com/msitarzewski/agency-agents/blob/053ddbbf392a1688fc7043d81529f47ef2cf86c8/.github/workflows/lint-agents.yml#L3-L4)

Every claim links to its cited files at the pinned commit. Citations identify source evidence; they do not establish runtime correctness. Independent CodeVetter scan — not reviewed by upstream maintainers.

## Public product links

- [CodeVetter](https://codevetter.com/)
- [Download](https://codevetter.com/download)
- [Documentation](https://codevetter.com/docs/)
- [Source](https://github.com/Codevetter/codevetter)
