name: sweep-labs description: > Diff connect-labs workflows/pipelines/synthetic/solicitations against the live-set, score orphans, auto-delete/disable. Funds and standalone reviews/responses remain report-only (no upstream per-type atom yet). disable-model-invocation: true
sweep-labs
Find connect-labs artifacts (workflows, pipelines, synthetic opportunities, solicitations, funds, reviews, responses) that no current opp references. Workflows, pipelines, synthetic opps, and solicitations have first-class delete/disable atoms in the labs MCP — deletable in the execute pass, after the orchestrator's per-system human-confirmation gate (see agents/sweep.md § Human-confirmation gate). The remaining LabsRecord-backed types (funds + standalone reviews/responses) are report-only by design until per-type atoms exist upstream. Reviews and responses cascade-delete with their parent solicitation, so they generally don't need standalone cleanup.
Inputs
- Live-set file path from
sweep-live-set. LABS_MCP_TOKENand labs base URL (loaded viaconnect-labsMCP).- Labs admin base URL:
https://labs.connect.dimagi.com. mode—recommend(default) |execute. Inrecommendthe skill is report-only: diff/score/render + return the recommended-action list; no mutations (no delete/disable). Inexecuteit mutates onlyapprovedIds. The human-confirmation gate between the two is the orchestrator's job — seeagents/sweep.md § Human-confirmation gate.approvedIds(executemode only) — the exact workflow/pipeline/synthetic/solicitation ids the human approved in chat. Mutate nothing outside this set.
Products
ACE/_sweep/<timestamp>/labs-orphans.md— human-readable triage report.ACE/_sweep/<timestamp>/labs-orphans.yaml— machine-readableOrphanReport.- For approved orphan workflows:
workflow_deletecalls. - For approved orphan pipelines:
pipeline_deletecalls. - For approved orphan synthetic opps:
synthetic_disablecalls. - For approved orphan solicitations:
delete_solicitationcalls (cascade-deletes reviews + responses; gated on cascade emptiness — connect-labs PR #197).
Process
- Read the live-set via
drive_read_file. - List labs inventory using existing atoms:
workflow_listpipeline_listlist_solicitations(each entry includesprogram_idandstatusfields — both needed for the delete call)list_fundslist_reviewslist_responses
- Diff against the live-set's labs buckets:
- workflows →
liveSet.identifiers.labsWorkflowIds - pipelines →
liveSet.identifiers.labsPipelineIds - synthetic opps →
liveSet.identifiers.labsSyntheticIds - solicitations/funds/reviews/responses →
liveSet.identifiers.labsRecordIds
- workflows →
- Score each orphan via
scoreLabsItem(item, liveSet)fromlib/sweep-fingerprint.ts. The scorer defensively downgrades tolowwhen an item references a Connect opportunity that's still inliveSet.identifiers.connectOpportunityIds— that's a sign the caller mis-flagged the item. - Build the
OrphanReportwithsystem: 'labs'. Partition into:- Actionable (deleted in the execute pass, after human approval): workflows, pipelines, synthetic opps, orphan solicitations. Solicitation deletion is gated on
responses + reviews == 0(cascade emptiness), not on lifecycle status — every ACE dogfood solicitation passes that gate cleanly because no real LLO ever engaged. See connect-labs PR #197. - Informational only: funds, standalone reviews/responses (reviews+responses that were already cascade-deleted with a parent solicitation don't appear here). Funds may need their own per-type atom in a future labs MCP release; reviews/responses generally cascade with their parent solicitation.
- Actionable (deleted in the execute pass, after human approval): workflows, pipelines, synthetic opps, orphan solicitations. Solicitation deletion is gated on
- Render + write
labs-orphans.mdand.yamlto the sweep folder. - Recommend — stop here in
mode: recommend. Return the structured recommended-action list (orphan workflows/pipelines/synthetic to delete-or-disable; orphan solicitations to delete with their cascade preview — each with id, confidence) plus the informational-only items (funds, standalone reviews/responses) and the report Drive link, to the orchestrator. Perform no mutations. Do not try to prompt the human from this skill — a dispatched subagent can't reach them; the orchestrator runs the confirmation gate (seeagents/sweep.md § Human-confirmation gate).
Execute phase (mode: execute only)
Runs only when the orchestrator re-dispatches with mode: execute + approvedIds (the ids the human approved in chat). Mutate only those ids:
- Orphan workflows →
workflow_delete({ workflow_id }) - Orphan pipelines →
pipeline_delete({ pipeline_id }) - Orphan synthetic opps →
synthetic_disable({ synthetic_opp_id }) - Orphan solicitations →
delete_solicitation({ solicitation_id, program_id }). The atom cascade-deletes the solicitation's reviews and responses in one call and returns the count of records deleted at each level — surface that in the result so the human sees the cascade impact. Passforce: trueonly for the rare legitimate destroy-with-engagement-data case (test fixtures that intentionally include responses) — and only if the human explicitly approved that override.
Funds + standalone reviews/responses are never mutated (report-only). Return the per-item result.
Failure modes
- Live-set path doesn't resolve: abort with "Run
sweep-live-setfirst." - Labs MCP returns 401:
LABS_MCP_TOKENis expired; recommend/ace:labs-token-mintto rotate, then retry. workflow_deletefails because the workflow has running tasks: report the item as "in-use — needs manual review"; don't retry, don't abort the batch.delete_solicitationrefused (FAILED_PRECONDITIONwith response/review counts): the solicitation has real engagement data — a real LLO filed a response or a review was created. Surface the counts in the chat output; do NOT passforce: trueautomatically. The operator decides whether to override.
Why funds + standalone reviews/responses remain report-only
The labs MCP exposes per-type delete for solicitations because solicitations are the lifecycle unit for the audit-data ecosystem (reviews and responses are children that cascade-delete with their parent). The other LabsRecord types intentionally don't have per-type delete atoms because:
- Funds may have allocations + downstream allocation refs from responses. A future
delete_fundatom would need similar lifecycle guards (and the labs team hasn't surfaced demand for one yet — funds tend to be reused across solicitations rather than created per-opp). - Standalone reviews/responses (not cascade-deleted with a parent solicitation) are uncommon — if they exist as true orphans, they were probably created by a buggy producer and should be investigated rather than auto-deleted. Surface them for visibility.
If the labs team adds delete_fund upstream, this skill's coverage matrix entry flips automatically — the proxy is a pure forwarder so no ACE-side wiring is needed beyond updating Step 5/6/9 and agents/sweep.md.
Related skills
sweep-live-setproduces the live-set this skill diffs against.