opencode-swarm 7.141.2 → 7.142.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/dist/cli/{config-doctor-weqs97sa.js → config-doctor-2a3qmp5p.js} +2 -2
- package/dist/cli/{core-zg7fqfsm.js → core-h9z49ant.js} +1 -1
- package/dist/cli/{curation-policy-j1fbc3ry.js → curation-policy-pkb2eeb1.js} +6 -6
- package/dist/cli/curator-drift-49p3jnte.js +1 -1
- package/dist/cli/{curator-llm-factory-8p86mgye.js → curator-llm-factory-9fr243kj.js} +29 -29
- package/dist/cli/{curator-v1tnrt93.js → curator-mtz194wy.js} +29 -29
- package/dist/cli/{evidence-summary-service-a4w0yc8h.js → evidence-summary-service-fgckng0a.js} +13 -11
- package/dist/cli/{gate-evidence-rt9034ft.js → gate-evidence-ppna7em4.js} +9 -5
- package/dist/cli/{guardrail-explain-8yrznk98.js → guardrail-explain-ejdvvnjz.js} +30 -30
- package/dist/cli/{guardrail-log-7hj4x9yt.js → guardrail-log-adjs25ye.js} +4 -4
- package/dist/cli/{hive-promoter-6zcnyh1j.js → hive-promoter-jejme31e.js} +29 -29
- package/dist/cli/{index-vts5e84g.js → index-0r4qs243.js} +31 -31
- package/dist/cli/index-2mb5y2w1.js +1372 -0
- package/dist/cli/{index-nse60anv.js → index-7c4bxgdh.js} +1 -1
- package/dist/cli/{index-qskz8j2z.js → index-82m5kwtd.js} +1 -1
- package/dist/cli/{index-6bp1jecx.js → index-9kf3mj08.js} +4 -4
- package/dist/cli/{index-szrcxvr7.js → index-9wmx9ca8.js} +6 -6
- package/dist/cli/{index-76651erq.js → index-ajfa2wmj.js} +9 -9
- package/dist/cli/{index-jpt07f2k.js → index-bb4pcn58.js} +2 -2
- package/dist/cli/{index-qa50yyeh.js → index-bkkxxwcd.js} +1 -1
- package/dist/cli/{index-c2hczjhp.js → index-erfnw81g.js} +3 -3
- package/dist/cli/{index-why8n7cr.js → index-gtkk5rx7.js} +137 -36
- package/dist/cli/{index-73sxchez.js → index-h7ye3bzp.js} +4127 -2558
- package/dist/cli/{index-hwxcdrv9.js → index-j02ez59y.js} +9 -9
- package/dist/cli/{index-h3vk67wp.js → index-k1xsjzm3.js} +3 -3
- package/dist/cli/{index-zbj3yrrd.js → index-k31en0ja.js} +3 -3
- package/dist/cli/{index-q4vaar2b.js → index-k92cagmt.js} +2 -2
- package/dist/cli/{index-p5y72gtj.js → index-kbshtwha.js} +3 -3
- package/dist/cli/{index-r6pdts5c.js → index-ktazgjqw.js} +2 -2
- package/dist/cli/{index-mxtt4x8r.js → index-myav90y6.js} +212 -10
- package/dist/cli/{index-kkn2jxda.js → index-rthq1a6w.js} +1 -1
- package/dist/cli/{index-9d4gck4e.js → index-s2rcz51a.js} +59 -35
- package/dist/cli/{index-y6k6x197.js → index-sdqtecsd.js} +1 -1
- package/dist/cli/{index-v250345n.js → index-tq5s07ta.js} +1 -1
- package/dist/cli/{index-zf5nkkdd.js → index-vefjxxmb.js} +1 -1
- package/dist/cli/{index-bxjhn3t3.js → index-vy11zjvh.js} +2 -2
- package/dist/cli/{index-kq5p3nm3.js → index-w7x7qxz2.js} +1 -1
- package/dist/cli/{index-mqqmant3.js → index-we279je2.js} +1 -1
- package/dist/cli/{index-xx0q37xb.js → index-xah70t2t.js} +1 -1
- package/dist/cli/{index-aqzvjhb7.js → index-xfhe29z3.js} +5 -5
- package/dist/cli/{index-f1hsrgw1.js → index-y9h2vqf6.js} +1 -1
- package/dist/cli/index.js +42 -29
- package/dist/cli/{knowledge-escalator-xjkbek46.js → knowledge-escalator-0b80ryka.js} +12 -12
- package/dist/cli/{knowledge-events-hsdx5prn.js → knowledge-events-8x2wt562.js} +10 -10
- package/dist/cli/{knowledge-link-x86ebng8.js → knowledge-link-fn5j3r4q.js} +5 -5
- package/dist/cli/{knowledge-store-vt059r81.js → knowledge-store-d0xj6wht.js} +6 -6
- package/dist/cli/{knowledge-validator-jr5694jb.js → knowledge-validator-ewfj679a.js} +8 -8
- package/dist/cli/{pending-delegations-7xsagjy5.js → pending-delegations-0hb97ps1.js} +4 -4
- package/dist/cli/{pr-subscriptions-r6cdsa3t.js → pr-subscriptions-b63t252j.js} +4 -4
- package/dist/cli/{runner-nm3baddf.js → runner-hrg7h2h4.js} +6 -6
- package/dist/cli/{scan-cursor-6nrkcfbr.js → scan-cursor-hfyz7zpw.js} +7 -7
- package/dist/cli/{schema-f6pt0zjy.js → schema-ney3c685.js} +1 -1
- package/dist/cli/{scope-persistence-jc0mtp7g.js → scope-persistence-dbfgs7gh.js} +6 -6
- package/dist/cli/{skill-generator-4vp33gjb.js → skill-generator-p651jex5.js} +14 -14
- package/dist/cli/{telemetry-zex3zv3v.js → telemetry-xyfb5vm8.js} +1 -1
- package/dist/cli/{worktree-collision-ownership-n41qw3n8.js → worktree-collision-ownership-ymdxetnn.js} +4 -4
- package/dist/cli/{worktree-isolation-a3hkz665.js → worktree-isolation-513vx61s.js} +29 -29
- package/dist/commands/close.d.ts +20 -2
- package/dist/commands/hive-quarantine.d.ts +23 -0
- package/dist/commands/registry.d.ts +9 -0
- package/dist/gate-evidence.d.ts +24 -1
- package/dist/hooks/hive-transaction.d.ts +41 -0
- package/dist/index.js +491 -478
- package/dist/knowledge/hive-quarantine.d.ts +156 -0
- package/dist/observability/catalog.d.ts +2 -2
- package/dist/plan/ledger.d.ts +31 -1
- package/dist/plan/manager.d.ts +1 -0
- package/dist/state.d.ts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/workflow/close-terminal.d.ts +22 -0
- package/dist/workflow/coder-settlement.d.ts +0 -23
- package/dist/workflow/task-repair.d.ts +1 -0
- package/dist/workflow/task-terminal.d.ts +18 -23
- package/dist/workflow/workflow-wal-file.d.ts +20 -0
- package/dist/workflow/workflow-wal-schema.d.ts +67 -0
- package/dist/worktree/merge.d.ts +17 -0
- package/package.json +1 -1
- package/dist/cli/index-3d13jkzq.js +0 -623
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-only exact-ID quarantine for the machine-global hive knowledge store (issue #2033).
|
|
3
|
+
*
|
|
4
|
+
* Problem: the hive store (`shared-learnings.jsonl`, resolved by
|
|
5
|
+
* `src/knowledge/hive-paths.ts`) has been polluted by leaked test fixtures, and no safe
|
|
6
|
+
* remediation existed: `quarantineEntry` is swarm-tier only, `knowledge_archive` refuses
|
|
7
|
+
* hive-tier quarantine, and bulk text scrubbing would destroy legitimate lessons (a real
|
|
8
|
+
* store may legitimately contain test-like text). Parent #1823: never bulk delete.
|
|
9
|
+
*
|
|
10
|
+
* This module implements the adjudicated exact-ID flow:
|
|
11
|
+
* preview — read-only snapshot of exact candidate IDs, per-entry hashes/provenance, a
|
|
12
|
+
* store fingerprint, and a confirmation token bound to preview + store +
|
|
13
|
+
* plugin version (TTL-bounded) AND HMAC-signed with a per-install secret
|
|
14
|
+
* (not derivable from store contents — PR #2200 review CC-1).
|
|
15
|
+
* commit — a validated backup + manifest written and hash-verified BEFORE any
|
|
16
|
+
* mutation (outside the hive lock, keeping the locked closure fast per
|
|
17
|
+
* hive-transaction's contract), then ONE `transactHiveStore` transaction
|
|
18
|
+
* that re-verifies the live file hash against the backup under lock (any
|
|
19
|
+
* drift — including duplicate-id ambiguity — aborts with no mutation;
|
|
20
|
+
* clean aborts clean up the orphaned backup dir), quarantines EXACTLY the
|
|
21
|
+
* selected IDs with audit + sidecar records staged under the lock, and
|
|
22
|
+
* verifies counts afterwards with an HONEST auto-restore report (a failed
|
|
23
|
+
* restore is never claimed as success).
|
|
24
|
+
* rollback — idempotent restore of the EXACT original line bytes from the manifest's
|
|
25
|
+
* backup, aborting on collision (an id re-promoted with different content).
|
|
26
|
+
* Backup lookup resolves symlinks/reparse points on BOTH sides — a lexical
|
|
27
|
+
* prefix compare alone is dead code against a planted link (review CC-4).
|
|
28
|
+
*
|
|
29
|
+
* Selection is EXACT-ID only: no text, substring, "test-looking phrase", cohort, age, or
|
|
30
|
+
* blacklist matching exists anywhere in this module, and there is no bulk operation.
|
|
31
|
+
*
|
|
32
|
+
* Byte-fidelity note: restored ids are written through the transaction's
|
|
33
|
+
* `rawLineOverrides` channel as the EXACT original line bytes, and every restore is
|
|
34
|
+
* verified against the manifest's `raw_line_sha256` (hex sha256 of the line bytes
|
|
35
|
+
* INCLUDING the trailing newline) before success is reported. Two standing-transaction
|
|
36
|
+
* disclosures apply to everything EXCEPT the selected ids: unselected entries may be
|
|
37
|
+
* re-serialized by the normalize-on-read pipeline, and unparseable (corrupt) lines are
|
|
38
|
+
* DROPPED by any commit rewrite — they survive only in the hash-verified backup copy,
|
|
39
|
+
* from which they can be recovered manually.
|
|
40
|
+
*
|
|
41
|
+
* The module holds no module-level mutable state (invariant 8) and performs no work on
|
|
42
|
+
* the plugin-init path (invariant 1) — it is loaded only by the human-only
|
|
43
|
+
* `knowledge hive-quarantine` command dispatch.
|
|
44
|
+
*/
|
|
45
|
+
import { chmod, copyFile, mkdir, readdir, readFile, realpath, rm, stat, writeFile } from 'node:fs/promises';
|
|
46
|
+
import { transactHiveStore } from '../hooks/hive-transaction.js';
|
|
47
|
+
import { emit } from '../telemetry.js';
|
|
48
|
+
import { resolveHiveDataDir, resolveHiveKnowledgePath } from './hive-paths.js';
|
|
49
|
+
/** Confirmation token TTL (freshness window). */
|
|
50
|
+
export declare const HIVE_QUARANTINE_TOKEN_TTL_MS: number;
|
|
51
|
+
/** Upper bound of exact IDs per operation (tokens embed per-id hashes). */
|
|
52
|
+
export declare const MAX_IDS_PER_OPERATION = 200;
|
|
53
|
+
/** Quarantine sidecar living beside the store in the hive data dir. */
|
|
54
|
+
export declare const HIVE_QUARANTINE_SIDECAR = "shared-learnings-quarantined.jsonl";
|
|
55
|
+
/** Backup directory root inside the hive data dir. */
|
|
56
|
+
export declare const HIVE_QUARANTINE_BACKUP_DIR = "quarantine-backups";
|
|
57
|
+
export type HiveQuarantineAbortCode = 'invalid_ids' | 'id_not_found' | 'duplicate_id' | 'duplicate_id_in_store' | 'too_many_ids' | 'invalid_token' | 'token_expired' | 'store_drift' | 'id_changed' | 'id_missing' | 'version_changed' | 'backup_failed' | 'backup_corrupt' | 'backup_not_found' | 'rollback_collision' | 'ambiguous_backup' | 'transaction_failed';
|
|
58
|
+
export interface HiveQuarantinePreviewRecord {
|
|
59
|
+
id: string;
|
|
60
|
+
tier: string;
|
|
61
|
+
status: string;
|
|
62
|
+
confidence: number;
|
|
63
|
+
category: string;
|
|
64
|
+
source_project?: string;
|
|
65
|
+
lineage_actor?: string;
|
|
66
|
+
created_at: string;
|
|
67
|
+
updated_at: string;
|
|
68
|
+
content_hash?: string;
|
|
69
|
+
raw_line_sha256: string;
|
|
70
|
+
}
|
|
71
|
+
export interface HiveQuarantinePreview {
|
|
72
|
+
records: HiveQuarantinePreviewRecord[];
|
|
73
|
+
store_entry_count: number;
|
|
74
|
+
store_file_sha256: string;
|
|
75
|
+
plugin_version: string;
|
|
76
|
+
issued_at: string;
|
|
77
|
+
expires_at: string;
|
|
78
|
+
token: string;
|
|
79
|
+
}
|
|
80
|
+
export interface HiveQuarantineCommitResult {
|
|
81
|
+
quarantinedIds: string[];
|
|
82
|
+
storeEntriesBefore: number;
|
|
83
|
+
storeEntriesAfter: number;
|
|
84
|
+
backupDir: string;
|
|
85
|
+
backupBytes: number;
|
|
86
|
+
verified: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface HiveQuarantineRollbackResult {
|
|
89
|
+
restoredIds: string[];
|
|
90
|
+
alreadyPresentIds: string[];
|
|
91
|
+
storeEntriesAfter: number;
|
|
92
|
+
verified: boolean;
|
|
93
|
+
}
|
|
94
|
+
type Abort = {
|
|
95
|
+
ok: false;
|
|
96
|
+
code: HiveQuarantineAbortCode;
|
|
97
|
+
error: string;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Canonical JSON: `JSON.stringify` with recursively sorted object keys. Used for BOTH the
|
|
101
|
+
* preview token construction and the under-lock reconstruction so key order can never
|
|
102
|
+
* produce a false drift signal.
|
|
103
|
+
*/
|
|
104
|
+
export declare function canonicalJson(value: unknown): string;
|
|
105
|
+
declare function readQuarantineSecret(): Promise<string>;
|
|
106
|
+
/**
|
|
107
|
+
* Read-only preview of exact candidate IDs. Errors list missing ids; selection never
|
|
108
|
+
* falls back to prefix or text matching.
|
|
109
|
+
*/
|
|
110
|
+
export declare function previewHiveQuarantine(ids: string[]): Promise<{
|
|
111
|
+
ok: true;
|
|
112
|
+
preview: HiveQuarantinePreview;
|
|
113
|
+
} | Abort>;
|
|
114
|
+
export declare function commitHiveQuarantine(input: {
|
|
115
|
+
token: string;
|
|
116
|
+
reason?: string;
|
|
117
|
+
}): Promise<{
|
|
118
|
+
ok: true;
|
|
119
|
+
result: HiveQuarantineCommitResult;
|
|
120
|
+
} | Abort>;
|
|
121
|
+
/**
|
|
122
|
+
* Idempotent rollback: restores the EXACT original line bytes for the manifest's ids.
|
|
123
|
+
* Ids already present with identical bytes are skipped (safe replay); an id present with
|
|
124
|
+
* DIFFERENT bytes aborts the whole operation with no mutation (collision).
|
|
125
|
+
*/
|
|
126
|
+
export declare function rollbackHiveQuarantine(input: {
|
|
127
|
+
ref: string;
|
|
128
|
+
}): Promise<{
|
|
129
|
+
ok: true;
|
|
130
|
+
result: HiveQuarantineRollbackResult;
|
|
131
|
+
} | Abort>;
|
|
132
|
+
/** Read-only listing of quarantine backups (for the `status` subcommand). */
|
|
133
|
+
export declare function listHiveQuarantineBackups(): Promise<{
|
|
134
|
+
token12: string;
|
|
135
|
+
committed_at: string;
|
|
136
|
+
idCount: number;
|
|
137
|
+
reason: string;
|
|
138
|
+
}[]>;
|
|
139
|
+
/** Test-only DI seam (AGENTS.md invariant 7). */
|
|
140
|
+
export declare const _internals: {
|
|
141
|
+
emit: typeof emit;
|
|
142
|
+
readFile: typeof readFile;
|
|
143
|
+
writeFile: typeof writeFile;
|
|
144
|
+
copyFile: typeof copyFile;
|
|
145
|
+
mkdir: typeof mkdir;
|
|
146
|
+
stat: typeof stat;
|
|
147
|
+
readdir: typeof readdir;
|
|
148
|
+
resolveHiveDataDir: typeof resolveHiveDataDir;
|
|
149
|
+
resolveHiveKnowledgePath: typeof resolveHiveKnowledgePath;
|
|
150
|
+
transactHiveStore: typeof transactHiveStore;
|
|
151
|
+
realpath: typeof realpath;
|
|
152
|
+
rm: typeof rm;
|
|
153
|
+
chmod: typeof chmod;
|
|
154
|
+
readQuarantineSecret: typeof readQuarantineSecret;
|
|
155
|
+
};
|
|
156
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The event catalog (issue #2029).
|
|
3
3
|
*
|
|
4
|
-
* Exactly
|
|
4
|
+
* Exactly 42 entries, matching the `TelemetryEvent` union at
|
|
5
5
|
* `src/telemetry.ts:15-91`. Thirty-eight predate the #2029 contract; the 39th is
|
|
6
6
|
* `agent_conflict_detected` (previously emitted through a force-cast past the
|
|
7
7
|
* type system), and the 40th is `close_archive_result` (issue #2030 — the
|
|
@@ -62,7 +62,7 @@ export interface CatalogEntry {
|
|
|
62
62
|
/**
|
|
63
63
|
* Whether an event of this kind must carry `trace.parentSpanId`.
|
|
64
64
|
*
|
|
65
|
-
* `false` for all
|
|
65
|
+
* `false` for all 42 entries today, and that is a truthful statement about
|
|
66
66
|
* the current system rather than a placeholder: no producer supplies a
|
|
67
67
|
* parent span, so `createObservation` never sets one. Setting this to `true`
|
|
68
68
|
* for a kind whose producer cannot supply a parent would make every
|
package/dist/plan/ledger.d.ts
CHANGED
|
@@ -62,6 +62,16 @@ export type LedgerEventInput = Omit<LedgerEvent, 'seq' | 'timestamp' | 'plan_has
|
|
|
62
62
|
export interface SnapshotEventPayload {
|
|
63
63
|
plan: Plan;
|
|
64
64
|
payload_hash: string;
|
|
65
|
+
plan_epoch?: string;
|
|
66
|
+
root_event_hash?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface PlanEpochIdentity {
|
|
69
|
+
planId: string;
|
|
70
|
+
planIdentityHash: string;
|
|
71
|
+
planEpoch: string;
|
|
72
|
+
rootEventHash: string;
|
|
73
|
+
payloadHash: string;
|
|
74
|
+
source: 'root' | 'plan_epoch_adopted';
|
|
65
75
|
}
|
|
66
76
|
/**
|
|
67
77
|
* Error thrown when a writer attempts to append to the ledger with stale state.
|
|
@@ -173,6 +183,23 @@ export declare function readLedgerEvents(directory: string): Promise<LedgerEvent
|
|
|
173
183
|
* @param planId - Unique identifier for the plan
|
|
174
184
|
*/
|
|
175
185
|
export declare function initLedger(directory: string, planId: string, initialPlanHash?: string, initialPlan?: Plan): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Read and validate the current plan epoch identity without creating,
|
|
188
|
+
* adopting, or appending any ledger state.
|
|
189
|
+
*
|
|
190
|
+
* Returns null when the ledger is absent or when a legacy ledger has not yet
|
|
191
|
+
* adopted an epoch. Invalid or conflicting epoch metadata still fails closed.
|
|
192
|
+
*/
|
|
193
|
+
export declare function readPlanEpochIdentity(directory: string, authoritativePlan: Plan): Promise<PlanEpochIdentity | null>;
|
|
194
|
+
/**
|
|
195
|
+
* Return the persisted plan epoch for the authoritative ledger root, adopting
|
|
196
|
+
* one backward-readable snapshot when a legacy root predates the epoch field.
|
|
197
|
+
*
|
|
198
|
+
* The caller is expected to already hold the higher-level plan lock. This
|
|
199
|
+
* helper acquires only the ledger append lock so concurrent adopters serialize
|
|
200
|
+
* to one adoption snapshot.
|
|
201
|
+
*/
|
|
202
|
+
export declare function getOrAdoptPlanEpochUnderLock(directory: string, authoritativePlan: Plan): Promise<PlanEpochIdentity>;
|
|
176
203
|
/**
|
|
177
204
|
* Append a new event to the ledger.
|
|
178
205
|
* Uses atomic write: write to temp file then rename.
|
|
@@ -390,7 +417,9 @@ export interface LedgerIntegrityResult {
|
|
|
390
417
|
* @param directory - The working directory
|
|
391
418
|
* @returns LedgerIntegrityResult with events, truncated flag, and bad suffix
|
|
392
419
|
*/
|
|
393
|
-
export declare function readLedgerEventsWithIntegrity(directory: string
|
|
420
|
+
export declare function readLedgerEventsWithIntegrity(directory: string, options?: {
|
|
421
|
+
failClosedOnReadError?: boolean;
|
|
422
|
+
}): Promise<LedgerIntegrityResult>;
|
|
394
423
|
/**
|
|
395
424
|
* Result of a {@link quarantineLedgerSuffix} call.
|
|
396
425
|
*/
|
|
@@ -516,5 +545,6 @@ export declare const _internals: {
|
|
|
516
545
|
getPlanJsonPath: typeof getPlanJsonPath;
|
|
517
546
|
writeFileFsyncedThenRename: typeof writeFileFsyncedThenRename;
|
|
518
547
|
fsyncRecoveryDirectory: typeof fsyncRecoveryDirectory;
|
|
548
|
+
randomUUID: () => `${string}-${string}-${string}-${string}-${string}`;
|
|
519
549
|
};
|
|
520
550
|
export {};
|
package/dist/plan/manager.d.ts
CHANGED
|
@@ -214,6 +214,7 @@ export declare function isTaskSettled(directory: string, taskId: string): Promis
|
|
|
214
214
|
export declare function updateTaskStatus(directory: string, taskId: string, status: TaskStatus, options?: {
|
|
215
215
|
force?: boolean;
|
|
216
216
|
planLockAlreadyHeld?: boolean;
|
|
217
|
+
terminalReconciliation?: boolean;
|
|
217
218
|
}): Promise<Plan>;
|
|
218
219
|
/**
|
|
219
220
|
* Generate deterministic markdown view from plan object.
|
package/dist/state.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ export interface PrSubscriptionState {
|
|
|
64
64
|
* Per-task workflow state for gate progression tracking.
|
|
65
65
|
* Transitions must be forward-only: idle → coder_delegated → pre_check_passed → reviewer_run → tests_run → complete
|
|
66
66
|
*/
|
|
67
|
-
export type TaskWorkflowState = 'idle' | 'coder_delegated' | 'pre_check_passed' | 'reviewer_run' | 'tests_run' | 'rework_required' | 'complete' | 'blocked';
|
|
67
|
+
export type TaskWorkflowState = 'idle' | 'coder_delegated' | 'pre_check_passed' | 'reviewer_run' | 'tests_run' | 'rework_required' | 'complete' | 'blocked' | 'closed';
|
|
68
68
|
export interface TaskWorkflowCacheEntry {
|
|
69
69
|
generation: number;
|
|
70
70
|
retryCount: number;
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export type TelemetryEvent = 'session_started' | 'session_ended' | 'agent_activa
|
|
|
26
26
|
* `prm_hard_stop` TRIGGER emitted by `src/prm/escalation.ts`. A trigger with
|
|
27
27
|
* no matching delivery means the containment never reached the agent.
|
|
28
28
|
*/
|
|
29
|
-
| 'prm_hard_stop_delivered' | 'agent_conflict_detected' | 'close_archive_result' | 'knowledge_receipt_transition';
|
|
29
|
+
| 'prm_hard_stop_delivered' | 'agent_conflict_detected' | 'close_archive_result' | 'knowledge_receipt_transition' | 'knowledge_maintenance';
|
|
30
30
|
/** Stable classification for how a reviewer-gate decision was established. */
|
|
31
31
|
export type ReviewerGateEvidenceKind = 'genuine' | 'fallback' | 'data_quality' | 'block';
|
|
32
32
|
/**
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Plan } from '../config/plan-schema.js';
|
|
2
|
+
export interface CloseTerminalResult {
|
|
3
|
+
plan: Plan;
|
|
4
|
+
closedTaskIds: string[];
|
|
5
|
+
preservedCompletedTaskIds: string[];
|
|
6
|
+
closedPhaseIds: number[];
|
|
7
|
+
/**
|
|
8
|
+
* Tasks whose terminal state was settled as a QA-exempt forced completion — either
|
|
9
|
+
* recorded as such by this reconciliation, or already carrying `forcedCompletion`
|
|
10
|
+
* in durable evidence from an earlier one. Surfaced so `/swarm close` can report
|
|
11
|
+
* that these tasks did not pass the normal gates; without it a forced completion is
|
|
12
|
+
* indistinguishable from a genuinely reviewed and tested one.
|
|
13
|
+
*/
|
|
14
|
+
forcedCompletionTaskIds: string[];
|
|
15
|
+
}
|
|
16
|
+
/** Reconcile `/swarm close` intent with exact-task workflow authority. */
|
|
17
|
+
export declare function reconcileCloseTerminalState(directory: string, targetPlan: Plan, options: {
|
|
18
|
+
actor: string;
|
|
19
|
+
requestedClosedTaskIds: string[];
|
|
20
|
+
closedPhaseIds: number[];
|
|
21
|
+
originalStatuses?: Map<string, string>;
|
|
22
|
+
}): Promise<CloseTerminalResult>;
|
|
@@ -1,32 +1,11 @@
|
|
|
1
1
|
import type { BackgroundTaskChangeContext, BackgroundWorktreeDescriptor } from '../background/pending-delegations.js';
|
|
2
2
|
import { type TaskEvidence } from '../gate-evidence.js';
|
|
3
3
|
import type { MergeOperationProvenance } from '../worktree/merge.js';
|
|
4
|
-
type CoderSettlementState = 'ABORTED' | 'COMMITTED' | 'DISPATCHED' | 'PREPARED';
|
|
5
|
-
interface CoderSettlementWal {
|
|
6
|
-
version: 1;
|
|
7
|
-
state: CoderSettlementState;
|
|
8
|
-
taskId: string;
|
|
9
|
-
transitionId: string;
|
|
10
|
-
actor: string;
|
|
11
|
-
processId: number;
|
|
12
|
-
runtimeId: string;
|
|
13
|
-
expectedGeneration: number;
|
|
14
|
-
context: BackgroundTaskChangeContext;
|
|
15
|
-
worktree?: BackgroundWorktreeDescriptor;
|
|
16
|
-
observedFiles?: string[];
|
|
17
|
-
mergeProvenance?: MergeOperationProvenance;
|
|
18
|
-
accepted?: boolean;
|
|
19
|
-
testEngineerExempt?: boolean;
|
|
20
|
-
settlementFailed?: boolean;
|
|
21
|
-
cleanupComplete?: boolean;
|
|
22
|
-
recordedAt: string;
|
|
23
|
-
}
|
|
24
4
|
export interface CoderSettlementResult {
|
|
25
5
|
evidence: TaskEvidence;
|
|
26
6
|
accepted: boolean;
|
|
27
7
|
alreadyApplied: boolean;
|
|
28
8
|
}
|
|
29
|
-
declare function parseWal(raw: string): CoderSettlementWal;
|
|
30
9
|
export declare function beginCoderSettlement(options: {
|
|
31
10
|
directory: string;
|
|
32
11
|
taskId: string;
|
|
@@ -56,7 +35,5 @@ export declare function recoverCoderSettlement(directory: string, taskId: string
|
|
|
56
35
|
export declare function releaseCoderDispatchOwnership(directory: string, taskId: string, transitionId: string): void;
|
|
57
36
|
export declare function assertNoUnsettledCoderDispatch(directory: string, taskId: string): Promise<void>;
|
|
58
37
|
export declare const _internals: {
|
|
59
|
-
parseWal: typeof parseWal;
|
|
60
38
|
liveDispatches: Set<string>;
|
|
61
39
|
};
|
|
62
|
-
export {};
|
|
@@ -10,6 +10,7 @@ export interface TaskRepairResult<TPlan> {
|
|
|
10
10
|
* the task. This reads only the exact per-task WAL path; it never scans.
|
|
11
11
|
*/
|
|
12
12
|
export declare function recoverPreparedTaskRepair(directory: string, taskId: string, actor: string): Promise<TaskRepairResult<NonNullable<Awaited<ReturnType<typeof loadPlanJsonOnly>>>> | null>;
|
|
13
|
+
export declare function recoverPreparedTaskRepairUnderPlanLock(directory: string, taskId: string, actor: string, currentPlan: NonNullable<Awaited<ReturnType<typeof loadPlanJsonOnly>>>): Promise<TaskRepairResult<NonNullable<Awaited<ReturnType<typeof loadPlanJsonOnly>>>> | null>;
|
|
13
14
|
/**
|
|
14
15
|
* Execute or lazily finish one exact-task repair while the caller holds the
|
|
15
16
|
* plan lock. Lock ordering is therefore always plan -> exact task evidence.
|
|
@@ -1,28 +1,12 @@
|
|
|
1
1
|
import type { Plan } from '../config/plan-schema.js';
|
|
2
2
|
import { type TaskEvidence, withTaskEvidenceTransaction } from '../gate-evidence.js';
|
|
3
|
-
import type {
|
|
4
|
-
type TerminalPlanStatus = 'blocked' | 'completed';
|
|
5
|
-
type TerminalWorkflowState = 'blocked' | 'complete';
|
|
6
|
-
type TerminalWalState = 'ABORTED' | 'COMMITTED' | 'PREPARED';
|
|
7
|
-
interface TaskTerminalWal {
|
|
8
|
-
version: 1;
|
|
9
|
-
state: TerminalWalState;
|
|
10
|
-
taskId: string;
|
|
11
|
-
transitionId: string;
|
|
12
|
-
actor: string;
|
|
13
|
-
oldPlanStatus: string;
|
|
14
|
-
newPlanStatus: TerminalPlanStatus;
|
|
15
|
-
oldWorkflowState: TaskWorkflowState;
|
|
16
|
-
newWorkflowState: TerminalWorkflowState;
|
|
17
|
-
generation: number;
|
|
18
|
-
qaExempt: boolean;
|
|
19
|
-
recordedAt: string;
|
|
20
|
-
}
|
|
3
|
+
import type { TaskTerminalWal, TerminalPlanStatus } from './workflow-wal-schema.js';
|
|
21
4
|
export interface TaskTerminalResult<TPlan> {
|
|
22
5
|
plan: TPlan;
|
|
23
6
|
evidence: TaskEvidence;
|
|
24
7
|
alreadyApplied: boolean;
|
|
25
8
|
transitionId: string;
|
|
9
|
+
targetStatus: TerminalPlanStatus;
|
|
26
10
|
}
|
|
27
11
|
declare function applyTerminalEvidence(transaction: Parameters<Parameters<typeof withTaskEvidenceTransaction>[3]>[0], wal: TaskTerminalWal): Promise<TaskEvidence>;
|
|
28
12
|
/** Narrow dependency-injection seam for crash-window failure tests. */
|
|
@@ -30,12 +14,16 @@ export declare const _internals: {
|
|
|
30
14
|
applyTerminalEvidence: typeof applyTerminalEvidence;
|
|
31
15
|
};
|
|
32
16
|
/**
|
|
33
|
-
* Lazily close
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
17
|
+
* Lazily close a recoverable terminal crash window: the WAL is PREPARED but the
|
|
18
|
+
* plan/evidence pair it describes has not settled. A v1 record whose plan and
|
|
19
|
+
* evidence are both still old is safely aborted rather than executing an
|
|
20
|
+
* abandoned completed/blocked request. A v2 (close) record is instead
|
|
21
|
+
* force-forwarded even from old plan and old evidence — its plan-epoch identity
|
|
22
|
+
* is re-verified first, and abandoning it would leave a task the caller already
|
|
23
|
+
* closed silently open.
|
|
37
24
|
*/
|
|
38
25
|
export declare function recoverPreparedTaskTerminal(directory: string, taskId: string, actor: string): Promise<TaskTerminalResult<Plan> | null>;
|
|
26
|
+
export declare function recoverPreparedTaskTerminalUnderPlanLock(directory: string, taskId: string, actor: string, currentPlan: Plan): Promise<TaskTerminalResult<Plan> | null>;
|
|
39
27
|
/** Commit a terminal plan/evidence transition while the caller holds plan.json. */
|
|
40
28
|
export declare function commitTaskTerminalUnderPlanLock<TPlan>(options: {
|
|
41
29
|
directory: string;
|
|
@@ -45,8 +33,15 @@ export declare function commitTaskTerminalUnderPlanLock<TPlan>(options: {
|
|
|
45
33
|
currentPlanStatus: string;
|
|
46
34
|
targetStatus: TerminalPlanStatus;
|
|
47
35
|
qaExempt: boolean;
|
|
36
|
+
resolveTerminal?: (evidence: TaskEvidence | null) => {
|
|
37
|
+
targetStatus: TerminalPlanStatus;
|
|
38
|
+
qaExempt: boolean;
|
|
39
|
+
preserveEvidence?: boolean;
|
|
40
|
+
};
|
|
41
|
+
planIdentityHash?: string;
|
|
42
|
+
planEpoch?: string;
|
|
48
43
|
currentPlan: TPlan;
|
|
49
44
|
validateEvidence?: (evidence: TaskEvidence | null) => Promise<void> | void;
|
|
50
|
-
updatePlan: () => Promise<TPlan>;
|
|
45
|
+
updatePlan: (targetStatus: TerminalPlanStatus) => Promise<TPlan>;
|
|
51
46
|
}): Promise<TaskTerminalResult<TPlan>>;
|
|
52
47
|
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import { type FileHandle } from 'node:fs/promises';
|
|
3
|
+
import { type CoderSettlementWal, type TaskRepairWal, type TaskTerminalWal } from './workflow-wal-schema.js';
|
|
4
|
+
type WorkflowWalKind = 'coder-settlement' | 'task-repair' | 'task-terminal';
|
|
5
|
+
type WorkflowWalByKind = {
|
|
6
|
+
'coder-settlement': CoderSettlementWal;
|
|
7
|
+
'task-repair': TaskRepairWal;
|
|
8
|
+
'task-terminal': TaskTerminalWal;
|
|
9
|
+
};
|
|
10
|
+
type OpenFile = (filePath: string, flags: string) => Promise<FileHandle>;
|
|
11
|
+
export declare const _internals: {
|
|
12
|
+
openFile: OpenFile;
|
|
13
|
+
openFileSync: typeof fs.openSync;
|
|
14
|
+
readFileSync: typeof fs.readSync;
|
|
15
|
+
closeFileSync: typeof fs.closeSync;
|
|
16
|
+
};
|
|
17
|
+
export declare function readWorkflowWalFile<K extends WorkflowWalKind>(kind: K, filePath: string, expectedTaskId: string): Promise<WorkflowWalByKind[K] | null>;
|
|
18
|
+
export declare function readWorkflowWalFileSync<K extends WorkflowWalKind>(kind: K, filePath: string, expectedTaskId: string): WorkflowWalByKind[K] | null;
|
|
19
|
+
export declare function writeWorkflowWalFile(kind: WorkflowWalKind, filePath: string, wal: CoderSettlementWal | TaskRepairWal | TaskTerminalWal): Promise<void>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { BackgroundTaskChangeContext, BackgroundWorktreeDescriptor } from '../background/pending-delegations.js';
|
|
2
|
+
import type { TaskWorkflowState } from '../state.js';
|
|
3
|
+
import { type MergeOperationProvenance } from '../worktree/merge.js';
|
|
4
|
+
export type CoderSettlementState = 'ABORTED' | 'COMMITTED' | 'DISPATCHED' | 'PREPARED';
|
|
5
|
+
export interface CoderSettlementWal {
|
|
6
|
+
version: 1;
|
|
7
|
+
state: CoderSettlementState;
|
|
8
|
+
taskId: string;
|
|
9
|
+
transitionId: string;
|
|
10
|
+
actor: string;
|
|
11
|
+
processId: number;
|
|
12
|
+
runtimeId: string;
|
|
13
|
+
expectedGeneration: number;
|
|
14
|
+
context: BackgroundTaskChangeContext;
|
|
15
|
+
worktree?: BackgroundWorktreeDescriptor;
|
|
16
|
+
observedFiles?: string[];
|
|
17
|
+
mergeProvenance?: MergeOperationProvenance;
|
|
18
|
+
accepted?: boolean;
|
|
19
|
+
testEngineerExempt?: boolean;
|
|
20
|
+
settlementFailed?: boolean;
|
|
21
|
+
cleanupComplete?: boolean;
|
|
22
|
+
recordedAt: string;
|
|
23
|
+
}
|
|
24
|
+
export type RepairWalState = 'ABORTED' | 'COMMITTED' | 'PREPARED';
|
|
25
|
+
export interface TaskRepairWal {
|
|
26
|
+
version: 1;
|
|
27
|
+
state: RepairWalState;
|
|
28
|
+
taskId: string;
|
|
29
|
+
transitionId: string;
|
|
30
|
+
reason: string;
|
|
31
|
+
actor: string;
|
|
32
|
+
oldPlanStatus: string;
|
|
33
|
+
newPlanStatus: 'in_progress';
|
|
34
|
+
oldWorkflowState: string;
|
|
35
|
+
newWorkflowState: 'idle';
|
|
36
|
+
oldGeneration: number;
|
|
37
|
+
generation: number;
|
|
38
|
+
recordedAt: string;
|
|
39
|
+
}
|
|
40
|
+
export type TerminalWalState = 'ABORTED' | 'COMMITTED' | 'PREPARED';
|
|
41
|
+
export type TerminalPlanStatus = 'blocked' | 'closed' | 'completed';
|
|
42
|
+
export type TerminalWorkflowState = 'blocked' | 'closed' | 'complete';
|
|
43
|
+
export interface TaskTerminalWalV1 {
|
|
44
|
+
version: 1;
|
|
45
|
+
state: TerminalWalState;
|
|
46
|
+
taskId: string;
|
|
47
|
+
transitionId: string;
|
|
48
|
+
actor: string;
|
|
49
|
+
oldPlanStatus: string;
|
|
50
|
+
newPlanStatus: 'blocked' | 'completed';
|
|
51
|
+
oldWorkflowState: TaskWorkflowState;
|
|
52
|
+
newWorkflowState: 'blocked' | 'complete';
|
|
53
|
+
generation: number;
|
|
54
|
+
qaExempt: boolean;
|
|
55
|
+
recordedAt: string;
|
|
56
|
+
}
|
|
57
|
+
export interface TaskTerminalWalV2 extends Omit<TaskTerminalWalV1, 'version' | 'newPlanStatus' | 'newWorkflowState'> {
|
|
58
|
+
version: 2;
|
|
59
|
+
newPlanStatus: 'closed' | 'completed';
|
|
60
|
+
newWorkflowState: 'closed' | 'complete';
|
|
61
|
+
planIdentityHash: string;
|
|
62
|
+
planEpoch: string;
|
|
63
|
+
}
|
|
64
|
+
export type TaskTerminalWal = TaskTerminalWalV1 | TaskTerminalWalV2;
|
|
65
|
+
export declare function parseCoderSettlementWal(raw: string, filePath: string, expectedTaskId?: string): CoderSettlementWal;
|
|
66
|
+
export declare function parseTaskRepairWal(raw: string, filePath: string, expectedTaskId?: string): TaskRepairWal;
|
|
67
|
+
export declare function parseTaskTerminalWal(raw: string, filePath: string, expectedTaskId?: string): TaskTerminalWal;
|
package/dist/worktree/merge.d.ts
CHANGED
|
@@ -99,6 +99,23 @@ export interface MergeOperationProvenance {
|
|
|
99
99
|
branchName: string;
|
|
100
100
|
strategy: MergeStrategy;
|
|
101
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Git object ids as written by `git rev-parse HEAD`: sha1 (40) today, sha256 (64)
|
|
104
|
+
* under the sha256 object format. Abbreviated ids are deliberately rejected —
|
|
105
|
+
* nothing in this codebase persists them. Constraining the shape also makes a
|
|
106
|
+
* leading `-` structurally impossible for values later passed to git as
|
|
107
|
+
* revisions, which matters because neither sink below passes a separator that
|
|
108
|
+
* would protect one today: the `git log` call's `--` sits after the range and
|
|
109
|
+
* separates pathspecs rather than options, and the
|
|
110
|
+
* `git merge-base --is-ancestor` call passes the revision bare. (Both commands
|
|
111
|
+
* would accept `--`/`--end-of-options` before the operand, so sink-side
|
|
112
|
+
* hardening is also available; this pattern guards the value itself.)
|
|
113
|
+
*
|
|
114
|
+
* Owned here beside `MergeOperationProvenance` because this module defines the
|
|
115
|
+
* struct whose head fields reach git argv; `workflow-wal-schema.ts` re-imports
|
|
116
|
+
* it so the two validation surfaces for the same values cannot drift apart.
|
|
117
|
+
*/
|
|
118
|
+
export declare const GIT_OBJECT_ID_PATTERN: RegExp;
|
|
102
119
|
export type MergeReconciliationResult = {
|
|
103
120
|
landed: true;
|
|
104
121
|
method: 'ancestry' | 'cherry-pick-trailer';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-swarm",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.142.1",
|
|
4
4
|
"description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|