Review: linkedin-scheduler-remote — Add Woodpecker CI pipeline and k8s manifests
Verdict: NEEDS_REFINEMENT
Template Completeness
Compared against
template-issue-feature:- [ ]
### Type— missing (defaults to Feature, acceptable) - [ ]
### Lineage— missing. References plan-2026-02-25-mcp-gateway-migration Phase 3, but uses non-standard "### Plan" header - [x]
### Repo— present: linkedin-scheduler-remote - [x]
### User Story— present and well-formed - [ ]
### Context— missing. "Additional Information" provides technical details but not motivation for zero-knowledge reader - [ ]
### File Targets— missing as formal section. File list in "Changes" under Additional Information doesn't follow template format - [x]
### Acceptance Criteria— present (2 criteria) - [ ]
### Test Expectations— missing. No test commands or verification steps - [ ]
### Constraints— missing - [x]
### Checklist— present - [x]
### Related— present
Traceability
- [x] story:superuser-onboard — present on board item
- [x] arch:ci-pipeline — present on board item
- [x] Forgejo issue — forgejo_admin/linkedin-scheduler-remote#3, open
- [x] type:feature — present on board item
File Targets
CRITICAL FINDING: Most work described in the issue is ALREADY DONE. Verified against current repo state on main branch:
- [x]
.woodpecker.yml— ALREADY EXISTS (note: .yml not .yaml as issue states). Has test step (ruff) + build-and-push step (kaniko to Harbor). Uses Forgejo PyPI for private deps. - [x]
Dockerfile— ALREADY EXISTS (namedDockerfilenotDockerfile.k8sas issue states). Multi-stage build with requirements.txt. - [x]
k8s/deployment.yaml— ALREADY EXISTS. All env vars present. Port 8000. 256Mi memory limit. Health checks. imagePullSecrets. - [ ]
k8s/service.yaml— Does NOT exist as separate file. Service is defined inline at bottom of deployment.yaml. - [ ]
k8s/pvc.yaml— Does NOT exist as separate file. PVC is defined inline at bottom of deployment.yaml. - [x]
k8s/servicemonitor.yaml— ALREADY EXISTS - [x]
k8s/kustomization.yaml— ALREADY EXISTS but only lists deployment.yaml + servicemonitor.yaml - [ ]
server.py— EXISTS but NO /metrics endpoint found - [ ]
pyproject.toml— needs verification for dev deps and ruff config
Repo Placement
Correct — issue is filed on linkedin-scheduler-remote and work happens there. Note: current server.py has PORT default 8002, but k8s deployment already sets PORT=8000 via env var, so this is fine.
Dependencies
- Board item #64 (gcal-scheduler CI+k8s) is in
done— no blocker - notion-mcp-remote (reference pattern) is merged — no blocker
- Harbor project appears to already exist (Woodpecker CI references
harbor.tail5b443a.ts.net/linkedin-scheduler-remote/server) - Woodpecker secrets appear configured (build step references harbor_username, harbor_password, forgejo_publish_user, forgejo_publish_token)
- No dependency on other board items
Acceptance Criteria
- CI criterion: "Woodpecker runs ruff lint/format checks and builds a container image to Harbor" — this appears to ALREADY WORK based on existing .woodpecker.yml.
- Deploy criterion: "deploys with correct env vars, port 8000, PVC, and ServiceMonitor" — mostly already in place. Only missing: separate service.yaml/pvc.yaml files and /metrics endpoint.
- Missing criterion: No verification that /metrics endpoint works. No criterion for splitting inline resources into separate files.
Blast Radius
Low blast radius. The remaining work is minor:
- Extract Service and PVC from deployment.yaml into separate files (cosmetic, aligns with pattern)
- Update kustomization.yaml to reference all 4 resources
- Add /metrics endpoint to server.py
- Add ruff config to pyproject.toml if missing
The .woodpecker.yml uses
.yml extension while the notion-mcp-remote pattern uses .yaml. Woodpecker supports both, but convention alignment may be desired.Decomposition
Remaining scope is small (3-4 file changes). Single agent pass is fine IF the scope is narrowed to reflect what is actually left to do.
Recommendation
The issue scope is fundamentally stale — it describes creating files that already exist. Before moving to next_up:
- Audit and rewrite scope — the issue body describes work that is roughly 80% done. Rewrite to reflect only remaining delta: split inline resources, add /metrics, add ruff config
- Add File Targets section — list ONLY the files that still need changes, with what exactly changes
- Add Test Expectations — at minimum: ruff passes, /metrics returns valid Prometheus output, kubectl apply dry-run succeeds for all k8s/ files
- Decide on .yml vs .yaml — current file is .woodpecker.yml, reference pattern is .woodpecker.yaml. Specify which is canonical.
- Consider closing as mostly-done — if the remaining delta is trivial enough, it may make more sense to close this issue and open a new, smaller one for just the /metrics + file split work