Skip to content

Testing plan: the-loop's JSON schemas ship with the plugin, not with your repo

Derived from the approved requirements.md and design.md, before tasks.md. Authored at the test-planning node and completed at the verification node.

This file is executable content. It names commands an agent will run, so review it like code. No credentials of any kind are involved in this work item.

What can be tested, and what honestly cannot

Half of this work item is instructions an agent followscommands/init.md and commands/upgrade-the-loop.md are markdown, executed by a model, not by a runner. No test in this repository can assert that /the-loop:init did not copy a file, because nothing here runs /the-loop:init. Saying so plainly is the point of this section: R1, R3 and R5 are verified by review against their acceptance criteria, recorded as evidence, and the rows below mark that explicitly instead of borrowing credibility from the tests that do run.

What is mechanically testable is the part that decides what the agent does: the manifest declarations it reads, and the files it writes. Those carry T1 and T2.

Test matrix

#TypeApplies?Scope / what it provesWhere it runs
T1Unityesharness_config.scaffold() keeps the $schema modeline on line 1 when it prepends its adoption header (R4.2 on the issue-193 path); the packaged default and the shipped template stay byte-identicaluv run pytest cli/tests/test_harness_config.py
T2Integration (repository parity)yesthe manifest declares schemasDir, it resolves and holds the three schemas, meta names no schema, all three are deprecated, and every scaffolded config's first line is a modeline naming a schema that exists (R2, R3.1, R4.1)uv run pytest cli/tests/test_manifest_schemas.py
T3Contract (OpenAPI / GraphQL SDL)n/a — no API surface changes; the control-plane contract under docs/api-specs/ is untouched
T4End-to-endn/a — the e2e suite (cli/tests/test_pdlc_e2e/, issue-217) drives the process graph; /init and /upgrade are not graph nodes and have no runtime to drive
T5UI / visualn/a — no user-facing surface (design.md §UI/UX)
T6Snapshotn/a — no rendered output; the one byte-for-byte comparison this work item cares about (template ↔ packaged default) is an existing assertion in T1
T7Performance / loadn/a — removing files from a scaffold has no performance dimension
T8Security / abuse caseyesthe four abuse cases in design.md §Security design: deletion is name-driven and closed, a drifted copy is reported not deleted, the loop needs no network, a tampered modeline reaches nothingreview against requirements.md §Security considerations + T2's assertion that the three deprecated paths are exact literals
T9Accessibilityn/a — no user interface
T10Migration / upgradeyes, by reviewan existing project's copies are shed by /upgrade and its config migrations still work with no project-local schema: upgrade-the-loop.md steps 3 and 4 read against R3.1–R3.5review + uv run python scripts/validate_config.py (this repository is the migration's own target: it carries all three configs)
T11Manual exploratoryyesread commands/init.md end to end as the agent would, confirming no step still writes a schema and every schema reference names ${CLAUDE_PLUGIN_ROOT} (R1, R2.4)grep + read-through, recorded in evidence

Scenarios & requirement trace

RowRequirement(s)Scenario / case
T1R4.2, R4.3Scenario: adoption keeps the schema modeline on the first line
T1NFR3existing: the packaged default is the shipped template (byte parity)
T2R2.1, R2.2Scenario: the manifest's schemasDir resolves to the shipped schemas
T2R2.3Scenario: the manifest claims no schema as a project file
T2R3.1Scenario: every retired schema copy is listed as deprecated
T2R4.1, R4.2, R2.4Scenario: every scaffolded config points at a schema that exists
T8abuse 1–4negative reading: the deprecated list is three exact literals; no code path reads the modeline
T10R3.1–R3.5review of upgrade-the-loop.md §3–4 against the criteria; this repo's own configs re-validated
T11R1.1–R1.4, R2.4, R5.1read-through of init.md, the guide, and the config reference

Verification environment

  • Repositories: this repository only. No consuming repository is checked out: the criteria that would need one (R1.1's "init creates no schema") are the ones this plan marks as review-verified rather than executed.
  • Services / containers: none.
  • Fixtures & data: none beyond tmp_path in the unit test.
  • Credentials: none. This work item touches no secret, token or environment variable.
  • Bring-up: uv sync · Tear-down: none.
  • If bring-up fails: record it under Verification results, leave the dependent activities unticked, and escalate.

Evidence plan

RowEvidencePath under evidence/
T1, T2test output (counts, duration), plus the full-suite run proving no regressionverification.md
T8, T10, T11the review record: each criterion, where it is met in the diff, and the quality-gate output (lint, markdownlint, pyright, validate_config.py)verification.md

Nothing captured here can contain a secret: the commands run a test suite and linters over a public repository. Standard redaction still applies to any path that would reveal a local home directory.

Verification activities

  • [x] T1 — uv run pytest cli/tests/test_harness_config.py
  • [x] T2 — uv run pytest cli/tests/test_manifest_schemas.py
  • [x] T8 — review against requirements.md §Security considerations (four abuse cases)
  • [x] T10 — review of commands/upgrade-the-loop.md §3–4 + uv run python scripts/validate_config.py
  • [x] T11 — read-through of commands/init.md and the user-facing docs
  • [x] Regression — make check (full suite, lint, format, types, markdown, config validation)

Verification results

Executed in full on 2026-08-14. Every activity ran; nothing was replanned or escalated. Full output in evidence/verification.md.

ActivityCommand / procedureOutcomeEvidence
T1uv run pytest cli/tests/test_harness_config.py38 passed in 0.52s, including the new modeline case (red→green captured)T1
T2uv run pytest cli/tests/test_manifest_schemas.py7 passed in 0.10s; all 7 red against the unchanged repositoryT2
T8review of the four abuse cases against the shipped mechanismsall four met; the one new authority (/upgrade deleting three named files) is bounded by a closed list, an escape check and a fail-closed ruleT8
T10review of upgrade-the-loop.md §3–4 + uv run python scripts/validate_config.pyR3.1–R3.5 met; this repo's 7 config files still VALIDT10
T11read-through of init.md + the grep sweep for project-relative schema pathsno step writes a schema; every surviving reference is a plugin-root path, this repo's own file, or a deprecated entryT11
Regressionmake checklint, markdownlint (623 files), format, pyright, config validation all clean; 1895 passed + 1 skipped (+8)Regression

Review comments

None yet.

Released under the MIT License.