diff --git a/bin/fm-brief.sh b/bin/fm-brief.sh index 700c743ca14..84e5cc5480f 100755 --- a/bin/fm-brief.sh +++ b/bin/fm-brief.sh @@ -45,6 +45,10 @@ # affected-based test selection before done, a learning loop into the project's # docs/agents/codegraph/README.md with an AGENTS.md pointer, and a one-line note # to continue without codegraph when the binary is missing. +# They also carry a standing test-selection contract: no full-suite first run, +# changed-first selection (fm-test-run.sh --changed here, the project runner's +# native equivalent elsewhere), failed-family-only reruns, GitHub CI as the PR +# merge verdict, and full output kept in a file so failures need no rerun. # Ship briefs begin with a worktree-isolation assertion before the branch step. # --mode is refused on scout and secondmate scaffolds: a scout's deliverable is a # report rather than a merge, and a charter is not a delivery contract. @@ -317,6 +321,16 @@ CODEGRAPH_SECTION=$(printf '%s\n' \ " Keep an \`AGENTS.md\` pointer section to that file via '$FM_ROOT/bin/fm-ensure-agents-md.sh .'" \ 'If the `codegraph` binary is missing, append one status line noting it and continue with ordinary tools; nothing else changes.') +# Standing test-selection contract shared by the ship and scout scaffolds. +# shellcheck disable=SC2016 # single quotes are deliberate: backtick-wrapped command names must reach the reading agent verbatim, not expand at scaffold time. +TEST_SELECTION_SECTION=$(printf '%s\n' \ +'# Test selection contract' \ +'Verify efficiently: never make a full local suite run your first verification step.' \ +"1. Changed-first selection: when the repo under test is the firstmate repo itself, select tests with \`bin/fm-test-run.sh --changed\` (add \`--base \` when your working base is not origin/main); on other projects use the runner's native changed/related feature, e.g. \`vitest --changed\`." \ +'2. On failure, re-run only the failed family or single script (`bin/fm-test-run.sh --family ` or that one script path), never the whole suite.' \ +'3. For PR-based deliveries, GitHub CI owns the final merge verdict; local runs are a fast pre-check, not the authority.' \ +'4. Keep full test output in a file: never pipe it through `tail` or any other filter that discards per-test result lines, so failures stay identifiable without rerunning.') + if [ "$KIND" = scout ]; then cat > "$BRIEF" </dev/null 2>&1 + else + FM_HOME="$home" FM_ROOT_OVERRIDE="$ROOT" "$ROOT/bin/fm-brief.sh" "$id" some-proj --mode direct-PR >/dev/null 2>&1 + fi + brief="$home/data/$id/brief.md" + assert_grep "# Test selection contract" "$brief" \ + "$kind brief missing the test-selection contract heading" + assert_grep "never make a full local suite run your first verification step" "$brief" \ + "$kind brief missing the no-full-suite-first rule" + assert_grep "select tests with \`bin/fm-test-run.sh --changed\` (add \`--base \` when your working base is not origin/main)" "$brief" \ + "$kind brief missing changed-first selection for the firstmate repo" + assert_grep "on other projects use the runner's native changed/related feature" "$brief" \ + "$kind brief missing the other-projects changed-selection rule" + assert_grep "re-run only the failed family or single script (\`bin/fm-test-run.sh --family \` or that one script path), never the whole suite" "$brief" \ + "$kind brief missing the failed-family-only rerun rule" + assert_grep "GitHub CI owns the final merge verdict; local runs are a fast pre-check, not the authority" "$brief" \ + "$kind brief missing the CI-owns-the-verdict rule" + assert_grep "never pipe it through \`tail\` or any other filter that discards per-test result lines" "$brief" \ + "$kind brief missing the keep-full-output rule" + assert_no_grep "EOF" "$brief" \ + "$kind brief leaked a heredoc EOF marker (unterminated heredoc) in the test-selection section" + done + + FM_HOME="$home" FM_SECONDMATE_CHARTER='sample domain' \ + "$ROOT/bin/fm-brief.sh" brief-testsel-mate --secondmate --no-projects >/dev/null 2>&1 + assert_no_grep "# Test selection contract" "$home/data/brief-testsel-mate/brief.md" \ + "secondmate charter must not carry the worker-level test-selection contract" + pass "fm-brief.sh: ship and scout scaffolds carry the standing test-selection contract" +} + test_script_parses() { local out rc out=$(bash -n "$ROOT/bin/fm-brief.sh" 2>&1); rc=$? @@ -771,6 +811,7 @@ test_herdr_lab_contract_quotes_foreign_firstmate_path test_herdr_lab_omission_is_loud_for_ship_and_scout test_herdr_lab_contract_applies_to_scouts_but_not_secondmates test_codegraph_contract_in_ship_and_scout_briefs +test_test_selection_contract_in_ship_and_scout_briefs test_secondmate_no_projects_charter test_secondmate_marked_request_reporting_contract test_secondmate_directory_paths_are_absolute_and_output_is_stable