Skip to content

Testing plan: the env file the CLI config names

Derived from requirements.md and design.md, before tasks.md. Authored at test-planning; the results section is filled at verification.

This file is executable content. Commands below are what the agent runs; credentials appear by reference only.

Test matrix

#TypeApplies?Scope / what it provesWhere it runs
T1Unityesenvfile.parse: the grammar (comments, blanks, export, double/single/unquoted values, escapes, trailing comments, duplicates, invalid names, unterminated quotes, no interpolation); envfile.load: absent-only, missing, not a regular file, unreadable, mode warning, no values in any log line; cli_config.resolve_env_file / load_env_file: config-relative, ~, absolute, wrong types, lenient config read; cli.main, daemon_entry.main, api.serve.main each call the loader firstuv run --project cli python -m pytest -q cli/tests/test_envfile.py cli/tests/test_cli_config.py
T2Integration (scenario)yesthe Gherkin scenario: a config naming the Slack token variable and an env file carrying it; the-loop run through cli.main; the variable present afterwards, untouched when it was already exporteduv run --project cli python -m pytest -q cli/tests/test_envfile_integration.py
T3Contract (OpenAPI / GraphQL SDL)n/a — no API route changes; the schema the dashboard renders gains one block, covered by T10
T4End-to-endn/a — the entry points are exercised in-process with the daemon and service runs faked; a real daemon needs tmux and a listening port
T5UI / visualn/a — the Settings tab renders the block from the schema, as every block
T6Snapshotn/a — field assertions on two small dataclasses
T7Performance / loadn/a — one file read per process start
T8Security / abuse caseyesone negative test per abuse case A1–A5 (design.md § Security design)uv run --project cli python -m pytest -q cli/tests -k "never_carries_a_value or readable_by_others or malformed_lines_are_skipped or environment_wins_over_the_file or parent_path_is_honoured"
T9Accessibilityn/a — no UI
T10Migration / upgradeyesa config without env behaves as before (load_env_fileNone, nothing logged); a config with env.file validates against the authored schema and the packaged copy is byte-identical; CURRENT_CONFIG_VERSION unchanged; a stale-version config loads no env file and is still refused by the commanduv run --project cli python -m pytest -q cli/tests/test_config_schema_parity.py cli/tests/test_docs_parity.py cli/tests/test_migrations.py cli/tests/test_envfile.py -k "parity or migrat or without_an_env or stale" and make validate
T11Manual exploratoryn/a — the reviewer's walk-through is the PR briefing's "what to check"
T12Lint / format / typecheck / config validation / full suiteyesthe repository's own gates, as pre-commit and CI run themmake check
T13Security review (gate)yesthe-loop checklist against A1–A5, recorded as evidence; tier 3 needs no human sign-off (humanSignOffMinTier: 4)evidence/security-review.md

Scenarios & requirement trace

RowRequirement(s)Scenario / case
T1R1.4the grammar, line by line
T1R1.5a present name is left alone and reported as skipped
T1R1.3relative → the config's directory; ~ expanded; absolute honoured
T1R1.1, R2.6no env → nothing; a stale or unparseable config → nothing, no raise
T1R2.1, R2.2, R2.3, R2.4, R2.5missing, unreadable, malformed, readable-by-others; no value in any record
T1R1.2the three entry points call the loader before their own work
T2R1.2, R1.5, R1.6Scenario: The Slack token comes from the env file the config names
T8A1–A5one negative test each, named in design.md § Security design
T10R1.1, R3.1schema parity, docs parity, no migration

Verification environment

  • Repositories: this repo only.
  • Services / containers: none. The poller's and the service's run/main are monkeypatched at the entry-point boundary; nothing binds a port.
  • Fixtures & data: temp directories per test; env files written by the tests.
  • Credentials: none. THE_LOOP_SLACK_BOT_TOKEN and friends are set to dummy values inside tests — by name, never a real token; monkeypatch restores the environment.
  • Bring-up: uv sync · Tear-down: none.
  • If bring-up fails: record it under Verification results and escalate.

Evidence plan

RowEvidencePath under evidence/
T1, T2, T8, T10, T12command, counts, duration, raw tail of the output; red → green per taskverification.md
T13the abuse-case table with verdicts and the tests that close eachsecurity-review.md

Verification activities

  • [x] T1 — uv run --project cli python -m pytest -q cli/tests/test_envfile.py cli/tests/test_cli_config.py
  • [x] T2 — uv run --project cli python -m pytest -q cli/tests/test_envfile_integration.py
  • [x] T8 — uv run --project cli python -m pytest -q cli/tests -k "never_carries_a_value or readable_by_others or malformed_lines_are_skipped or environment_wins_over_the_file or parent_path_is_honoured"
  • [x] T10 — uv run --project cli python -m pytest -q cli/tests/test_config_schema_parity.py cli/tests/test_docs_parity.py cli/tests/test_migrations.py cli/tests/test_envfile.py -k "parity or migrat or without_an_env or stale" and make validate
  • [x] T12 — make check
  • [x] T13 — evidence/security-review.md

Verification results

ActivityCommand / procedureOutcomeEvidence
T1uv run --project cli python -m pytest -q cli/tests/test_envfile.py cli/tests/test_cli_config.pypass — 45 passedevidence/verification.md
T2uv run --project cli python -m pytest -q cli/tests/test_envfile_integration.pypass — 2 passed (the two scenarios)evidence/verification.md
T8uv run --project cli python -m pytest -q cli/tests -k "never_carries_a_value or readable_by_others or malformed_lines_are_skipped or environment_wins_over_the_file or parent_path_is_honoured"pass — 5 passed (A1–A5)evidence/verification.md
T10uv run --project cli python -m pytest -q cli/tests/test_config_schema_parity.py cli/tests/test_docs_parity.py cli/tests/test_migrations.py cli/tests/test_envfile.py -k "parity or migrat or without_an_env or stale" and make validatepass — 53 passed; seven configs VALIDevidence/verification.md
T12make checkpass — lint (ruff, markdownlint over 957 files), format, pyright, config validation, full suite: 3020 passed, 1 skippedevidence/verification.md
T13the-loop checklist over A1–A5pass; no human sign-off at tier 3evidence/security-review.md

Not executed: none.

Review comments

Appended by the-loop's record-feedback hook when a human gate approves with comments (issue-109). Append-only and attributed: an approval never silently discards a reviewer's suggestions, and the feedback travels with the document it concerns rather than living in a side-channel tracker.

Released under the MIT License.