# Harness — ai-readiness-assessment ## Context ### Stack - **Primary languages**: Markdown (content), JSON (plugin manifest). No programming language is compiled or executed; the plugin's entire product is the prose inside the command and skill files. - **Build system**: None for the plugin artifact — it's a plugin distribution layout (`.claude-plugin/plugin.json` + `commands/` + `skills/`) consumed directly by Claude Code, Copilot, Cursor, and Windsurf, with no compilation, bundling, or packaging. The one build step in the repo is the documentation site (`mkdocs build --strict` — see CI/CD). - **Test framework**: TDAB (Test-Driven Agentic Behaviours). The A-tier (structural) assertions are automated in `tests/run.py` — a stdlib-only runner that checks each fixture's committed sample assessment for the required structure — and are CI-enforced on every PR by `.github/workflows/agentic-behaviours.yml`. The B-tier (behavioural) and C-tier (semantic) assertions in each fixture's `expected.md` need an interactive Claude session or an LLM judge and are run manually — see `tests/README.md`. - **CI/CD**: GitHub Actions (`.github/workflows/`). On every PR to a branch-protected `main`, four **required status checks** run: `A-tier structural assertions` (the TDAB suite, `agentic-behaviours.yml`), `Changelog gate` (`changelog-gate.yml`), `Spec-first gate` (`spec-first-gate.yml`), and `Onboarding gate` (`onboarding-gate.yml`). The context names are the authority — they are what branch protection actually requires. On a version bump, `release.yml` tags `vX.Y.Z` and publishes a GitHub Release whose notes are the matching `CHANGELOG.md` section. On docs changes, `pages.yml` builds the MkDocs Material site and deploys it to GitHub Pages. - **Container strategy**: N/A. No runtime, no container. ### Conventions - **Dual-surface sync**: The framework content (six literacy levels, the scoring heuristic, and the assessment process) embedded in `commands/ai-readiness-assess.md` must be identical to the same content embedded in `skills/ai-readiness-assessment/SKILL.md`. Editing one without updating the other is forbidden. A reviewer can verify by diffing the agreed framework sections between the two files. - **Self-contained**: Neither `commands/ai-readiness-assess.md` nor `skills/ai-readiness-assessment/SKILL.md` may reference, invoke, or depend on any other plugin, skill, agent, MCP server, or external service. The `dependencies` field in `.claude-plugin/plugin.json` must remain absent or empty. A reviewer can verify by grepping the two files for cross-plugin references and checking the manifest. - **Single CTA**: The assessment's recommendation output must propose exactly one specific TechTalk engagement (a particular service, book, course, or workshop). Multi-option menus, "consider one of…" phrasings, or "you might want…" lists are forbidden. A reviewer can verify by reading the recommendation section of each rendered assessment. - **Frontmatter shape**: Every file in `commands/` and every `SKILL.md` file under `skills/` must carry YAML frontmatter with both a `name` and a `description` field. For commands, `name` must equal the filename without the `.md` extension. For skills, `name` must equal the parent directory name. A reviewer can verify by parsing the YAML block at the top of each file. - **Plain-text output**: The optional rendered output (HTML, printable PDF, or other) must use print-friendly typography. No emojis appear in any rendering template the skill emits. - **Spec-first for substantive changes**: Substantive, behaviour-changing work (the assessment instrument, the model or scoring, a new workflow) is captured as a spec under `specs/` — at minimum a one-paragraph intent — written or updated with the change and referenced in the PR. Docs, chore, surface-sync, dependency, and pure-fix PRs are exempt. Each spec carries a "Risks / what could go wrong" section and an adjudicated Adversarial review disposition. **Enforced** — see the *Spec-first* constraint below. --- ## Constraints ### Consistent formatting - **Rule**: All source files must pass the project's configured formatter without changes - **Enforcement**: unverified - **Tool**: none yet - **Scope**: commit ### Tests must pass - **Rule**: The project's test suite must pass with zero failures before any code is merged - **Enforcement**: deterministic - **Tool**: python3 tests/run.py - **Scope**: pr ### Dual-surface sync (command ≡ skill) - **Rule**: The embedded framework content (the model, the cognitive read, the scoring heuristic, and the assessment process) in `commands/ai-readiness-assess.md` must match the same content in `skills/ai-readiness-assessment/SKILL.md`. Editing one without updating the other is forbidden. Intentional command-vs-skill wording differences in the preamble are allowed; the model and process substance must agree. - **Enforcement**: agent - **Tool**: agent review at PR — a reviewer (or review agent) diffs the embedded model and process sections of the two files and confirms they agree - **Scope**: pr ### Spec-first - **Rule**: A PR that changes the instrument (`commands/**` or `skills/**`) or the model / scoring must reference a spec under `specs/` (a changed `specs/NNNN-*.md`), unless it carries an exempt label (`chore`, `fix`, or `docs`). Each substantive spec carries an adjudicated **Adversarial review** disposition before merge. - **Enforcement**: deterministic (ordering) + agent (review adjudication) - **Tool**: `.github/workflows/spec-first-gate.yml`; reviewer adjudication of the spec's Risks at PR - **Scope**: pr ### No direct pushes to main - **Rule**: All changes must be committed on a feature branch and merged via a pull request — direct pushes to `main` are not permitted, including for administrators - **Enforcement**: deterministic - **Tool**: GitHub branch protection — `require_pull_request_reviews` enabled on `main` with `enforce_admins: true`, configured in repository Settings → Branches - **Scope**: pr ### No secrets in source - **Rule**: No API keys, tokens, passwords, or private keys may appear in committed source files - **Enforcement**: deterministic - **Tool**: gitleaks detect --source . --no-banner --exit-code 1 - **Scope**: commit --- ## Garbage Collection ### Template currency - **What it checks**: Whether the `template-version` marker in HARNESS.md matches the version of the **ai-literacy-superpowers** plugin installed locally — the plugin that provides this harness template. A mismatch means new template content exists that has not been reviewed. - **Frequency**: weekly - **Enforcement**: deterministic - **Tool**: compare the marker against the template provider's manifest: `jq -r .version ~/.claude/plugins/cache/ai-literacy-superpowers/ai-literacy-superpowers/*/.claude-plugin/plugin.json` against `grep -o 'template-version: [0-9.]*' HARNESS.md`. **Not** this repo's `.claude-plugin/plugin.json` — that is the assessment plugin's own product version (currently `1.0.0`) and has no relationship to the template. Comparing against it reports permanent false drift, which is how this rule was originally worded. - **Caveat**: reads the local plugin cache, so the result is per-machine. A maintainer with an older plugin installed sees no drift where a colleague does. The marker in HARNESS.md is the shared fact; the installed version is not. - **Auto-fix**: false (run `/harness-upgrade` to review and adopt) ### Onboarding document staleness - **What it checks**: Whether `ONBOARDING.md` is older than the most recent change to the HARNESS.md body or `AGENTS.md` — i.e. the onboarding guide has fallen behind its sources - **Frequency**: monthly - **Enforcement**: deterministic - **Tool**: PR-time gate `.github/workflows/onboarding-gate.yml` (fails a PR that changes the HARNESS body or AGENTS.md without refreshing ONBOARDING.md); file-date comparison as the periodic backstop - **Auto-fix**: false (run `/harness-onboarding` to regenerate) ### Secret scanner operational - **What it checks**: Whether gitleaks is installed and the "No secrets in source" constraint is still enforced as deterministic (not regressed to unverified) - **Frequency**: weekly - **Enforcement**: deterministic - **Tool**: gitleaks --version && gitleaks detect --source . --no-banner --exit-code 1 - **Auto-fix**: false ### Convention file sync - **What it checks**: Whether .cursor/rules/, .github/copilot-instructions.md, and .windsurf/rules/ exist and reflect the current HARNESS.md conventions - **Frequency**: weekly - **Enforcement**: agent - **Tool**: harness-gc agent - **Auto-fix**: false ### Documentation freshness - **What it checks**: Whether README, HARNESS.md, and inline doc comments reference files, functions, or conventions that no longer exist - **Frequency**: weekly - **Enforcement**: agent - **Tool**: harness-gc agent - **Auto-fix**: false ### Dependency currency - **What it checks**: Whether project dependencies have known vulnerabilities or are more than one major version behind latest - **Frequency**: weekly - **Enforcement**: agent - **Tool**: harness-gc agent - **Auto-fix**: false ### Reflection-driven regression detection - **What it checks**: Whether REFLECTION_LOG.md contains recurring failure patterns (same type of surprise across 2+ entries) that are not yet covered by a HARNESS.md constraint - **Frequency**: weekly - **Enforcement**: agent - **Tool**: harness-gc agent - **Auto-fix**: false ### Reflection log aged-out review - **What it checks**: Entries older than the configured age threshold (default 6 months) that lack a `Promoted` line; emits per-entry evidence (recurrence count, AGENTS.md/HARNESS.md text-overlap matches, single- instance signal) for the curator to interpret. - **Frequency**: monthly - **Enforcement**: agent - **Tool**: harness-gc agent - **Auto-fix**: false - **Threshold**: 180 days (configurable; reduce to surface candidates sooner, increase to defer) - **Opt-in**: declare this rule to enable. If absent, no monthly report is generated and the system reverts to today's behaviour for this project. --- ## Observability ### Operating cadence ### Health thresholds ### Regression detection --- ## Status Last audit: 2026-08-17 Constraints enforced: 5/6 (4 deterministic incl. Spec-first's deterministic half, 1 agent, 1 unverified — "Consistent formatting", honestly declared: no formatter config exists on disk) Garbage collection active: 7/8 (1 non-operational: Template currency — its Tool compares two incompatible version schemes, see below) Drift detected: yes (7 items; none is a live enforcement failure — every constraint that names a tool passed when run) - Convention surfaces 75 days stale — `.cursor/rules/`, `.windsurf/rules/` and `.github/copilot-instructions.md` were last synced by 834ea87 (2026-06-03) and list 4 constraints; HARNESS.md declares 6. "No direct pushes to main" and "No secrets in source" are absent from all three. Fix: `/convention-sync` (auto). - Template currency is defective as worded — its Tool says compare the HARNESS.md template-version marker against "plugin.json version". The marker (0.64.0) tracks the ai-literacy-superpowers plugin, but this repo's `.claude-plugin/plugin.json` is 1.0.0, its own product version. As written the rule reports permanent false drift. Fix: name the harness plugin's manifest as the comparison source (human edit to the rule). - Dual-surface sync is under-declared — HARNESS.md says `agent`, but R1 and R6 in `tests/run.py` also enforce it deterministically under the required check "A-tier structural assertions" (`check_parity`, tests/run.py:857, compares full normalised bodies). Truthful declaration: deterministic + agent. Promotion is `/harness-constrain`'s job and needs a human. - No secrets in source has a tool but no automatic trigger — scope is `commit`, yet gitleaks appears in no workflow and there are no non-sample git hooks, so it fires only when someone runs an audit. The declared `--source .` also scans git history, not the working tree, so the command alone would miss a secret in an uncommitted file. Both scans clean today (140 commits, no leaks; `--no-git` also clean). - No GC rule has a scheduled executor — all six workflows trigger on pull_request / push / workflow_dispatch only; a cron/schedule grep over `.github/` returns nothing. Every "weekly" and "monthly" cadence above is invocation-driven, not automatic. - Reflection log archival of promoted entries (Path 1) is not declared, yet 3 entries carry `Promoted` lines (REFLECTION_LOG.md:18, 35, 52) with no archival path. Path 2 (aged-out review) is declared and operating. Curation debt is 0: 6 active entries, 0 archived, oldest 2026-06-02 (76 days), none past the 180-day threshold. Entries are delimited by `- **Date**:` bullets rather than `##` headings — a parser expecting headings finds 0 entries here. - README badges are stale — line 12 reads `harness-3/4-enforced` (actual 5/6) and is green where 83% should be steel blue; lines 10 and 11 read `commands-1` and `skills-1` while the repo ships two of each; line 13's AI Literacy badge still links to `assessments/2026-06-03-assessment-2.md` though `assessments/2026-08-16-assessment.md` exists. Left unchanged deliberately — badge edits are the human's call. The newly-adopted Documentation freshness rule covers this class of finding. In sync: ONBOARDING.md (regenerated 2026-08-17 alongside HARNESS.md; covers all 6 constraints and all 8 GC rules) · branch protection on `main` (API verified: enforce_admins true, force pushes and deletions disabled, 4 required contexts) · TDAB A-tier suite (117 PASS, 0 FAIL) · gitleaks (clean). Observability: the four Observability subsections above are still placeholders and `observability/snapshots/` does not exist, so snapshot staleness is not a claim this project makes — not counted as drift.