Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
300816f
docs(plan): change 0526 plan
danielhanold Oct 5, 2026
7265f68
feat(reposetup): explicit test-command planner for configure-tests --…
danielhanold Oct 5, 2026
fe10671
fix(reposetup): gap note and migrate ambiguity name remedies that res…
danielhanold Oct 5, 2026
5764726
feat(repository): configure-tests --command and truthful discovery me…
danielhanold Oct 5, 2026
b45d5f7
test(repository): configure-tests --command on the root test.sh fixture
danielhanold Oct 5, 2026
d594d58
docs: describe repository configure-tests --command
danielhanold Oct 5, 2026
d030bc7
fix(reposetup): refuse a test-policy splice that the re-parse cannot …
danielhanold Oct 5, 2026
79dda61
fix(init): no-suite note states only unset gates were written off (re…
danielhanold Oct 5, 2026
1b091e0
docs(results): change 0526 results
danielhanold Oct 5, 2026
1ed2697
Revert "fix(init): no-suite note states only unset gates were written…
danielhanold Oct 5, 2026
e50e069
Revert "fix(reposetup): refuse a test-policy splice that the re-parse…
danielhanold Oct 5, 2026
a9e9306
docs(results): change 0526 review outcome
danielhanold Oct 5, 2026
d427a8d
Reapply "fix(reposetup): refuse a test-policy splice that the re-pars…
danielhanold Oct 5, 2026
748ceb4
Reapply "fix(init): no-suite note states only unset gates were writte…
danielhanold Oct 5, 2026
92d70eb
test(app): configure-tests splice-refusal test uses testsupport.TempDir
danielhanold Oct 5, 2026
0b2326d
docs(results): change 0526 fixes re-applied on resume
danielhanold Oct 5, 2026
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
3 changes: 2 additions & 1 deletion docs/concepts/build-tiers-and-gate.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ build that must be green before review — runs the whole suite once and records
`local`. With `build.gate: off` it runs nothing and records truthful skipped
evidence (`skipped`, reason `build-gate-off`) before review. An empty
`build.test_command` under `local` is a configuration gap, not a red suite: the
build halts with the remedy `docket repository configure-tests`.
build halts with the remedy `docket repository configure-tests` (add
`--command "<cmd>"` when discovery cannot find the suite).
- Build evidence is minted by `docket evidence record` from the passed run and
checked by `docket evidence verify`. It lives in the pull request body's
build-evidence block and is never committed, so the reviewer reads a durable
Expand Down
5 changes: 4 additions & 1 deletion docs/guide/proving-the-build.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,10 @@ Two keys name the suite, one per gate, and they are **read from config, never fr

Both default to the empty string, which means *unconfigured*: a `local` gate with no command halts
with a typed remedy pointing you at `docket repository configure-tests` rather than trying to guess a
command at runtime. They are **independent** — the two may diverge if a repo wants a lighter suite at
command at runtime. Plain `configure-tests` re-runs suite discovery. When discovery cannot find your
suite, or finds more than one, pass it yourself: `docket repository configure-tests --command "<cmd>"`
sets both gates to `local` with that command and leaves the `.docket.yml` edit unstaged for you to
commit. They are **independent** — the two may diverge if a repo wants a lighter suite at
build time than at merge time. The one rule that matters whichever they resolve to: each gate reads its own key from config, so there is
exactly one source for each and no drifting duplicate to keep in sync. `finalize.gate` is the
matching on/off switch for the finalize gate — `local` (the default) or `off`, where `off` skips the
Expand Down
3 changes: 2 additions & 1 deletion docs/guide/where-the-metadata-lives.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ All of these operate on the repository in your current directory (or the one `--
- **`docket repository repair`** — previews the mechanical repairs `check` reports and applies them
only once you confirm (or pass `--yes`).
- **`docket repository configure-tests`** — writes the build and finalize test commands into
`.docket.yml` for a repository that is already set up, for you to review and commit.
`.docket.yml` for a repository that is already set up, from suite discovery or from
`--command "<cmd>"`, for you to review and commit.

The workflows never set a repository up for you. If one runs against a repository that is not set
up, its startup check stops and names the command to run: `init` for a fresh repository, `migrate`
Expand Down
10 changes: 9 additions & 1 deletion docs/reference/glossary.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ legacy single-branch layout; it is human-typed and asks for confirmation unless

**Used for:** the one-time setup per repo. The skills never set a repository up for you; the
bootstrap guard stops and names the command to run. A local gate with no test command halts until
one is configured, and `repository configure-tests` sets the test commands.
one is configured, and `repository configure-tests` sets the test commands: from suite discovery,
or from `--command "<cmd>"` when discovery cannot find the suite.

```sh
cd <target-repo>
docket repository init # a repository that has never used docket
docket repository migrate # a legacy single-branch repository (human-typed)
docket repository configure-tests # set the build and finalize test commands
docket repository configure-tests --command "sh ./test.sh" # set both gates to local with this command
```

### Archived record
Expand Down Expand Up @@ -893,8 +895,14 @@ the finalize gate. They are independent and may differ. Both default to `""`, wh
not a red suite, and names `docket repository configure-tests` as the remedy. Each gate reads its key from config,
never from a second copy.

Plain `docket repository configure-tests` re-runs suite discovery and writes what it finds. `--command "<cmd>"`
skips discovery and sets both `build` and `finalize` to `gate: local` with that command, replacing whatever test
policy was there. Either way the `.docket.yml` edit is left unstaged for you to review and commit. Different build
and finalize commands are a hand edit.

```sh
docket repository configure-tests --repo-dir . # generate the build/finalize test policy in .docket.yml
docket repository configure-tests --command "sh ./test.sh" --repo-dir . # set both gates to local with this command
docket diagnostic config --repo-dir . --json # see what each key resolves to
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!-- docket:backlink:start (generated — do not hand-edit) -->
> ↩ **[Change 0526 — repository configure-tests takes the test command as input](https://github.com/danielhanold/docket/blob/docket/docs/changes/active/0526-repository-init-writes-gate-off-and-configure-tests-then-ref.md)**
<!-- docket:backlink:end -->
# repository configure-tests takes the test command as input — Results

**Human action:** None required before merge. One optional walkthrough below shows `--command`
working on a repository whose only test is a root `test.sh`.

## Outcome

Before this change, a repository whose tests Docket could not detect, such as one whose only
test is a root `test.sh`, ended up with both test gates `off`. No command could turn them on
again: `docket repository configure-tests` took no input, re-ran the same detection, and
printed a false "the test policy is already configured; nothing to write".

Now:

- `docket repository configure-tests --command "<cmd>"` sets `build.gate` and `finalize.gate` to
`local` with that command. It replaces any existing gate value or command and leaves the usual
pending, unstaged `.docket.yml` edit for review. Running it again with the same command does
nothing. An empty or whitespace-only value, `auto`, or a value with control characters or line
breaks is refused, and nothing is written.
- Without `--command`, configure-tests says what detection actually found: no suite (with the
resolved gates and the `--command` remedy), two candidate suites (each with its command), or
already configured (naming the commands). The half-configured note and init's "no suite" and
"two suites" notes now point at `--command` instead of a hand edit.
- When `docket repository migrate` finds two candidate suites, it now says to commit
`finalize.test_command` and re-run migrate. It no longer points at configure-tests, which
refuses a legacy repository.
- The glossary and the guide pages describe `--command`.

How this differs from the design:

- **Quoting.** A command that YAML would read as a number or date (`123`, `2026-10-05`) is now
quoted when written. Before, such a value would have produced a `.docket.yml` that fails to
load.
- **The no-suite message.** It reports the gates as they actually resolve rather than saying
they are `off`, because a gate the file already sets explicitly is left alone.

## Human actions and testing

### Optional — turn the gates on for a root `test.sh` repository

This shows the original problem fixed from start to finish. The integration test
`TestIntegrationRepoSetupConfigureTestsCommandTurnsOnRootTestSh` already covers it.

Prerequisites: a `docket` binary built from this branch on `PATH`, and an empty GitHub-less
scratch directory with a bare remote.

1. `mkdir -p /tmp/ct526 && cd /tmp/ct526 && git init --bare remote.git && git clone remote.git repo && cd repo && printf '#!/bin/sh\nexit 0\n' > test.sh && chmod +x test.sh && git add test.sh && git commit -m init && git push origin HEAD`
2. `docket repository init`, then commit and push the paths it reports as pending.
Expected: the note says no supported test suite was found and names
`docket repository configure-tests --command "<cmd>"`. `.docket.yml` has both gates `off`.
3. `docket repository configure-tests --command "sh ./test.sh"`
Expected: an applied result. `git diff .docket.yml` shows `gate: local` and
`test_command: sh ./test.sh` under both `build:` and `finalize:`.
4. Run the same command again.
Expected: a no-op naming the command.

Cleanup: `rm -rf /tmp/ct526`.

## Verification performed

- Each task followed TDD with focused package tests. The overwrite rule, the string-quoting
check, the command-flag handling, and the no-suite message were each
mutation-tested: breaking the guard made its test fail, and restoring it made the test pass.
- The full suite (`go run ./cmd/docket development test`) passed after the build. The PR body
carries the evidence from the final run. The run printed
`BUDGET WATCH` and `PARALLEL-SENSITIVE` lines for unrelated app-integration shards, which this
change does not touch, and no `SERIAL CONFIRMED OVER BUDGET` line.
- Whole-branch review (deep tier): 2 findings (1 important, 1 minor), both fixed in-branch.
The first fix-pass suite run failed because the important fix's new test used a bare
`t.TempDir()`, which a repository guard rejects; both fixes were reverted, the run halted, and
on the authorized resume both were re-applied with the test switched to
`testsupport.TempDir(t)`. The splice now re-parses the edited `.docket.yml` and refuses, file
untouched, when a folded/literal block `test_command` or an inline `{...}` `build:`/`finalize:`
would not round-trip to exactly the requested settings. The init no-suite note now says only
gates `.docket.yml` did not already set were written `off`. The full table is in the PR body.
- A second fix-pass run failed in `internal/process` TestObserveRunningThenTerminal ("timed out
waiting for vanished"), a package this branch does not touch; the final gate run is recorded in
the PR body's evidence block.
Loading
Loading