Scopes down F3 to just the generic <name>_ENABLED toggle-check primitive (ccam lanes integration <name>) — ticketer/dev-qc agents stay deferred, same reasoning E3 already used for qc-local's credential gap: no tracker/ dev-QC MCP configured anywhere, no per-lane credential source to consume.
4.3 KiB
F3a — ccam lanes integration <name> toggle reader
Status: approved 2026-08-05. Roadmap it belongs to:
docs/superpowers/plans/2026-08-03-shipyard-parity-lanes.md (subsystem F).
Problem
SKILL.md's Setup section hardcodes tracker/dev-QC/CI-wait as permanently off ("treat all three as permanently off for this run") because F's integrations.env toggle system doesn't exist in CCAM yet. Shipyard's source, lane-env.sh --check NAME, is the reference primitive: read one <NAME>_ENABLED flag from a profile's integrations.env, exit 0/1.
This is a narrow slice of F, not all of F3. ticketer (the agent that would actually consume TRACKER_ENABLED) is explicitly deferred — no tracker MCP is configured for any lane yet, and CCAM has no per-lane credential source (same gap E3 already documented for qc-local). This task only builds the toggle-reading primitive itself, so SKILL.md's hardcoded-off text can become a real check instead of a permanent assumption, once something exists to check.
Scope
In scope:
<repo>/.ccam/profile/integrations.env— a new, optional profile file (same directory asprofile.env), parsed with the EXISTINGparseEnvFilehelper inserver/lib/lane-profile.js(comments/quotes/exportalready handled — no new parser).isIntegrationEnabled(lane, name)inserver/lib/lane-profile.js— readsintegrations.env(falling backlane.cwd→lane.source_repo, same two-location searchresolveProfilealready does forprofile.env), returnstrueiff<NAME_UPPER>_ENABLED === "1". A missing file or missing key isfalse— off by default, consistent with A2's declarations.GET /api/lanes/:id/integrations/:nameroute —{enabled: boolean}.ccam lanes integration <name> [<id>]CLI — exit0when enabled,1when disabled (the exit-code contract Shipyard's--checkalready established, and what a skill's&&-gated stage-skip logic needs).
Explicitly out of scope:
ticketer.md/dev-qc.mdagents — deferred pending a tracker/dev-QC MCP and credential source.- Every other field
integrations.envcan declare (TRACKER_URL,TRACKER_PROJECT,DEV_SITE_URL,CI_REPO, etc.) — only the<NAME>_ENABLEDflags matter for this primitive; the rest is read by whatever later task actually consumes a specific integration (F3/F4's real agent work), not by this generic toggle check. - Surfacing toggle state in
GET /api/lanes/:id/runtime— that endpoint is polled and broadcast on every hook; adding fields nothing consumes yet is premature.GET /:id/integrations/:nameis its own lightweight endpoint instead. lane-env.sh's default (no--check) mode — dumping the full per-lane runtime env asexportlines exists in Shipyard because bash/zsh sourcing has a HARNESS_ROOT resolution footgun CCAM's cwd-based lane resolution doesn't have. Nothing in CCAM needs this.
Decisions
| Choice | Rationale | |
|---|---|---|
Reuse parseEnvFile |
Yes, from lane-profile.js, unexported currently — export it |
integrations.env is the same KEY=VALUE shape profile.env already is; a second parser for an identical format would be pure duplication. |
| Two-location search (cwd then source_repo) | Same as profile.env |
A worktree lane's branch may have changed integration config; the source-repo fallback covers a gitignored integrations.env the same way it does for profile.env. |
| Missing file / missing key | false (off) |
Matches every other optional profile declaration's off-by-default shape already established across A2/E1/E2. |
| Case handling | name argument lowercased by convention (tracker, dev_qc, ci_wait), uppercased + _ENABLED appended to build the env key |
Matches Shipyard's own naming (TRACKER_ENABLED, DEV_QC_ENABLED, CI_WAIT_ENABLED) — the CLI argument is the lowercase, readable form; the env var stays the exact Shipyard name so a ported integrations.env file (if a user copies one from Shipyard) needs no field renaming. |
Verify
Unit tests: a profile with TRACKER_ENABLED=1 reads enabled for tracker, a profile with no integrations.env reads disabled for anything, DEV_QC_ENABLED=0 reads disabled, the source-repo fallback works when the lane's own cwd has no file. CLI exit-code test via the route/CLI's own manual smoke check (no automated HTTP harness in this repo, same as every other F/E route).