From 74b2bde9cbb3630e38d91f6e1db685ca1571e83b Mon Sep 17 00:00:00 2001 From: Daniel Petty Date: Wed, 4 Nov 2026 15:54:55 +0000 Subject: [PATCH 1/2] test(roadmap): cover a refused delivery title before the write (#3368) --- .../design.md | 1 + .../tasks.md | 4 +- tests/roadmap/test_roadmap_implement_job.py | 53 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/openspec/changes/3368-stop-a-delivery-title-that-the/design.md b/openspec/changes/3368-stop-a-delivery-title-that-the/design.md index f70327942..5c3e7d40b 100644 --- a/openspec/changes/3368-stop-a-delivery-title-that-the/design.md +++ b/openspec/changes/3368-stop-a-delivery-title-that-the/design.md @@ -4,6 +4,7 @@ - **Put both tests in `tests/roadmap/test_roadmap_implement_job.py`, beside the #3319 test.** The guard is one function, `_delivery_title`, and its tests belong in the module that already holds the refused-title test, so a reader sees every case together and no new module mirrors one helper. - **Use `planned_world` for the first-push case and assert that `origin` holds no branch, not that the job deletes one.** `_publish` calls `_delivery_title` before `_push`, so a refused title stops the item before the branch reaches `origin`; a deletion assertion would describe code that no longer exists. +- **Edit the title of the planned item after the plan reads it.** The plan refuses a Planned item whose title has no Conventional Commit type, so the test changes the title on the selected target's item, as a person's edit after the plan reaches the job does. - **Set `skip_specs: true` and write no spec delta.** The change adds tests for behavior that `openspec/specs/roadmap-implement-job/spec.md` already states in the requirement `The pull request that delivers the code has the type of the issue`, and a test changes no behavior that a consumer observes. ## Rejected alternatives diff --git a/openspec/changes/3368-stop-a-delivery-title-that-the/tasks.md b/openspec/changes/3368-stop-a-delivery-title-that-the/tasks.md index 3c5a537a6..5f5fc4397 100644 --- a/openspec/changes/3368-stop-a-delivery-title-that-the/tasks.md +++ b/openspec/changes/3368-stop-a-delivery-title-that-the/tasks.md @@ -4,9 +4,9 @@ Reads: `src/devops_cli/roadmap/implement_run.py`, `src/devops_cli/roadmap/pull_form.py`, `tests/roadmap/test_roadmap_implement_job.py`. Changes: `tests/roadmap/test_roadmap_implement_job.py`. -- [ ] 1.1 Add a test for an issue title `wip(cli): add a flag`, whose type the project does not declare, and assert the job stops the item and writes no pull request title +- [x] 1.1 Add a test for an issue title `wip(cli): add a flag`, whose type the project does not declare, and assert the job stops the item and writes no pull request title - Verification: `uv run devops ci test tests/roadmap/test_roadmap_implement_job.py` -- [ ] 1.2 Add a test for a Planned item whose delivery title has no type, and assert the job stops before `_publish` pushes, so `origin` holds no branch and no draft pull request exists +- [x] 1.2 Add a test for a Planned item whose delivery title has no type, and assert the job stops before `_publish` pushes, so `origin` holds no branch and no draft pull request exists - Verification: `uv run devops ci test tests/roadmap/test_roadmap_implement_job.py` ## Workflow follow-up diff --git a/tests/roadmap/test_roadmap_implement_job.py b/tests/roadmap/test_roadmap_implement_job.py index 01c153b3d..f00a405ec 100644 --- a/tests/roadmap/test_roadmap_implement_job.py +++ b/tests/roadmap/test_roadmap_implement_job.py @@ -12,6 +12,7 @@ import shutil import subprocess from collections.abc import Callable +from dataclasses import replace from pathlib import Path import pytest @@ -283,6 +284,58 @@ def test_a_title_that_the_check_refuses_stops_the_item_before_the_job_writes_it( assert "not in the form" in job_world.issue_comments()[0] +def test_a_title_with_a_type_that_the_project_does_not_declare_stops_the_item( + job_world: JobWorld, +) -> None: + """A person may edit the title of the issue after staging (#3368). The type `wip` is not a + Conventional Commit type, so the job stops the item and writes no pull request title.""" + issue = job_world.store._roadmap.issues[1] + job_world.store._roadmap.issues[1] = issue.model_copy(update={"title": "wip(cli): add a flag"}) + + applied = job_world.run(two_groups()) + + status, record = _item(job_world) + assert (applied.stopped, status, record.get("implement.stopped")) == ( + (1,), + "Blocked", + "pull request", + ) + assert job_world.sent("PATCH", f"pulls/{PULL}") == [] + assert "wip" in job_world.issue_comments()[0] + + +def test_a_title_with_no_type_stops_a_planned_item_before_the_first_push( + planned_world: JobWorld, +) -> None: + """A Planned item has no branch until `_publish`. A person may edit the title after the plan + reads it, so the job checks the title again before the first push. A title with no type stops + the item with no branch on `origin` and no draft (#3368).""" + plan = planned_world.plan() + (target,) = plan.selected + edited = replace( + plan, + selected=(replace(target, item=target.item.model_copy(update={"title": "Add a flag"})),), + ) + + applied = apply_implement( + planned_world.store, + edited, + source=planned_world.repo.clone, + model=two_groups().model(), + window=WINDOW, + ) + + status, record = _item(planned_world) + assert (applied.stopped, status, record.get("implement.stopped")) == ( + (1,), + "Blocked", + "push", + ) + assert planned_world.repo.origin_git("branch", "--list", BRANCH) == "" + assert planned_world.sent("POST", "pulls") == [] + assert "not in the form" in planned_world.issue_comments()[0] + + def test_the_changes_of_the_archive_and_the_documents_are_in_the_pushed_tree( job_world: JobWorld, ) -> None: From 74aea12f1333c80296d2e1fd40222ab5b909a097 Mon Sep 17 00:00:00 2001 From: Daniel Petty Date: Wed, 4 Nov 2026 15:55:44 +0000 Subject: [PATCH 2/2] docs(openspec): archive #3368 cover a refused delivery title (#3368) --- .../.openspec.yaml | 0 .../2026-11-04-3368-stop-a-delivery-title-that-the}/design.md | 0 .../2026-11-04-3368-stop-a-delivery-title-that-the}/proposal.md | 0 .../2026-11-04-3368-stop-a-delivery-title-that-the}/tasks.md | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename openspec/changes/{3368-stop-a-delivery-title-that-the => archive/2026-11-04-3368-stop-a-delivery-title-that-the}/.openspec.yaml (100%) rename openspec/changes/{3368-stop-a-delivery-title-that-the => archive/2026-11-04-3368-stop-a-delivery-title-that-the}/design.md (100%) rename openspec/changes/{3368-stop-a-delivery-title-that-the => archive/2026-11-04-3368-stop-a-delivery-title-that-the}/proposal.md (100%) rename openspec/changes/{3368-stop-a-delivery-title-that-the => archive/2026-11-04-3368-stop-a-delivery-title-that-the}/tasks.md (100%) diff --git a/openspec/changes/3368-stop-a-delivery-title-that-the/.openspec.yaml b/openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/.openspec.yaml similarity index 100% rename from openspec/changes/3368-stop-a-delivery-title-that-the/.openspec.yaml rename to openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/.openspec.yaml diff --git a/openspec/changes/3368-stop-a-delivery-title-that-the/design.md b/openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/design.md similarity index 100% rename from openspec/changes/3368-stop-a-delivery-title-that-the/design.md rename to openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/design.md diff --git a/openspec/changes/3368-stop-a-delivery-title-that-the/proposal.md b/openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/proposal.md similarity index 100% rename from openspec/changes/3368-stop-a-delivery-title-that-the/proposal.md rename to openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/proposal.md diff --git a/openspec/changes/3368-stop-a-delivery-title-that-the/tasks.md b/openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/tasks.md similarity index 100% rename from openspec/changes/3368-stop-a-delivery-title-that-the/tasks.md rename to openspec/changes/archive/2026-11-04-3368-stop-a-delivery-title-that-the/tasks.md