Review: [Ch 9] CI/CD — add lint, security scan, and test steps
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type — Feature
- [x] Lineage — present
- [x] Repo — present (ldraney/mdview)
- [x] User Story — present
- [x] Context — present
- [x] File Targets — present
- [x] Feature Flag — present (none)
- [x] Acceptance Criteria — present (4 items)
- [x] Test Expectations — present
- [x] Constraints — present
- [x] Checklist — present
- [x] Related — present
Traceability
- [x] story:full-stack label — "Register READMEs via CLI, browse on phone via iOS app with Keycloak auth"
- [x] story note verified — found in project-mdview user-stories section (status: TBD)
- [x] arch:mdview-app label — present on board item
- [ ] arch note MISSING — [SCOPE] Create architecture note arch-mdview-app for component mdview-app
- [x] Forgejo issue — https://forgejo.tail5b443a.ts.net/ldraney/mdview/issues/18, open
File Targets
- [x]
.woodpecker.yaml— verified: exists, currently contains only clone and build-and-push steps. No lint/security steps yet, matching issue description. - [x]
Dockerfile— correctly listed as "should NOT touch" - [x]
Gemfile— correctly listed as "should NOT touch"; gems verified present: rubocop-rails-omakase (line 43), brakeman (line 40), bundler-audit (line 37). All confirmed in Gemfile.lock. - [x]
.rubocop.yml— exists, inherits from rubocop-rails-omakase - [x]
config/bundler-audit.yml— exists with placeholder ignore list
Repo Placement
OK. Issue filed on ldraney/mdview, fix targets ldraney/mdview. Single-repo change.
Dependencies
- Board item #1242 "Add .woodpecker.yaml CI pipeline" — done. This is the existing pipeline this ticket extends.
- No other board items block or are blocked by #1949.
Acceptance Criteria
4 criteria, all agent-verifiable by checking Woodpecker pipeline output after push to main. Criteria are clear and measurable. No missing criteria detected.
Blast Radius
- Image name conflict: The constraint says
harbor.tail5b443a.ts.net/library/rails-base:latestbut the landscaping-assistant pattern (also referenced in constraints) usesharbor.tail5b443a.ts.net/library/ruby-rails-build:latest. These are different images. The agent implementing this will not know which to use. - Missing bundle-install step: The landscaping-assistant CI pattern has a separate
bundle-installstep that copies pre-cached gems from the image (cp -a /usr/local/bundle/. vendor/bundle/) before lint can run. The mdview issue does not mention this step. Without it, rubocop/brakeman/bundler-audit gems will not be available in the lint step unless the specified image already has them installed. This is a critical implementation detail. - 10+ sibling repos have Woodpecker CI configs. No blast radius beyond mdview — this is a self-contained CI change.
Decomposition Assessment
1 file target in 1 repo. 4 acceptance criteria. Estimated agent work well under 5 minutes. No decomposition needed.
Recommendation
[SCOPE]Create architecture notearch-mdview-appfor component mdview-app in pal-e-docs.[BODY]Fix image name conflict in Constraints section: constraint saysrails-base:latestbut the landscaping-assistant pattern usesruby-rails-build:latest. Clarify which image to use, or confirm they are the same.[BODY]Addbundle-installstep to File Targets or Constraints: the landscaping-assistant pattern requires a separate bundle-install step before lint. Either (a) add it as an explicit step in the spec, or (b) confirm the lint image has all gems pre-installed and no bundle-install step is needed.