Extract shared .sdlc/project.yaml behavior into a cc-os gem #922

Open
opened 2026-10-03 13:19:55 +00:00 by jared · 0 comments
Owner

Problem

Jared asked for this ticket on 2026-10-03: "Capture the .sdlc/project.yaml gem ticket."
Jared's position: the plugin codebases should not call each other. Tiny-to-small shared functionality may be duplicated. Meaningful or somewhat complex shared functionality goes into a gem or gems.
He suspects that most CRUD on .sdlc/project.yaml belongs in such a gem: models such as Project and Target that read or change values in project.yaml, or compose, validate, and write the file. Each plugin would then do its special task and would not build the shared project/target configuration again.
This ticket needs a design ruling from Jared. An ADR is required before work starts.

Observed

Investigation of which plugins touch project configuration (grep over plugins/, 2026-10-03):

  1. Only os-sdlc reads or writes .sdlc/project.yaml. This weakens the case for a gem today: there is no second consumer. Every non-test hit for project.yaml is under plugins/os-sdlc/.
  2. The owners in os-sdlc: plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb (Config.load, load_shared, read, document, write, save_tracker, merge_keys; yaml_path at line 39), adapter/project/root_search.rb (finds the file), model/project.rb and model/project/*.rb (target.rb, codebase.rb, test.rb, lint.rb, root.rb, artifact_dir.rb, validation.rb, target_selection_error.rb), command/project/config_command.rb and controller/project/onboarding.rb (the project-config CLI that writes it).
  3. Other plugins do not touch the file. plugins/os/lib/worktree/checkout.rb:51 creates the .sdlc directory and plugins/os/lib/worktree/linked_entries.rb:6 links .sdlc/pipeline.db; neither reads project.yaml.
  4. .cc-os/config is a separate file with a separate owner: plugins/os-backlog/lib/backlog/config.rb, config_data.rb, config_locator.rb (tracker key). It is a different schema; whether it belongs in the same gem is an open point.
  5. Gem precedent: forgejo-api (ADR-0257) is shared by os-backlog and os-sdlc; procman and pb-mirror live in ~/dev/ruby-gems/ (ADR-0219, ADR-0150). No gem lives inside cc-os today. gems/ does not exist; the repo root holds assets autoresearch bin docs lib plugins reference teach tests tuning. The root lib/ holds arch_metrics and status_table_trimmer.rb, not shared plugin code.

ADRs found by os-adr:find:

  1. ADR-0166 (Accepted): each plugin has its own Gemfile and Gemfile.lock, loaded through one boot file. A shared gem fits: each plugin adds it to its Gemfile. Vendoring is rejected, so copying the whole file logic is not covered.
  2. ADR-0025 (Superseded; amended by 0123 and 0166): standard plugin structure, silent on shared code.
  3. ADR-0257, ADR-0219, ADR-0150 (Accepted): precedents for gems shared across plugins, all outside cc-os.
  4. ADR-0037 (Accepted): os-sdlc lives inside cc-os as a plugin.
  5. ADR-0055, ADR-0074, ADR-0088, ADR-0210 (Accepted): the project.yaml schema (tracked file, unified config, named targets, code_path alias). The gem must implement this schema.
  6. ADR-0177, ADR-0189 (Superseded by ADR-0224, which does not discuss project.yaml): the earlier owner of project.yaml reads and writes (Project::Yaml, Document). Check why they were retired.
  7. No ADR states "plugins must not call each other". ADR-0253 line 31 cites ADR-0193 rule 3 for "the os plugin never calls os-sdlc", but ADR-0193 is Superseded and a worktree-finish CLI call between plugins exists. The new ADR should record the rule if it is to bind.

Correction to the origin of this idea: Jared first read the need for this gem from a test that became a subprocess call in #860. That reading was incorrect for that test. The test calls os-sdlc's own bin/os-sdlc, so it shows no cross-plugin call. Jared keeps the gem idea on its own merit.

Reproduce

n/a: design ticket, nothing to reproduce.

Approach

Rule on these open points before any build. An ADR is required before work starts.

  1. Ruling: is a gem justified while only os-sdlc uses project.yaml? What second consumer exists or is planned?
  2. Location: cc-os/gems/<gem> (Jared's lean: it gives gems/ the same flexibility as plugins/), cc-os/<gem>, or cc-os/libraries/<gem> (Jared suspects this violates YAGNI). Gems normally live in ~/Dev/ruby-gems/; this one is specific to cc-os plugins.
  3. Scope: which classes move (Project, Target, and the CRUD in adapter/project/config.rb) and which stay in os-sdlc; whether .cc-os/config joins the gem.
  4. Run /os-adr:create for the decision; it amends ADR-0166 and cites ADR-0257, ADR-0219, ADR-0150 and the project.yaml schema ADRs.

Required work: none beyond the acceptance criteria.

Acceptance criteria

  1. Given Jared's ruling on the open points, when the ticket is made ready-for-agent, then it names the gem, its location, and the classes that move.
  2. Given the ruling, when work starts, then an ADR recording it exists.

Origin

  • Trigger: Jared asked on 2026-10-03: "Capture the .sdlc/project.yaml gem ticket."
  • Improvised this session: none
  • Chain: duplicated project/target configuration risk ← plugins must not call each other (Jared's rule; no ADR states it) ← project.yaml CRUD sits inside os-sdlc (DESIGN: docs/adr/0055, docs/adr/0074, docs/adr/0088)
  • Root candidate: none
  • Where: plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb and plugins/os-sdlc/lib/os_sdlc/model/project.rb
  • Session: a0dbd5c4-ce77-4eaa-bb8a-9517044ae3ad
  • Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/a0dbd5c4-ce77-4eaa-bb8a-9517044ae3ad.jsonl
## Problem Jared asked for this ticket on 2026-10-03: "Capture the .sdlc/project.yaml gem ticket." Jared's position: the plugin codebases should not call each other. Tiny-to-small shared functionality may be duplicated. Meaningful or somewhat complex shared functionality goes into a gem or gems. He suspects that most CRUD on `.sdlc/project.yaml` belongs in such a gem: models such as `Project` and `Target` that read or change values in project.yaml, or compose, validate, and write the file. Each plugin would then do its special task and would not build the shared project/target configuration again. This ticket needs a design ruling from Jared. An ADR is required before work starts. ## Observed Investigation of which plugins touch project configuration (grep over `plugins/`, 2026-10-03): 1. Only os-sdlc reads or writes `.sdlc/project.yaml`. This weakens the case for a gem today: there is no second consumer. Every non-test hit for `project.yaml` is under `plugins/os-sdlc/`. 2. The owners in os-sdlc: `plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb` (`Config.load`, `load_shared`, `read`, `document`, `write`, `save_tracker`, `merge_keys`; `yaml_path` at line 39), `adapter/project/root_search.rb` (finds the file), `model/project.rb` and `model/project/*.rb` (`target.rb`, `codebase.rb`, `test.rb`, `lint.rb`, `root.rb`, `artifact_dir.rb`, `validation.rb`, `target_selection_error.rb`), `command/project/config_command.rb` and `controller/project/onboarding.rb` (the `project-config` CLI that writes it). 3. Other plugins do not touch the file. `plugins/os/lib/worktree/checkout.rb:51` creates the `.sdlc` directory and `plugins/os/lib/worktree/linked_entries.rb:6` links `.sdlc/pipeline.db`; neither reads project.yaml. 4. `.cc-os/config` is a separate file with a separate owner: `plugins/os-backlog/lib/backlog/config.rb`, `config_data.rb`, `config_locator.rb` (tracker key). It is a different schema; whether it belongs in the same gem is an open point. 5. Gem precedent: `forgejo-api` (ADR-0257) is shared by os-backlog and os-sdlc; `procman` and `pb-mirror` live in `~/dev/ruby-gems/` (ADR-0219, ADR-0150). No gem lives inside cc-os today. `gems/` does not exist; the repo root holds `assets autoresearch bin docs lib plugins reference teach tests tuning`. The root `lib/` holds `arch_metrics` and `status_table_trimmer.rb`, not shared plugin code. ADRs found by `os-adr:find`: 1. ADR-0166 (Accepted): each plugin has its own `Gemfile` and `Gemfile.lock`, loaded through one boot file. A shared gem fits: each plugin adds it to its `Gemfile`. Vendoring is rejected, so copying the whole file logic is not covered. 2. ADR-0025 (Superseded; amended by 0123 and 0166): standard plugin structure, silent on shared code. 3. ADR-0257, ADR-0219, ADR-0150 (Accepted): precedents for gems shared across plugins, all outside cc-os. 4. ADR-0037 (Accepted): os-sdlc lives inside cc-os as a plugin. 5. ADR-0055, ADR-0074, ADR-0088, ADR-0210 (Accepted): the project.yaml schema (tracked file, unified config, named targets, `code_path` alias). The gem must implement this schema. 6. ADR-0177, ADR-0189 (Superseded by ADR-0224, which does not discuss project.yaml): the earlier owner of project.yaml reads and writes (`Project::Yaml`, `Document`). Check why they were retired. 7. No ADR states "plugins must not call each other". ADR-0253 line 31 cites ADR-0193 rule 3 for "the os plugin never calls os-sdlc", but ADR-0193 is Superseded and a worktree-finish CLI call between plugins exists. The new ADR should record the rule if it is to bind. Correction to the origin of this idea: Jared first read the need for this gem from a test that became a subprocess call in #860. That reading was incorrect for that test. The test calls os-sdlc's own `bin/os-sdlc`, so it shows no cross-plugin call. Jared keeps the gem idea on its own merit. ## Reproduce n/a: design ticket, nothing to reproduce. ## Approach Rule on these open points before any build. An ADR is required before work starts. 1. Ruling: is a gem justified while only os-sdlc uses project.yaml? What second consumer exists or is planned? 2. Location: `cc-os/gems/<gem>` (Jared's lean: it gives `gems/` the same flexibility as `plugins/`), `cc-os/<gem>`, or `cc-os/libraries/<gem>` (Jared suspects this violates YAGNI). Gems normally live in `~/Dev/ruby-gems/`; this one is specific to cc-os plugins. 3. Scope: which classes move (`Project`, `Target`, and the CRUD in `adapter/project/config.rb`) and which stay in os-sdlc; whether `.cc-os/config` joins the gem. 4. Run `/os-adr:create` for the decision; it amends ADR-0166 and cites ADR-0257, ADR-0219, ADR-0150 and the project.yaml schema ADRs. Required work: none beyond the acceptance criteria. ## Acceptance criteria 1. Given Jared's ruling on the open points, when the ticket is made ready-for-agent, then it names the gem, its location, and the classes that move. 2. Given the ruling, when work starts, then an ADR recording it exists. ## Origin - Trigger: Jared asked on 2026-10-03: "Capture the .sdlc/project.yaml gem ticket." - Improvised this session: none - Chain: duplicated project/target configuration risk ← plugins must not call each other (Jared's rule; no ADR states it) ← project.yaml CRUD sits inside os-sdlc (DESIGN: docs/adr/0055, docs/adr/0074, docs/adr/0088) - Root candidate: none - Where: plugins/os-sdlc/lib/os_sdlc/adapter/project/config.rb and plugins/os-sdlc/lib/os_sdlc/model/project.rb - Session: a0dbd5c4-ce77-4eaa-bb8a-9517044ae3ad - Transcript: /home/jared/.claude/projects/-home-jared-dev-cc-os/a0dbd5c4-ce77-4eaa-bb8a-9517044ae3ad.jsonl
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#922
No description provided.