opencode-swarm 7.124.0 → 7.125.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/skills/critic-gate/SKILL.md +8 -0
- package/.opencode/skills/swarm/SKILL.md +12 -8
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +245 -171
- package/.opencode/skills/swarm-pr-feedback/references/bot-claim-verification.md +71 -0
- package/.opencode/skills/swarm-pr-feedback/references/operational-gotchas.md +49 -0
- package/.opencode/skills/swarm-pr-review/SKILL.md +238 -412
- package/.opencode/skills/swarm-pr-review/references/parser-dry-run.md +235 -0
- package/.opencode/skills/swarm-pr-review/references/prompt-templates.md +103 -0
- package/.opencode/skills/writing-tests/SKILL.md +4 -123
- package/.opencode/skills/writing-tests/references/mock-and-seam-inventory.md +43 -0
- package/README.md +3 -1
- package/dist/background/lane-output-store.d.ts +10 -0
- package/dist/background/pending-delegations.d.ts +3 -0
- package/dist/background/workspace-snapshot.d.ts +59 -0
- package/dist/cli/{config-doctor-53mnpeke.js → config-doctor-g3m2q646.js} +2 -2
- package/dist/cli/{curation-policy-ny033330.js → curation-policy-vgbx8530.js} +2 -2
- package/dist/cli/{curator-llm-factory-e0tjz8qq.js → curator-llm-factory-7pvqy94w.js} +15 -14
- package/dist/cli/{curator-nvn1pdq6.js → curator-xk4g1nx2.js} +15 -14
- package/dist/cli/{evidence-summary-service-9hq7n9k9.js → evidence-summary-service-v4h2w487.js} +1 -1
- package/dist/cli/{guardrail-explain-d3dd57nf.js → guardrail-explain-wfk16bpr.js} +16 -15
- package/dist/cli/{guardrail-log-3q2z9axs.js → guardrail-log-5zz9xx6z.js} +3 -3
- package/dist/cli/{hive-promoter-9gbpepgm.js → hive-promoter-njwc5rt0.js} +15 -14
- package/dist/cli/{pending-delegations-e3bcqj77.js → index-0cz1ws47.js} +4 -18
- package/dist/cli/{index-3yyr4ynk.js → index-3k8pg467.js} +1 -1
- package/dist/cli/{index-x2mmnrnx.js → index-83rwq7pb.js} +1 -1
- package/dist/cli/{index-c6crt5rs.js → index-8yvqkbw7.js} +12 -2
- package/dist/cli/{index-z0m4angq.js → index-93cq8t5b.js} +5 -5
- package/dist/cli/{index-8pz0ypxz.js → index-cz6fv84h.js} +17 -16
- package/dist/cli/{index-mkkx1a4f.js → index-dsf1yv4s.js} +1588 -891
- package/dist/cli/{index-4rzzzjtg.js → index-fs02c7tz.js} +277 -16
- package/dist/cli/{index-zjedv2bd.js → index-ghteqdy1.js} +2 -2
- package/dist/cli/{index-13d2g7k9.js → index-kvrk3h8p.js} +1 -1
- package/dist/cli/{index-eeg04r0x.js → index-kws8zn6y.js} +1 -1
- package/dist/cli/index-mg54y5gc.js +564 -0
- package/dist/cli/{index-qd77aft9.js → index-mhhmecsw.js} +2 -2
- package/dist/cli/{index-2x4maxte.js → index-mwdcvh0e.js} +4 -4
- package/dist/cli/{index-e19mxn9f.js → index-pbjenws7.js} +1 -1
- package/dist/cli/{index-wqwpzhv1.js → index-rpg8qqjs.js} +2 -2
- package/dist/cli/{index-tyg0zezw.js → index-tn3shyqj.js} +3 -3
- package/dist/cli/{index-htbjqftb.js → index-txragda9.js} +1 -1
- package/dist/cli/{index-v5ecczts.js → index-z4sc6yxc.js} +1 -1
- package/dist/cli/index.js +15 -14
- package/dist/cli/{knowledge-escalator-r1s01m3z.js → knowledge-escalator-jtyykzqc.js} +3 -3
- package/dist/cli/{knowledge-events-a9hmxvke.js → knowledge-events-qhr97sy9.js} +1 -1
- package/dist/cli/{knowledge-store-jt31br5k.js → knowledge-store-332x3pjv.js} +1 -1
- package/dist/cli/{knowledge-validator-9vrwxr3z.js → knowledge-validator-3t8tgzsz.js} +4 -4
- package/dist/cli/pending-delegations-7j8xqg5f.js +34 -0
- package/dist/cli/{scan-cursor-bkjtsawg.js → scan-cursor-q21c9k9q.js} +2 -2
- package/dist/cli/{schema-y3z416z7.js → schema-y2d7j2jk.js} +1 -1
- package/dist/cli/{skill-generator-794hyndw.js → skill-generator-3gkxx98d.js} +5 -5
- package/dist/cli/workspace-snapshot-c9pxxt9a.js +48 -0
- package/dist/commands/close.d.ts +4 -2
- package/dist/commands/registry.d.ts +1 -1
- package/dist/config/schema.d.ts +4 -0
- package/dist/evidence/documents-retention.d.ts +116 -0
- package/dist/evidence/manager.d.ts +17 -0
- package/dist/hooks/pr-workflow-gate.d.ts +211 -0
- package/dist/hooks/pr-workflow-response-gate.d.ts +23 -0
- package/dist/hooks/pr-workflow-session-resolver.d.ts +14 -0
- package/dist/index.js +563 -523
- package/dist/tools/complete-pr-workflow.d.ts +5 -0
- package/dist/tools/dispatch-lanes.d.ts +44 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/manifest.d.ts +2 -0
- package/dist/tools/run-pr-feedback-stage-a.d.ts +69 -0
- package/dist/tools/tool-metadata.d.ts +8 -0
- package/dist/tools/write-pr-review-trigger-eval.d.ts +56 -46
- package/package.json +1 -1
- package/dist/cli/index-dqh3zhhc.js +0 -133
- package/dist/cli/workspace-snapshot-eyf6gd0d.js +0 -22
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Dry-Run: Parser-Based Candidate Extraction
|
|
2
|
+
|
|
3
|
+
This section demonstrates the new parser-based extraction path end-to-end
|
|
4
|
+
using synthetic data. It is concrete enough to implement the same pattern in
|
|
5
|
+
another skill.
|
|
6
|
+
|
|
7
|
+
### Scenario
|
|
8
|
+
|
|
9
|
+
A PR review has dispatched six base explorer lanes via `dispatch_lanes_async`.
|
|
10
|
+
The batch completed and `collect_lane_results` returned:
|
|
11
|
+
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"batch_id": "batch-a1b2c3",
|
|
15
|
+
"lane_results": [
|
|
16
|
+
{
|
|
17
|
+
"lane_id": "pr_review_lane1_correctness",
|
|
18
|
+
"status": "completed",
|
|
19
|
+
"output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
20
|
+
"output_degraded": false
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"lane_id": "pr_review_lane2_security",
|
|
24
|
+
"status": "completed",
|
|
25
|
+
"output_ref": "L1:dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd:eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
|
26
|
+
"output_degraded": false
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Step 1 — Call the parser
|
|
33
|
+
|
|
34
|
+
The orchestrator calls `parse_lane_candidates` for each `output_ref`:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"tool": "parse_lane_candidates",
|
|
39
|
+
"arguments": {
|
|
40
|
+
"output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
41
|
+
"producer": "swarm-pr-review",
|
|
42
|
+
"expected_family": "base_explorer"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Step 2 — Structured response
|
|
48
|
+
|
|
49
|
+
The parser returns a `ParseResultWithSidecar`. On success, `error` and `error_code` are absent:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"candidates": [
|
|
54
|
+
{
|
|
55
|
+
"record_type": "candidate",
|
|
56
|
+
"row_format_family": "base_explorer",
|
|
57
|
+
"row_format_version": 1,
|
|
58
|
+
"record_version": { "major": 1, "minor": 1 },
|
|
59
|
+
"source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
60
|
+
"source_batch_id": "B-2025-06-22-001",
|
|
61
|
+
"source_lane_id": "explorer-1",
|
|
62
|
+
"source_agent": "paid_explorer",
|
|
63
|
+
"source_digest": "sha256:abc123def456...",
|
|
64
|
+
"extracted_from_partial_source": false,
|
|
65
|
+
"sessionId": "ses_01HXYZ...",
|
|
66
|
+
"parentSessionId": "ses_01HABC...",
|
|
67
|
+
"producer": "swarm-pr-review",
|
|
68
|
+
"candidate_id": "C-001",
|
|
69
|
+
"lane": "Lane 1: Correctness and edge cases",
|
|
70
|
+
"micro_lane": null,
|
|
71
|
+
"severity": "HIGH",
|
|
72
|
+
"category": "null-safety",
|
|
73
|
+
"file_line": "src/utils/cache.ts:142",
|
|
74
|
+
"claim": "Uncached getter may return undefined on cold start",
|
|
75
|
+
"evidence_summary": "The `getCached` function returns `cache[key]` without a fallback when the cache is empty.",
|
|
76
|
+
"impact_context": "Downstream callers in `src/handlers/*.ts` expect a defined value and call `.toString()` directly.",
|
|
77
|
+
"invariant_violated": null,
|
|
78
|
+
"confidence": "HIGH"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"record_type": "candidate",
|
|
82
|
+
"row_format_family": "base_explorer",
|
|
83
|
+
"row_format_version": 1,
|
|
84
|
+
"record_version": { "major": 1, "minor": 1 },
|
|
85
|
+
"source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
86
|
+
"source_batch_id": "B-2025-06-22-001",
|
|
87
|
+
"source_lane_id": "explorer-1",
|
|
88
|
+
"source_agent": "paid_explorer",
|
|
89
|
+
"source_digest": "sha256:abc123def456...",
|
|
90
|
+
"extracted_from_partial_source": false,
|
|
91
|
+
"sessionId": "ses_01HXYZ...",
|
|
92
|
+
"parentSessionId": "ses_01HABC...",
|
|
93
|
+
"producer": "swarm-pr-review",
|
|
94
|
+
"candidate_id": "C-002",
|
|
95
|
+
"lane": "Lane 1: Correctness and edge cases",
|
|
96
|
+
"micro_lane": null,
|
|
97
|
+
"severity": "MEDIUM",
|
|
98
|
+
"category": "async-ordering",
|
|
99
|
+
"file_line": "src/services/queue.ts:88",
|
|
100
|
+
"claim": "Race between `drain` and `processNext` may drop items",
|
|
101
|
+
"evidence_summary": "`drain` sets `active = false` before awaiting `processNext`, which also checks `active`.",
|
|
102
|
+
"impact_context": "Items submitted during the drain window are silently dropped.",
|
|
103
|
+
"invariant_violated": null,
|
|
104
|
+
"confidence": "MEDIUM"
|
|
105
|
+
}
|
|
106
|
+
],
|
|
107
|
+
"invocation_envelope": {
|
|
108
|
+
"record_type": "invocation",
|
|
109
|
+
"source_output_ref": "L1:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb:cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc",
|
|
110
|
+
"source_batch_id": "B-2025-06-22-001",
|
|
111
|
+
"source_lane_id": "explorer-1",
|
|
112
|
+
"source_agent": "paid_explorer",
|
|
113
|
+
"source_digest": "sha256:abc123def456...",
|
|
114
|
+
"row_format_version": 1,
|
|
115
|
+
"record_version": { "major": 1, "minor": 1 },
|
|
116
|
+
"sessionId": "ses_01HXYZ...",
|
|
117
|
+
"parentSessionId": "ses_01HABC...",
|
|
118
|
+
"producer": "swarm-pr-review",
|
|
119
|
+
"produced_at": "2025-06-22T14:30:00.000Z",
|
|
120
|
+
"format_families_detected": ["base_explorer"],
|
|
121
|
+
"candidate_count": 2,
|
|
122
|
+
"parse_errors": 0,
|
|
123
|
+
"malformed_rows": 0,
|
|
124
|
+
"clean_attestation_count": 0
|
|
125
|
+
},
|
|
126
|
+
"diagnostics": {
|
|
127
|
+
"candidate_count": 2,
|
|
128
|
+
"parse_errors": 0,
|
|
129
|
+
"parse_error_details": [],
|
|
130
|
+
"malformed_rows": 0,
|
|
131
|
+
"duplicate_id_count": 0,
|
|
132
|
+
"duplicate_id_warnings": [],
|
|
133
|
+
"degraded_source_count": 0,
|
|
134
|
+
"incomplete_source_count": 0,
|
|
135
|
+
"format_families_detected": ["base_explorer"],
|
|
136
|
+
"clean_attestation_count": 0
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
> **Note**: callers pass `expected_family` for each dispatch batch. A recognizable
|
|
141
|
+
> conflicting header fails closed with `expected-family-mismatch`; when the flag
|
|
142
|
+
> is absent, the recognized header controls the mapping and positional detection
|
|
143
|
+
> is only a legacy unknown-header fallback. Marker-prefixed data rows remain
|
|
144
|
+
> accepted for compatibility. Valid canonical rows produce `parse_errors: 0`.
|
|
145
|
+
|
|
146
|
+
On refusal (e.g. `output_ref` does not exist), `error` and `error_code` are present; `candidates` is `[]`; `invocation_envelope` and `diagnostics` are populated with empty fields for traceability:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"error": "Artifact reference not found in store",
|
|
151
|
+
"error_code": "ref-not-found",
|
|
152
|
+
"candidates": [],
|
|
153
|
+
"invocation_envelope": {
|
|
154
|
+
"record_type": "invocation",
|
|
155
|
+
"source_output_ref": "L1:1111111111111111111111111111111111111111111111111111111111111111:2222222222222222222222222222222222222222222222222222222222222222:3333333333333333333333333333333333333333333333333333333333333333",
|
|
156
|
+
"source_batch_id": "",
|
|
157
|
+
"source_lane_id": "",
|
|
158
|
+
"source_agent": "",
|
|
159
|
+
"source_digest": "",
|
|
160
|
+
"row_format_version": 1,
|
|
161
|
+
"record_version": { "major": 1, "minor": 1 },
|
|
162
|
+
"produced_at": "2025-06-22T14:30:00.000Z",
|
|
163
|
+
"format_families_detected": [],
|
|
164
|
+
"candidate_count": 0,
|
|
165
|
+
"parse_errors": 0,
|
|
166
|
+
"malformed_rows": 0,
|
|
167
|
+
"clean_attestation_count": 0
|
|
168
|
+
},
|
|
169
|
+
"diagnostics": {
|
|
170
|
+
"candidate_count": 0,
|
|
171
|
+
"parse_errors": 0,
|
|
172
|
+
"parse_error_details": [],
|
|
173
|
+
"malformed_rows": 0,
|
|
174
|
+
"duplicate_id_count": 0,
|
|
175
|
+
"duplicate_id_warnings": [],
|
|
176
|
+
"degraded_source_count": 0,
|
|
177
|
+
"incomplete_source_count": 0,
|
|
178
|
+
"format_families_detected": [],
|
|
179
|
+
"clean_attestation_count": 0
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Step 3 — Filter and group
|
|
185
|
+
|
|
186
|
+
The orchestrator filters the returned `candidates[]` array by `producer: "swarm-pr-review"` and the exact allowed `source_batch_id` / `source_lane_id` tuples, then groups
|
|
187
|
+
the candidates. In this synthetic example, the two candidates above are grouped
|
|
188
|
+
by file area:
|
|
189
|
+
|
|
190
|
+
- **Chunk A — `src/utils/`** (1 candidate): C-001
|
|
191
|
+
- **Chunk B — `src/services/`** (1 candidate): C-002
|
|
192
|
+
|
|
193
|
+
If there were more candidates, the orchestrator would also group by category
|
|
194
|
+
(e.g., `null-safety`, `async-ordering`) and cap each chunk at 50 candidates.
|
|
195
|
+
|
|
196
|
+
### Step 4 — Dispatch reviewer lanes
|
|
197
|
+
|
|
198
|
+
The orchestrator dispatches one reviewer lane per chunk:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
You are the independent reviewer. Validate only the candidates assigned below.
|
|
202
|
+
Do not search for new issues except where needed to validate reachability or
|
|
203
|
+
mitigation. Do not trust explorer severity.
|
|
204
|
+
|
|
205
|
+
Context pack summary:
|
|
206
|
+
- scope: ...
|
|
207
|
+
- obligations: ...
|
|
208
|
+
- impact cone: ...
|
|
209
|
+
- deterministic signals: ...
|
|
210
|
+
- relevant Swarm artifacts / knowledge: ...
|
|
211
|
+
- base_ref: <commit SHA of base branch>
|
|
212
|
+
- head_ref: <commit SHA of PR head branch>
|
|
213
|
+
|
|
214
|
+
Candidates (Chunk A — src/utils/):
|
|
215
|
+
- C-001 | HIGH | null-safety | src/utils/cache.ts:142 | Uncached getter may return undefined on cold start
|
|
216
|
+
|
|
217
|
+
For each candidate, return:
|
|
218
|
+
[REVIEWED] | candidate_id | CONFIRMED/DISPROVED/UNVERIFIED/PRE_EXISTING | evidence_type | final_severity | introduced_by_pr | file:line | rationale | falsification_probe | reviewer_id
|
|
219
|
+
|
|
220
|
+
You must check caller context, reachability, schema/middleware/framework mitigations, state-machine constraints, test coverage, PR-introducedness, and severity.
|
|
221
|
+
|
|
222
|
+
IMPORTANT: If a finding claims behavior is "new" or "introduced by the PR", you MUST read the equivalent code on the base branch (git show <base_ref>:<file>) to verify it was not present before. A reviewer claim of "this is new" is invalid without base-branch evidence. Do not compare the new code to an idealized baseline — compare it to what actually existed on the base branch at the time of the PR.
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Key invariants
|
|
226
|
+
|
|
227
|
+
- The parser reads the **full artifact**, not a preview. Truncation in the
|
|
228
|
+
`dispatch_lanes` preview does not affect candidate extraction.
|
|
229
|
+
- The orchestrator never classifies candidates — it only filters, groups, and
|
|
230
|
+
routes them.
|
|
231
|
+
- Each reviewer receives a bounded chunk. A chunk with more than 50 candidates
|
|
232
|
+
is split before dispatch.
|
|
233
|
+
- The `invocation_envelope` in the parser response provides audit provenance
|
|
234
|
+
for every extracted candidate.
|
|
235
|
+
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Reviewer Prompt Template
|
|
2
|
+
|
|
3
|
+
Use this template when dispatching reviewer subagents:
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
You are the independent reviewer. Validate only the candidates assigned below.
|
|
7
|
+
Do not search for new issues except where needed to validate reachability or mitigation.
|
|
8
|
+
Do not trust explorer severity.
|
|
9
|
+
|
|
10
|
+
Context pack summary:
|
|
11
|
+
- scope: ...
|
|
12
|
+
- obligations: ...
|
|
13
|
+
- impact cone: ...
|
|
14
|
+
- deterministic signals: ...
|
|
15
|
+
- relevant Swarm artifacts / knowledge: ...
|
|
16
|
+
- base_ref: <commit SHA of base branch>
|
|
17
|
+
- head_ref: <commit SHA of PR head branch>
|
|
18
|
+
|
|
19
|
+
Candidates:
|
|
20
|
+
- ...
|
|
21
|
+
|
|
22
|
+
For each candidate, return:
|
|
23
|
+
[REVIEWED] | candidate_id | CONFIRMED/DISPROVED/UNVERIFIED/PRE_EXISTING | evidence_type | final_severity | introduced_by_pr | file:line | rationale | falsification_probe | reviewer_id
|
|
24
|
+
|
|
25
|
+
You must check caller context, reachability, schema/middleware/framework mitigations, state-machine constraints, test coverage, PR-introducedness, and severity.
|
|
26
|
+
|
|
27
|
+
IMPORTANT: If a finding claims behavior is "new" or "introduced by the PR", you MUST read the equivalent code on the base branch (git show <base_ref>:<file>) to verify it was not present before. A reviewer claim of "this is new" is invalid without base-branch evidence. Do not compare the new code to an idealized baseline — compare it to what actually existed on the base branch at the time of the PR.
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
# Critic Prompt Template
|
|
33
|
+
|
|
34
|
+
Use this template when dispatching critic subagents:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
You are the adversarial critic. Challenge only reviewer-confirmed findings assigned below.
|
|
38
|
+
Your goal is to reduce false positives, severity inflation, and non-actionable reports.
|
|
39
|
+
|
|
40
|
+
For each finding, challenge:
|
|
41
|
+
- whether evidence proves the claim,
|
|
42
|
+
- whether the path is reachable,
|
|
43
|
+
- whether mitigations apply,
|
|
44
|
+
- whether severity is inflated,
|
|
45
|
+
- whether it is PR-introduced,
|
|
46
|
+
- whether suggested fixes are safe/actionable,
|
|
47
|
+
- whether related files were missed,
|
|
48
|
+
- whether multiple findings should be grouped.
|
|
49
|
+
|
|
50
|
+
Return:
|
|
51
|
+
[CRITIC] | finding_id | UPHELD/DOWNGRADED/DISPROVED/NEEDS_MORE_EVIDENCE | final_severity | reason | required_report_change
|
|
52
|
+
|
|
53
|
+
REQUIRED FINAL LINE — your final line MUST be exactly the row above (no variations, no labeled fields, no placeholders):
|
|
54
|
+
[CRITIC] | finding_id | UPHELD/DOWNGRADED/DISPROVED/NEEDS_MORE_EVIDENCE | final_severity | reason | required_report_change
|
|
55
|
+
|
|
56
|
+
A response without this exact row is treated as a planning preamble and re-dispatched. Do not output only a planning or investigation message.
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
# Explorer Prompt Template
|
|
62
|
+
|
|
63
|
+
Use this template when dispatching base explorer or micro-lane agents:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
You are an explorer. Optimize for recall, not final judgment.
|
|
67
|
+
Return candidates only. Do not use CONFIRMED, DISPROVED, or PRE_EXISTING.
|
|
68
|
+
|
|
69
|
+
Lane:
|
|
70
|
+
Scope:
|
|
71
|
+
base_ref:
|
|
72
|
+
head_ref:
|
|
73
|
+
Obligations:
|
|
74
|
+
Changed files/hunks:
|
|
75
|
+
Impact cone:
|
|
76
|
+
Relevant deterministic signals:
|
|
77
|
+
Relevant Swarm artifacts / knowledge:
|
|
78
|
+
Checklist:
|
|
79
|
+
|
|
80
|
+
You must inspect or mark unavailable:
|
|
81
|
+
1. changed hunk,
|
|
82
|
+
2. caller/consumer,
|
|
83
|
+
3. callee/dependency,
|
|
84
|
+
4. sibling implementation or prior pattern,
|
|
85
|
+
5. nearest test or missing-test location,
|
|
86
|
+
6. deterministic signals,
|
|
87
|
+
7. Swarm artifacts/knowledge,
|
|
88
|
+
8. the exact `base_sha...pr_head_sha` merge-base range and both endpoint revisions.
|
|
89
|
+
|
|
90
|
+
Return:
|
|
91
|
+
[CANDIDATE] | candidate_id | lane | severity | category | file:line | claim | evidence_summary | impact_context | confidence
|
|
92
|
+
Emit the marker-bearing header once, then unprefixed data rows.
|
|
93
|
+
For a clean micro-lane, emit `[CLEAN] | micro_lane | coverage_scope | evidence`.
|
|
94
|
+
For a clean base lane, emit `[CLEAN] | workflow_lane | coverage_scope | evidence`.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The orchestrator extracts candidates from the full lane artifact via
|
|
98
|
+
`parse_lane_candidates` as the primary mechanism. The `[CANDIDATE]` row
|
|
99
|
+
format above is a fallback convention for environments where the parser is
|
|
100
|
+
unavailable. Explorers should still emit structured records regardless of
|
|
101
|
+
whether the parser is present.
|
|
102
|
+
|
|
103
|
+
Do not let speed degrade validation quality.
|
|
@@ -619,44 +619,6 @@ authority checks:
|
|
|
619
619
|
|
|
620
620
|
For the full splitting protocol (describe-block extraction, shared helper management, pure-function extraction, mock isolation verification, cascading-split detection), read `file:.swarm/bundled-skills/test-file-split/SKILL.md`.
|
|
621
621
|
|
|
622
|
-
### Checking file length
|
|
623
|
-
|
|
624
|
-
```bash
|
|
625
|
-
# Check a single file
|
|
626
|
-
wc -l tests/unit/scripts/my-test.test.ts
|
|
627
|
-
|
|
628
|
-
# Find all test files exceeding 400 lines (early warning threshold)
|
|
629
|
-
find tests/ -name "*.test.ts" -exec wc -l {} \; | sort -rn | awk '$1 > 400'
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
### Splitting pattern
|
|
633
|
-
|
|
634
|
-
When a test file approaches or exceeds 500 lines, split it by extracting cohesive `describe()` blocks into a new file with a descriptive suffix:
|
|
635
|
-
|
|
636
|
-
1. **Identify natural boundaries.** Group `describe()` blocks by functional area (e.g., SHA resolution, validation, merge logic).
|
|
637
|
-
2. **Create the new file** with a descriptive suffix: `<module>-<area>.test.ts` (e.g., `release-notes-fragments-sha.test.ts`, `release-notes-fragments-validation.test.ts`).
|
|
638
|
-
3. **Move shared imports and helpers.** Either:
|
|
639
|
-
- Duplicate shared imports in both files (simple, for small overlap), OR
|
|
640
|
-
- Extract shared test helpers to a utility module (e.g., `tests/helpers/<module>-shared.ts`) and import from both files (preferred for complex shared setup).
|
|
641
|
-
4. **Extract testable pure functions.** If the source module has inline validation logic (e.g., `isValidPrNumber`), extract it as an exported pure function so both test files can target it independently.
|
|
642
|
-
5. **Verify both files are under 500 lines.**
|
|
643
|
-
6. **Run both files independently AND co-run** to verify no mock isolation breakage:
|
|
644
|
-
```bash
|
|
645
|
-
bun --smol test tests/unit/scripts/release-notes-fragments.test.ts --timeout 60000
|
|
646
|
-
bun --smol test tests/unit/scripts/release-notes-fragments-sha.test.ts --timeout 60000
|
|
647
|
-
bun --smol test tests/unit/scripts/release-notes-fragments*.test.ts --timeout 60000
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
### When to split vs refactor
|
|
651
|
-
|
|
652
|
-
- **Split** when there are natural `describe()` boundaries (e.g., one file per functional area).
|
|
653
|
-
- **Refactor** when the file is a single monolithic test with no clear boundaries — consolidate test logic instead.
|
|
654
|
-
- **Warning:** If a previously split file exceeds 500 lines again, the test suite is structurally too large. Reorganize by module rather than continuing to split.
|
|
655
|
-
|
|
656
|
-
### Reference
|
|
657
|
-
|
|
658
|
-
See PR #1762 for a real-world example: `release-notes-fragments.test.ts` was split into `release-notes-fragments.test.ts` (379 lines) + `release-notes-fragments-sha.test.ts` (261 lines).
|
|
659
|
-
|
|
660
622
|
## Cross-Entry Invariants (config maps)
|
|
661
623
|
|
|
662
624
|
When you modify any entry of a "map of agents/tools/roles" in `src/config/constants.ts` (`AGENT_TOOL_MAP`, `DEFAULT_MODELS`, `QA_AGENTS`, `PIPELINE_AGENTS`, etc.) or tool-name registration in `src/tools/tool-names.ts`, there are tests that assert **parity across sibling entries**, not just shape of one entry.
|
|
@@ -847,50 +809,7 @@ try {
|
|
|
847
809
|
|
|
848
810
|
## Running Tests
|
|
849
811
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
```bash
|
|
853
|
-
# Single file
|
|
854
|
-
bun test src/hooks/scope-guard.test.ts
|
|
855
|
-
|
|
856
|
-
# Batch directory (safe for dirs without mock conflicts)
|
|
857
|
-
bun --smol test tests/unit/hooks --timeout 30000
|
|
858
|
-
|
|
859
|
-
# Per-file loop (required for tools/services/agents — prevents mock poisoning)
|
|
860
|
-
for f in tests/unit/tools/*.test.ts; do bun --smol test "$f" --timeout 30000; done
|
|
861
|
-
|
|
862
|
-
# CI-equivalent run for batch steps (step 2: cli; step 3: commands + config)
|
|
863
|
-
bun --smol test tests/unit/cli --timeout 120000
|
|
864
|
-
bun --smol test tests/unit/commands tests/unit/config --timeout 120000
|
|
865
|
-
```
|
|
866
|
-
|
|
867
|
-
### PowerShell (Windows)
|
|
868
|
-
|
|
869
|
-
```powershell
|
|
870
|
-
# Single file
|
|
871
|
-
bun test src/hooks/scope-guard.test.ts
|
|
872
|
-
|
|
873
|
-
# Batch directory (safe for dirs without mock conflicts)
|
|
874
|
-
bun --smol test tests/unit/hooks --timeout 30000
|
|
875
|
-
|
|
876
|
-
# Per-file loop (required for tools/services/agents — prevents mock poisoning)
|
|
877
|
-
Get-ChildItem tests/unit/tools/*.test.ts | ForEach-Object { bun --smol test $_.FullName --timeout 30000 }
|
|
878
|
-
|
|
879
|
-
# CI-equivalent run for batch steps (step 2: cli; step 3: commands + config)
|
|
880
|
-
bun --smol test tests/unit/cli --timeout 120000
|
|
881
|
-
bun --smol test tests/unit/commands tests/unit/config --timeout 120000
|
|
882
|
-
|
|
883
|
-
# Capture output to file (avoids truncation when output is large)
|
|
884
|
-
bun --smol test tests/unit/agents --timeout 60000 | Out-File "$env:TEMP\test_out.txt"; Get-Content "$env:TEMP\test_out.txt" | Select-Object -Last 50
|
|
885
|
-
```
|
|
886
|
-
|
|
887
|
-
**Note:** `for f in ...; do` bash syntax is invalid in PowerShell. Use `Get-ChildItem | ForEach-Object` instead. `Select-String -Last N` is also invalid — use `Select-Object -Last N`.
|
|
888
|
-
|
|
889
|
-
**Warning:** Running `bun --smol test tests/unit/tools` as a single batch will cause mock poisoning failures. Always use the per-file loop for the per-file-isolation steps (1a, 1b, 4-6: tools, services, agents, etc.).
|
|
890
|
-
|
|
891
|
-
The `--smol` flag reduces Bun's memory footprint. Use it when running large directories (50+ files).
|
|
892
|
-
|
|
893
|
-
The `--timeout 120000` flag sets per-test timeout to 120 seconds. Individual tests should complete in under 5 seconds. If a test needs more than 10 seconds, it's doing too much — split it or mock the slow dependency.
|
|
812
|
+
For the full test execution commands (bash and PowerShell per-file isolation loops, CI integration), read `file:.swarm/bundled-skills/running-tests/SKILL.md`. The key principle: always run one test file per process (`bun --smol test <file> --timeout 30000`) to prevent `mock.module` cross-contamination.
|
|
894
813
|
|
|
895
814
|
## Before Submitting
|
|
896
815
|
|
|
@@ -905,44 +824,6 @@ The `--timeout 120000` flag sets per-test timeout to 120 seconds. Individual tes
|
|
|
905
824
|
|
|
906
825
|
Pre-existing and flaky failures are tracked in the per-platform quarantine ledgers (`scripts/ci/quarantined-tests.txt`, `quarantined-tests-macos.txt`, `quarantined-tests-windows.txt`), not in this skill. To confirm a failure is pre-existing, reproduce it in a clean worktree on `origin/main` (see the worktree verify protocol in `running-tests`).
|
|
907
826
|
|
|
908
|
-
##
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
- `tests/unit/commands/` — mocks tools, hooks, services, state
|
|
913
|
-
- `tests/unit/hooks/` — mocks knowledge-store, knowledge-validator, knowledge-reader, telemetry, utils
|
|
914
|
-
- `tests/unit/tools/` — mocks Node built-ins (fs, child_process), sast-baseline, build/discovery
|
|
915
|
-
- `tests/unit/services/` — mocks path-security
|
|
916
|
-
- `tests/unit/config/` — mocks node:fs/promises
|
|
917
|
-
- `tests/unit/background/` — mocks utils, event-bus, evidence-summary-service
|
|
918
|
-
- `tests/unit/council/` — mocks node:fs
|
|
919
|
-
- `tests/unit/plan/` — mocks spec-hash
|
|
920
|
-
- `tests/unit/mutation/` — mocks node:child_process
|
|
921
|
-
- `tests/unit/git/` — mocks node:child_process
|
|
922
|
-
- `tests/integration/` — mocks co-change-analyzer, knowledge-store
|
|
923
|
-
- `src/__tests__/` — mocks plan/manager, preflight-service, telemetry
|
|
924
|
-
- `src/hooks/` — mocks logger, event-bus
|
|
925
|
-
- `src/tools/__tests__/` — mocks test-impact/analyzer, build/discovery, path-security
|
|
926
|
-
- `src/mutation/__tests__/` — mocks state
|
|
927
|
-
- `src/agents/` — mocks node:fs/promises
|
|
928
|
-
- `src/background/` — mocks vulnerability trigger
|
|
929
|
-
|
|
930
|
-
## Dead-code _internals Seams
|
|
931
|
-
|
|
932
|
-
The following source modules export `_internals` but have no test consumers (as of this writing). They are harmless but may be removed in future cleanup:
|
|
933
|
-
|
|
934
|
-
- `src/tools/secretscan.ts`
|
|
935
|
-
- `src/tools/knowledge-recall.ts`
|
|
936
|
-
- `src/tools/lint.ts`
|
|
937
|
-
- `src/tools/sast-scan.ts`
|
|
938
|
-
- `src/tools/sast-baseline.ts`
|
|
939
|
-
- `src/mutation/gate.ts`
|
|
940
|
-
- `src/mutation/equivalence.ts`
|
|
941
|
-
- `src/mutation/engine.ts`
|
|
942
|
-
- `src/db/qa-gate-profile.ts`
|
|
943
|
-
- `src/config/schema.ts`
|
|
944
|
-
- `src/config/index.ts`
|
|
945
|
-
- `src/commands/registry.ts`
|
|
946
|
-
- `src/background/manager.ts`
|
|
947
|
-
- `src/background/event-bus.ts`
|
|
948
|
-
- `src/agents/critic.ts`
|
|
827
|
+
## Mock and Seam Inventories
|
|
828
|
+
|
|
829
|
+
For the current cross-module `mock.module` location inventory and dead-code `_internals` seam inventory, read `references/mock-and-seam-inventory.md`.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Mock and Seam Inventory
|
|
2
|
+
|
|
3
|
+
## Known Cross-module mock.module Locations
|
|
4
|
+
|
|
5
|
+
The following directories contain test files that use cross-module `mock.module` (permitted under two-tier convention):
|
|
6
|
+
|
|
7
|
+
- `tests/unit/commands/` — mocks tools, hooks, services, state
|
|
8
|
+
- `tests/unit/hooks/` — mocks knowledge-store, knowledge-validator, knowledge-reader, telemetry, utils
|
|
9
|
+
- `tests/unit/tools/` — mocks Node built-ins (fs, child_process), sast-baseline, build/discovery
|
|
10
|
+
- `tests/unit/services/` — mocks path-security
|
|
11
|
+
- `tests/unit/config/` — mocks node:fs/promises
|
|
12
|
+
- `tests/unit/background/` — mocks utils, event-bus, evidence-summary-service
|
|
13
|
+
- `tests/unit/council/` — mocks node:fs
|
|
14
|
+
- `tests/unit/plan/` — mocks spec-hash
|
|
15
|
+
- `tests/unit/mutation/` — mocks node:child_process
|
|
16
|
+
- `tests/unit/git/` — mocks node:child_process
|
|
17
|
+
- `tests/integration/` — mocks co-change-analyzer, knowledge-store
|
|
18
|
+
- `src/__tests__/` — mocks plan/manager, preflight-service, telemetry
|
|
19
|
+
- `src/hooks/` — mocks logger, event-bus
|
|
20
|
+
- `src/tools/__tests__/` — mocks test-impact/analyzer, build/discovery, path-security
|
|
21
|
+
- `src/mutation/__tests__/` — mocks state
|
|
22
|
+
- `src/agents/` — mocks node:fs/promises
|
|
23
|
+
- `src/background/` — mocks vulnerability trigger
|
|
24
|
+
|
|
25
|
+
## Dead-code _internals Seams
|
|
26
|
+
|
|
27
|
+
The following source modules export `_internals` but have no test consumers (as of this writing). They are harmless but may be removed in future cleanup:
|
|
28
|
+
|
|
29
|
+
- `src/tools/secretscan.ts`
|
|
30
|
+
- `src/tools/knowledge-recall.ts`
|
|
31
|
+
- `src/tools/lint.ts`
|
|
32
|
+
- `src/tools/sast-scan.ts`
|
|
33
|
+
- `src/tools/sast-baseline.ts`
|
|
34
|
+
- `src/mutation/gate.ts`
|
|
35
|
+
- `src/mutation/equivalence.ts`
|
|
36
|
+
- `src/mutation/engine.ts`
|
|
37
|
+
- `src/db/qa-gate-profile.ts`
|
|
38
|
+
- `src/config/schema.ts`
|
|
39
|
+
- `src/config/index.ts`
|
|
40
|
+
- `src/commands/registry.ts`
|
|
41
|
+
- `src/background/manager.ts`
|
|
42
|
+
- `src/background/event-bus.ts`
|
|
43
|
+
- `src/agents/critic.ts`
|
package/README.md
CHANGED
|
@@ -810,7 +810,9 @@ Every candidate passes a 3-gate pipeline before entering quarantine:
|
|
|
810
810
|
| generate_mutants | Architect-only: generates LLM-based mutation patches (5–10 per function across 6 types: off-by-one, null substitution, operator swap, guard removal, branch swap, side-effect deletion) for direct consumption by the mutation_test tool; returns SKIP verdict on LLM failure rather than throwing |
|
|
811
811
|
| write_mutation_evidence | Architect-only: writes mutation gate results atomically to `.swarm/evidence/{phase}/mutation-gate.json`; accepts verdict (PASS/WARN/FAIL/SKIP), kill rate metrics, and optional survived mutant details; normalizes uppercase-to-lowercase before persisting |
|
|
812
812
|
| parse_lane_candidates | Architect-only: parses `[CANDIDATE]` rows and micro-lane `[CLEAN]` attestations from a lane `output_ref`; supports asserted batch families, preserves dispatch provenance, and persists sidecar JSONL records |
|
|
813
|
-
| write_pr_review_trigger_eval | Architect-only: validates the exact PR-review
|
|
813
|
+
| write_pr_review_trigger_eval | Architect-only: validates the exact mandatory PR-review micro-lane ID set, requires completed provenance for all 11 repository-agnostic lanes, verifies the claimed merge base against an exact live base ref, rejects every `NO-MATCH` waiver, and atomically persists `.swarm/pr-review/<run_id>/trigger-eval.json` |
|
|
814
|
+
| complete_pr_workflow | Architect-only: validates terminal PR-review or PR-feedback coverage; feedback uses a two-call arm/publish protocol and clears only after the approved content is observed on both the bound remote-tracking ref and the actual remote branch |
|
|
815
|
+
| run_pr_feedback_stage_a | Architect-only: executes targeted reproduction/regression and exact `git diff --check` plus every mechanically applicable workspace/category/source build, typecheck, and lint obligation, then persists content-bound Stage A receipts before ordered feedback review gates |
|
|
814
816
|
| git_blame | Per-line git blame metadata (sha, author, date, summary) via `git blame --porcelain`; supports optional line range filtering |
|
|
815
817
|
| diff | Structured git diff with contract change detection; supports `summaryOnly` mode returning file list with additions/deletions counts |
|
|
816
818
|
| suggest_patch | Reviewer-safe structured patch suggestion; supports `format` parameter ('json' or 'unified') where unified outputs valid unified diff with `diff --git` headers, hunks, and context |
|
|
@@ -11,6 +11,11 @@ declare const LaneOutputArtifactSchema: z.ZodObject<{
|
|
|
11
11
|
sessionId: z.ZodOptional<z.ZodString>;
|
|
12
12
|
parentSessionId: z.ZodOptional<z.ZodString>;
|
|
13
13
|
mode: z.ZodOptional<z.ZodString>;
|
|
14
|
+
workflowLane: z.ZodOptional<z.ZodString>;
|
|
15
|
+
prHeadSha: z.ZodOptional<z.ZodString>;
|
|
16
|
+
gitHead: z.ZodOptional<z.ZodString>;
|
|
17
|
+
revisionDigest: z.ZodOptional<z.ZodString>;
|
|
18
|
+
scope: z.ZodOptional<z.ZodString>;
|
|
14
19
|
source: z.ZodEnum<{
|
|
15
20
|
dispatch_lanes: "dispatch_lanes";
|
|
16
21
|
collect_lane_results: "collect_lane_results";
|
|
@@ -34,6 +39,11 @@ export interface StoreLaneOutputInput {
|
|
|
34
39
|
sessionId?: string;
|
|
35
40
|
parentSessionId?: string;
|
|
36
41
|
mode?: string;
|
|
42
|
+
workflowLane?: string;
|
|
43
|
+
prHeadSha?: string;
|
|
44
|
+
gitHead?: string;
|
|
45
|
+
revisionDigest?: string;
|
|
46
|
+
scope?: string;
|
|
37
47
|
source: LaneOutputSource;
|
|
38
48
|
text: string;
|
|
39
49
|
messageCount?: number;
|
|
@@ -52,6 +52,8 @@ export interface BackgroundDelegationRecord {
|
|
|
52
52
|
laneId?: string;
|
|
53
53
|
/** Advisory workflow/mode that launched the lane. */
|
|
54
54
|
mode?: string;
|
|
55
|
+
/** Mechanical PR workflow obligation identifier, distinct from retry-safe laneId. */
|
|
56
|
+
workflowLane?: string;
|
|
55
57
|
/** Canonical hash of prompt/provenance inputs captured at dispatch time. */
|
|
56
58
|
promptHash?: string;
|
|
57
59
|
/** Project/root provenance captured at dispatch time. */
|
|
@@ -119,6 +121,7 @@ export interface RecordPendingInput {
|
|
|
119
121
|
batchId?: string;
|
|
120
122
|
laneId?: string;
|
|
121
123
|
mode?: string;
|
|
124
|
+
workflowLane?: string;
|
|
122
125
|
promptHash?: string;
|
|
123
126
|
workspace?: BackgroundWorkspaceSnapshot;
|
|
124
127
|
taskChangeContext?: BackgroundTaskChangeContext;
|
|
@@ -11,8 +11,65 @@ interface CaptureWorkspaceSnapshotOptions {
|
|
|
11
11
|
*/
|
|
12
12
|
resolveCurrentPrHeadSha?: boolean;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Read one bounded repository file from an immutable commit without consulting
|
|
16
|
+
* the mutable checkout. Callers compare this text with the checkout copy before
|
|
17
|
+
* treating a PR-provided contract as authority.
|
|
18
|
+
*/
|
|
19
|
+
export declare function readGitTextAtRevision(directory: string, revision: string, relativePath: string): string | null;
|
|
20
|
+
/** Resolve the exact checked-out commit through the bounded Git snapshot path. */
|
|
21
|
+
export declare function resolveCurrentGitHead(directory: string): string | null;
|
|
22
|
+
/** Resolve one exact PR merge base without shell interpolation or unbounded I/O. */
|
|
23
|
+
export declare function resolveExactMergeBase(directory: string, baseRef: string, prHeadSha: string): string | null;
|
|
24
|
+
/** Resolve the current branch's exact remote-tracking publication target. */
|
|
25
|
+
export declare function resolveCurrentUpstreamRemoteRef(directory: string): string | null;
|
|
26
|
+
export interface PrUpstreamPushTarget {
|
|
27
|
+
remoteName: string;
|
|
28
|
+
remoteBranchRef: string;
|
|
29
|
+
remoteTrackingRef: string;
|
|
30
|
+
}
|
|
31
|
+
/** Resolve a branch's upstream without guessing where a remote name ends. */
|
|
32
|
+
export declare function resolveCurrentUpstreamPushTarget(directory: string): PrUpstreamPushTarget | null;
|
|
33
|
+
/** Query the actual remote ref; local tracking refs are not publication proof. */
|
|
34
|
+
export declare function resolveExactRemoteBranchHead(directory: string, remoteName: string, remoteBranchRef: string): string | null;
|
|
35
|
+
/** Bind Stage-A execution to Git refs, config, HEAD, and index metadata. */
|
|
36
|
+
export declare function resolveGitControlStateDigest(directory: string): string | null;
|
|
37
|
+
/** Require all independently reviewed content to be captured by the commit. */
|
|
38
|
+
export declare function resolveIsWorkingTreeClean(directory: string): boolean | null;
|
|
39
|
+
/** Count commits on the ancestry path from the immutable intake head to HEAD. */
|
|
40
|
+
export declare function resolveCommitCountSince(directory: string, baseHeadSha: string, currentHeadSha: string): number | null;
|
|
41
|
+
/** Prove the publication commit is a non-merge direct child of intake HEAD. */
|
|
42
|
+
export declare function resolveIsExactSingleChildCommit(directory: string, baseHeadSha: string, currentHeadSha: string): boolean | null;
|
|
43
|
+
/**
|
|
44
|
+
* Return remote-tracking refs whose tip equals the exact checked-out commit.
|
|
45
|
+
* Publication closeout uses this bounded local observation after a successful
|
|
46
|
+
* push; an empty list is not proof that the approved revision was published.
|
|
47
|
+
*/
|
|
48
|
+
export declare function resolveRemoteRefsContainingHead(directory: string, headSha: string): string[] | null;
|
|
49
|
+
/**
|
|
50
|
+
* Bind a mutable working tree to its actual content, not merely porcelain status.
|
|
51
|
+
* This lets PR-feedback approvals fail closed when a same-path edit occurs after a
|
|
52
|
+
* gate. Paths come from Git, are containment-checked, and are hashed without
|
|
53
|
+
* following symlinks outside the project.
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolvePrWorkflowRevisionDigest(directory: string, baseHeadSha: string): string | null;
|
|
56
|
+
/**
|
|
57
|
+
* Asynchronously bind a mutable working tree to its actual content. File
|
|
58
|
+
* reads are chunked with bounded cooperative yields so a large, permitted
|
|
59
|
+
* revision cannot stall the synchronous plugin gate path.
|
|
60
|
+
*/
|
|
61
|
+
export declare function resolvePrWorkflowRevisionDigestAsync(directory: string, baseHeadSha: string): Promise<string | null>;
|
|
14
62
|
/** Parse `git status --porcelain=v1 -z`, including both sides of renames. */
|
|
15
63
|
export declare function parsePorcelainPaths(output: string): string[] | null;
|
|
64
|
+
interface PorcelainV2Snapshot {
|
|
65
|
+
gitHead: string | null;
|
|
66
|
+
changedFiles: string[];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Parse the one-command `git status --porcelain=v2 --branch -z` snapshot used
|
|
70
|
+
* by background evidence capture. A malformed or unknown record fails closed.
|
|
71
|
+
*/
|
|
72
|
+
declare function parsePorcelainV2Snapshot(output: string): PorcelainV2Snapshot | null;
|
|
16
73
|
export declare function captureWorkspaceSnapshot(directory: string, optionsOrScope?: string | null | CaptureWorkspaceSnapshotOptions, prHeadShaArg?: string | null): BackgroundWorkspaceSnapshot;
|
|
17
74
|
/**
|
|
18
75
|
* Conservatively derive final paths changed since a pre-task snapshot.
|
|
@@ -34,5 +91,7 @@ export declare function compareWorkspaceSnapshots(expected: BackgroundWorkspaceS
|
|
|
34
91
|
export declare function digest(text: string): string;
|
|
35
92
|
export declare const _internals: {
|
|
36
93
|
spawnSync: SpawnSync;
|
|
94
|
+
yieldControl: () => Promise<void>;
|
|
95
|
+
parsePorcelainV2Snapshot: typeof parsePorcelainV2Snapshot;
|
|
37
96
|
};
|
|
38
97
|
export {};
|