os-sdlc Runner always commits at implementation_complete: delete the commit_on_complete opt-in #837

Closed
opened 2026-09-29 19:25:31 +00:00 by jared · 2 comments
Owner

Problem

The os-sdlc Runner commits at implementation_complete only when .sdlc/project.yaml sets commit_on_complete: true (ADR-0171, default false). The implement skill then tells the orchestrator: "If the payload carries no commit, the project has not opted in and the commit is the user's to make." No project sets the key, so every run stops before the commit and waits for the user.

An agent added the opt-in and the sentence on 2026-09-09 (f752e9b5, ADR-0171). The user did not ask for either. The defect that ADR-0171 answered was that the orchestrator read full diffs before it committed. The commit itself was not a defect. The user ruled on 2026-09-29: the Runner always commits.

Observed

On 2026-09-29, implementation 78 (#827) returned implementation_complete with no commit field. The orchestrator stopped and asked the user to approve the commit.

Reproduce

/os-sdlc:implement <ticket>     # in cc-os, whose .sdlc/project.yaml has no commit_on_complete
# terminal payload has no `commit`; the skill hands the commit to the user

Approach

Delete the opt-in. Implementation::Commit#call commits whenever it has a git runner. The deterministic commit of handoff-listed paths from ADR-0171 does not change: git add -- <paths>, git commit --only, never -a, -A, checkout, restore or stash.

# Command::Implementation::Commit#call
return nil unless @git
  • OsSdlc::Project loses its commit_on_complete member. Project::Config::Document loses commit_on_complete? and the key in TARGET_KEYS. Project::Snapshot and Implementation::Targeting lose commit_on_complete?.
  • A .sdlc/project.yaml that still sets the key fails implementation-open through the unknown-key check (#832). No project in ~/dev sets it today.

Required work:

  1. No production code reads commit_on_complete — check: ! grep -rq commit_on_complete plugins/os-sdlc/lib plugins/os-sdlc/bin
  2. No test or fixture passes commit_on_complete as a valid setting. The only test file that names the key is plugins/os-sdlc/tests/model/project/validation_retired_commit_key_test.rb, which proves acceptance criterion 2 — check: ! grep -rq --exclude=validation_retired_commit_key_test.rb commit_on_complete plugins/os-sdlc/tests
  3. Delete the implement skill sentence that gives the commit to the user — check: ! grep -q "user's to make" plugins/os-sdlc/skills/implement/SKILL.md
  4. Delete the commit_on_complete bullet from the setup-project skill — check: ! grep -q commit_on_complete plugins/os-sdlc/skills/setup-project/SKILL.md

Rejected: keep the key and set commit_on_complete: true in cc-os — it keeps the agent-added opt-in, and every new project stops at the commit again.
Rejected: the orchestrator commits when the Runner did not — it adds a second commit owner.

Acceptance criteria

  1. Given a .sdlc/project.yaml with no commit key, when an implementation reaches implementation_complete with handoff-listed paths, then the Runner commits those paths and the terminal payload carries commit.
  2. Given a .sdlc/project.yaml that sets commit_on_complete, when implementation-open validates the project, then it fails and names the unknown key commit_on_complete.

Owner sketch

class OsSdlc::Implementation::Commit
  def initialize(implementation:, root:, git: nil)
  def call
end

class OsSdlc::Project < Data.define(:name, :root, :tracker, :targets)
end

class OsSdlc::Project::Config::Document
  TARGET_KEYS
end

Non-goals

  • The ADR that amends ADR-0171 decision 1 (opt-in per project) is recorded by the orchestrator after the run. The user approved the decision on 2026-09-29.
  • The responsibility-refactor skill keeps its orchestrator commits: they commit follow-through edits made after implementation_complete, which the Runner's commit does not include.
  • Historical records (docs/crc/, docs/orchestration-audit/, History rows) keep their wording.

Retired tests

plugins/os-sdlc/tests/model/project_commit_on_complete_test.rb
plugins/os-sdlc/tests/command/implementation/commit_test.rb#test_it_does_nothing_without_the_key
plugins/os-sdlc/tests/model/implementation_empty_project_config_test.rb#test_both_readers_agree_when_config_omits_name_but_carries_commit_on_complete

Origin

  • Trigger: /os-sdlc:implement 827 (implementation 78), 2026-09-29
  • Improvised this session: the orchestrator asked the user for commit approval, then committed 1c5142c1 by hand
  • Chain: run stops before the commit ← skill gives the commit to the user when the payload has no commit ← Runner commits only on opt-in, default false ← DESIGN (ADR-0171, f752e9b5; agent-added, not user-requested)
  • Root candidate: this ticket
  • Where: plugins/os-sdlc/lib/os_sdlc/command/implementation/commit.rb; plugins/os-sdlc/lib/os_sdlc/parser/project/config/document.rb; plugins/os-sdlc/skills/implement/SKILL.md
  • Session: eb87bf9f-0ece-444a-a016-5eaa5c739c98
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/eb87bf9f-0ece-444a-a016-5eaa5c739c98.jsonl
## Problem The os-sdlc Runner commits at `implementation_complete` only when `.sdlc/project.yaml` sets `commit_on_complete: true` (ADR-0171, default `false`). The implement skill then tells the orchestrator: "If the payload carries no `commit`, the project has not opted in and the commit is the user's to make." No project sets the key, so every run stops before the commit and waits for the user. An agent added the opt-in and the sentence on 2026-09-09 (f752e9b5, ADR-0171). The user did not ask for either. The defect that ADR-0171 answered was that the orchestrator read full diffs before it committed. The commit itself was not a defect. The user ruled on 2026-09-29: the Runner always commits. ## Observed On 2026-09-29, implementation 78 (#827) returned `implementation_complete` with no `commit` field. The orchestrator stopped and asked the user to approve the commit. ## Reproduce ``` /os-sdlc:implement <ticket> # in cc-os, whose .sdlc/project.yaml has no commit_on_complete # terminal payload has no `commit`; the skill hands the commit to the user ``` ## Approach Delete the opt-in. `Implementation::Commit#call` commits whenever it has a git runner. The deterministic commit of handoff-listed paths from ADR-0171 does not change: `git add -- <paths>`, `git commit --only`, never `-a`, `-A`, `checkout`, `restore` or `stash`. ```ruby # Command::Implementation::Commit#call return nil unless @git ``` - `OsSdlc::Project` loses its `commit_on_complete` member. `Project::Config::Document` loses `commit_on_complete?` and the key in `TARGET_KEYS`. `Project::Snapshot` and `Implementation::Targeting` lose `commit_on_complete?`. - A `.sdlc/project.yaml` that still sets the key fails implementation-open through the unknown-key check (#832). No project in ~/dev sets it today. Required work: 1. No production code reads `commit_on_complete` — check: `! grep -rq commit_on_complete plugins/os-sdlc/lib plugins/os-sdlc/bin` 2. No test or fixture passes `commit_on_complete` as a valid setting. The only test file that names the key is `plugins/os-sdlc/tests/model/project/validation_retired_commit_key_test.rb`, which proves acceptance criterion 2 — check: `! grep -rq --exclude=validation_retired_commit_key_test.rb commit_on_complete plugins/os-sdlc/tests` 3. Delete the implement skill sentence that gives the commit to the user — check: `! grep -q "user's to make" plugins/os-sdlc/skills/implement/SKILL.md` 4. Delete the `commit_on_complete` bullet from the setup-project skill — check: `! grep -q commit_on_complete plugins/os-sdlc/skills/setup-project/SKILL.md` Rejected: keep the key and set `commit_on_complete: true` in cc-os — it keeps the agent-added opt-in, and every new project stops at the commit again. Rejected: the orchestrator commits when the Runner did not — it adds a second commit owner. ## Acceptance criteria 1. Given a `.sdlc/project.yaml` with no commit key, when an implementation reaches `implementation_complete` with handoff-listed paths, then the Runner commits those paths and the terminal payload carries `commit`. 2. Given a `.sdlc/project.yaml` that sets `commit_on_complete`, when implementation-open validates the project, then it fails and names the unknown key `commit_on_complete`. ## Owner sketch ```ruby class OsSdlc::Implementation::Commit def initialize(implementation:, root:, git: nil) def call end class OsSdlc::Project < Data.define(:name, :root, :tracker, :targets) end class OsSdlc::Project::Config::Document TARGET_KEYS end ``` ## Non-goals - The ADR that amends ADR-0171 decision 1 (opt-in per project) is recorded by the orchestrator after the run. The user approved the decision on 2026-09-29. - The responsibility-refactor skill keeps its orchestrator commits: they commit follow-through edits made after `implementation_complete`, which the Runner's commit does not include. - Historical records (docs/crc/, docs/orchestration-audit/, History rows) keep their wording. ## Retired tests plugins/os-sdlc/tests/model/project_commit_on_complete_test.rb plugins/os-sdlc/tests/command/implementation/commit_test.rb#test_it_does_nothing_without_the_key plugins/os-sdlc/tests/model/implementation_empty_project_config_test.rb#test_both_readers_agree_when_config_omits_name_but_carries_commit_on_complete ## Origin - Trigger: /os-sdlc:implement 827 (implementation 78), 2026-09-29 - Improvised this session: the orchestrator asked the user for commit approval, then committed 1c5142c1 by hand - Chain: run stops before the commit ← skill gives the commit to the user when the payload has no `commit` ← Runner commits only on opt-in, default false ← DESIGN (ADR-0171, f752e9b5; agent-added, not user-requested) - Root candidate: this ticket - Where: plugins/os-sdlc/lib/os_sdlc/command/implementation/commit.rb; plugins/os-sdlc/lib/os_sdlc/parser/project/config/document.rb; plugins/os-sdlc/skills/implement/SKILL.md - Session: eb87bf9f-0ece-444a-a016-5eaa5c739c98 - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/eb87bf9f-0ece-444a-a016-5eaa5c739c98.jsonl
Author
Owner

Work started on branch ticket-837 (worktree) via /os-sdlc:implement.

Work started on branch ticket-837 (worktree) via /os-sdlc:implement.
Author
Owner

Resolution

Done: The os-sdlc Runner always commits at implementation_complete. commit_on_complete is removed from Project, Config::Document, Snapshot and Targeting; a project.yaml that sets it fails implementation-open as an unknown key. The implement skill sentence that handed the commit to the user and the setup-project bullet are deleted. ADR-0249 amends ADR-0171 decision 1.

Evidence: Commit 01f5edf9 on ticket-837. os-sdlc implementation 2: 10 dispatches (2-11), implementation_complete in 8 min 24 s; suite-check gate required-work exit 0, suite exit 0; behavior-verifier pass on both acceptance criteria. Implementation 1 escalated at change-auditor (ticket R2 check conflicted with AC 2); ticket fixed and reopened.

Follow-ups: none

## Resolution **Done:** The os-sdlc Runner always commits at implementation_complete. commit_on_complete is removed from Project, Config::Document, Snapshot and Targeting; a project.yaml that sets it fails implementation-open as an unknown key. The implement skill sentence that handed the commit to the user and the setup-project bullet are deleted. ADR-0249 amends ADR-0171 decision 1. **Evidence:** Commit 01f5edf9 on ticket-837. os-sdlc implementation 2: 10 dispatches (2-11), implementation_complete in 8 min 24 s; suite-check gate required-work exit 0, suite exit 0; behavior-verifier pass on both acceptance criteria. Implementation 1 escalated at change-auditor (ticket R2 check conflicted with AC 2); ticket fixed and reopened. **Follow-ups:** none
jared closed this issue 2026-09-29 19:38:39 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jared/cc-os#837
No description provided.