@groundnuty/macf-core 0.2.47 → 0.2.48

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.
@@ -16,7 +16,10 @@ export type UpgradeDisposition = 'behind' | 'at-target' | 'offline';
16
16
  export interface AgentUpgradePlan {
17
17
  /** The agent's routing label (registry key). */
18
18
  readonly agent: string;
19
- /** The fleet (registry identifier) this member belongs to. */
19
+ /**
20
+ * The fleet this member belongs to — the workspace's PROJECT (macf#710), NOT
21
+ * its (possibly-shared) registry scope. See `WorkspaceRecord.project`.
22
+ */
20
23
  readonly fleet: string;
21
24
  /** The agent's live self-reported `/health.version`, or `null` when offline/version-less. */
22
25
  readonly runningVersion: string | null;
@@ -27,18 +30,92 @@ export interface AgentUpgradePlan {
27
30
  }
28
31
  /**
29
32
  * The EXECUTE-path outcome of a single agent in the roll:
30
- * - `upgraded` — rolled + came up green on the target.
31
- * - `busy-skipped` — busy-gated (or `--wait` timed out still busy); NOT a
32
- * failure, so the roll CONTINUES to the next agent.
33
- * - `halted` — did not verify-green within the budget; the roll STOPS here.
33
+ * - `upgraded` — rolled + confirmed green on the target. CONTINUES.
34
+ * - `busy-skipped` — busy-gated (or `--wait` timed out still busy),
35
+ * BEFORE any mutation; NOT a failure, CONTINUES.
36
+ * - `config-dirty-skipped` — config-dirty-gated (uncommitted changes on the
37
+ * roll's touched-config surface), BEFORE any
38
+ * mutation; NOT a failure, CONTINUES. The roll
39
+ * OBJECTS with the specific file list + an
40
+ * agent-directed message (macf#725 — replaces
41
+ * macf#722 Fix B's silent skip).
42
+ * - `halted` — verify-green did NOT confirm the target version;
43
+ * the roll STOPS here. `reason` distinguishes WHY
44
+ * (see `HaltReason`).
45
+ *
46
+ * The two pre-flight skip outcomes (`busy-skipped` / `config-dirty-skipped`)
47
+ * are safe to continue past because the agent was NEVER mutated. `halted` is
48
+ * always terminal because the agent WAS rolled and its post-restart state is
49
+ * either confirmed-bad or unconfirmed — neither is safe to leave behind while
50
+ * moving on to the next agent (macf#722 Fix A).
51
+ */
52
+ export type RollOutcome = 'upgraded' | 'busy-skipped' | 'config-dirty-skipped' | 'halted';
53
+ /**
54
+ * WHY a roll halted (only meaningful when `outcome === 'halted'`):
55
+ * - `bad-release` — verify-green confirmed the agent came back up
56
+ * REACHABLE at its OLD (pre-upgrade) version — a
57
+ * crash-loop / stuck-old-process release. Terminal;
58
+ * stops this fleet's roll + later fleets.
59
+ * - `relaunch-unconfirmed` — past the full verify-green grace budget, the
60
+ * agent was never confirmed at the target version:
61
+ * down the whole time, unreachable, or reachable at
62
+ * some OTHER (neither old-pin nor target) version.
63
+ * "Not yet green" cannot distinguish a slow-but-fine
64
+ * relaunch from a release that crashes on startup
65
+ * (which never shows the old version either), so
66
+ * this is deliberately NOT a continue.
34
67
  */
35
- export type RollOutcome = 'upgraded' | 'busy-skipped' | 'halted';
36
- /** The per-agent EXECUTE result. `detail` carries the green version or halt reason. */
68
+ export type HaltReason = 'bad-release' | 'relaunch-unconfirmed';
69
+ /** The per-agent EXECUTE result. `detail` carries a human-readable summary. */
37
70
  export interface AgentRollResult {
38
71
  readonly agent: string;
39
72
  readonly outcome: RollOutcome;
73
+ /** Set only when `outcome === 'halted'` — see `HaltReason`. */
74
+ readonly reason?: HaltReason;
40
75
  readonly detail?: string;
41
76
  }
77
+ /**
78
+ * The roll's TOUCHED-CONFIG-SURFACE UNION (macf#722 Fix B, corrected naming
79
+ * macf#725) — the path globs `rollFleet`'s pre-flight config-dirty gate checks
80
+ * for uncommitted tracked changes before touching an agent.
81
+ *
82
+ * **This is a UNION, not an "operator-preserved" set** (the DR-037 Amendment B
83
+ * naming was a misnomer, corrected here macf#725): it spans BOTH (a) the files
84
+ * `macf update` OVERWRITES (the managed surface — canonical rules/scripts/hooks
85
+ * under `.claude/**`, `.macf/*`) and (b) the files `restart-self` would STASH
86
+ * (the operator surface — `settings.local.json`, `rules/project/**`,
87
+ * `env.local.*`, `CLAUDE.md`, a hand-authored `claude.sh`). Both halves answer
88
+ * the SAME pre-flight question the gate asks — "would this roll's `upgrade` +
89
+ * `restart` silently clobber or stash SOMETHING uncommitted on this surface?"
90
+ * — so both belong in the one union the gate checks, regardless of which half
91
+ * of DR-029's managed-vs-operator taxonomy a given path falls in.
92
+ *
93
+ * Sourced from DR-029's Amendment (2026-06-27, macf#598) managed-vs-operator
94
+ * taxonomy: `.claude/**` (rules + scripts + settings — managed AND
95
+ * project-tier), `CLAUDE.md` (operator workbench doc), `claude.sh` (the
96
+ * launcher — operator-preserved when hand-authored/header-less, and harmless
97
+ * to include even when macf-managed since a macf-managed copy is never
98
+ * legitimately "dirty" outside an in-flight `macf update`), and `env.local.*`
99
+ * (the operator-custom env extension slot — see
100
+ * `design/decisions/DR-029-substrate-config-via-init-and-reintegrate.md`
101
+ * Amendment table). Deliberately excludes macf-managed/regenerated files
102
+ * (`env.*` canonical seven, `host-prelude.sh`) that are ONLY ever touched by
103
+ * `macf update` itself and never by an operator — dirtiness there pre-flight
104
+ * would still be a genuine conflict (someone hand-edited a regenerated file),
105
+ * so those ARE covered by `.claude/**`/`.macf/*` where they live; the excluded
106
+ * class is narrower than "everything macf update touches."
107
+ *
108
+ * NOTE (macf#724 review, still applicable post-rename): this gate's set is
109
+ * intentionally a slight SUPERSET of DR-029's *regenerate*-boundary for
110
+ * `claude.sh`. The two answer DIFFERENT questions — this gate: "does the roll
111
+ * need to OBJECT before touching this agent?"; DR-029's header-conditional
112
+ * rule: "should `macf update` REGENERATE this file?". So do NOT "align"
113
+ * `claude.sh` here to DR-029's header-conditional form: that would reintroduce
114
+ * the roll-past-a-dirty-managed-`claude.sh` hole. Unconditional here is
115
+ * harmless when clean (nothing flagged) and protective when dirty, regardless
116
+ * of header.
117
+ */
118
+ export declare const ROLL_TOUCHED_CONFIG_PATTERNS: readonly [".claude/**", "CLAUDE.md", "claude.sh", "env.local.*"];
42
119
  /** The result of rolling ONE fleet (the EXECUTE path). */
43
120
  export interface FleetRollResult {
44
121
  readonly results: readonly AgentRollResult[];
@@ -48,6 +125,8 @@ export interface FleetRollResult {
48
125
  readonly upgraded: number;
49
126
  /** Count of agents skipped because they were busy. */
50
127
  readonly busySkipped: number;
128
+ /** Count of agents skipped because their config surface was dirty (macf#722 Fix B). */
129
+ readonly configDirtySkipped: number;
51
130
  }
52
131
  /** Progress events for CLI rendering (the RESULT objects are what tests assert on). */
53
132
  export type UpgradeEvent = {
@@ -64,18 +143,42 @@ export type UpgradeEvent = {
64
143
  readonly agent: string;
65
144
  readonly from: string | null;
66
145
  readonly to: string;
146
+ }
147
+ /**
148
+ * The pre-flight OBJECT (macf#725) — the agent's touched-config surface has
149
+ * UNCOMMITTED changes. `files` is the exact uncommitted-path list;
150
+ * `message` is the ready-to-forward, agent-directed text (inspect + commit /
151
+ * delete / gitignore, then re-run). Fired INSTEAD of any mutation — nothing
152
+ * on this agent was touched.
153
+ */
154
+ | {
155
+ readonly kind: 'config-dirty-skip';
156
+ readonly agent: string;
157
+ readonly files: readonly string[];
158
+ readonly message: string;
67
159
  } | {
68
160
  readonly kind: 'busy-skip';
69
161
  readonly agent: string;
70
162
  readonly waited: boolean;
71
- } | {
163
+ }
164
+ /**
165
+ * The post-upgrade modified-files report (macf#725) — fired once an agent is
166
+ * confirmed green, before advancing to the next agent. `files` lists what
167
+ * `macf update` regenerated (and `restart-self` deliberately left
168
+ * uncommitted) in the relaunched agent's workspace; `message` is the
169
+ * ready-to-forward, agent-directed text (review with `git diff` + commit /
170
+ * act as needed).
171
+ */
172
+ | {
72
173
  readonly kind: 'upgraded';
73
174
  readonly agent: string;
74
175
  readonly version: string;
176
+ readonly modifiedFiles: readonly string[];
177
+ readonly message: string;
75
178
  } | {
76
179
  readonly kind: 'halt';
77
180
  readonly agent: string;
78
- readonly reason: string;
181
+ readonly reason: HaltReason;
79
182
  readonly lastVersion: string | null;
80
183
  };
81
184
  /**
@@ -96,6 +199,16 @@ export interface RollFleetOptions {
96
199
  readonly waitTimeoutMs?: number;
97
200
  /** Re-poll interval while waiting for idle (ms). */
98
201
  readonly waitPollMs?: number;
202
+ /**
203
+ * `--force` (macf#722 Fix B / macf#725): roll an agent EVEN IF its config
204
+ * surface is dirty PRE-flight — bypasses the pre-flight config-dirty OBJECT
205
+ * gate. Once bypassed for an agent, that agent's `restart` is ALSO told
206
+ * `leaveConfigUncommitted: true` (same as the normal clean-path transaction)
207
+ * — `--force` means "roll anyway," not "stash the pre-existing dirt," so the
208
+ * pre-existing uncommitted files are left in place exactly like `macf
209
+ * update`'s own regeneration would be.
210
+ */
211
+ readonly force?: boolean;
99
212
  }
100
213
  /** Injected side-effect seams for the roll (all fakeable in tests). */
101
214
  export interface RollFleetDeps {
@@ -119,11 +232,46 @@ export declare const DEFAULT_WAIT_TIMEOUT_MS = 300000;
119
232
  /** Default `--wait` re-poll interval (ms). */
120
233
  export declare const DEFAULT_WAIT_POLL_MS = 5000;
121
234
  /**
122
- * Roll ONE fleet: for every `behind` plan (in order) run the busy-gate → upgrade
123
- * → restart → verify-green cycle, HALTING the roll on the first agent that fails
124
- * to come up green. Non-`behind` plans are ignored (planned skips). Busy agents
125
- * are skipped + reported (never a halt); with `wait`, they are re-polled for idle
126
- * first. The verb order + HALT semantics mirror `fleet/upgrade.sh`'s `roll_one`.
235
+ * Build the agent-directed OBJECT message for a config-dirty pre-flight skip
236
+ * (macf#725). Pure — exported for CLI-rendering reuse / tests.
237
+ */
238
+ export declare function buildConfigDirtyMessage(agent: string, files: readonly string[]): string;
239
+ /**
240
+ * Build the agent-directed post-upgrade modified-files message (macf#725).
241
+ * Pure — exported for CLI-rendering reuse / tests.
242
+ *
243
+ * The message names the intended STEADY-STATE explicitly: a clean roll LEAVES
244
+ * this regeneration uncommitted (so the agent can review it), which means the
245
+ * NEXT roll's pre-flight WILL re-flag these same files as uncommitted unless
246
+ * they're committed. That re-flag is intended hygiene ("commit last update's
247
+ * regen before upgrading again"), not a surprise — so the message tells the
248
+ * agent to commit them, not merely review them.
249
+ */
250
+ export declare function buildModifiedFilesMessage(agent: string, files: readonly string[]): string;
251
+ /**
252
+ * Roll ONE fleet: for every `behind` plan (in order) run the PRE-FLIGHT gates
253
+ * (config-dirty, then busy) → upgrade → restart → verify-green cycle, HALTING
254
+ * the roll on the first agent whose post-restart state isn't confirmed-green.
255
+ * Non-`behind` plans are ignored (planned skips). Pre-flight-gated agents are
256
+ * skipped + reported and NEVER a halt (they were never mutated, so continuing
257
+ * is always safe) — config-dirty is checked first because a busy-but-clean
258
+ * agent may still become idle later (`--wait`), whereas a dirty agent is
259
+ * skip-only regardless. With `wait`, a busy agent is re-polled for idle first.
260
+ * The verb order + HALT semantics mirror `fleet/upgrade.sh`'s `roll_one`.
261
+ *
262
+ * **Transactional + OBJECT-with-message revision (macf#725).** The pre-flight
263
+ * config-dirty gate is the ONLY decision point that inspects PRE-upgrade
264
+ * state: clean (or explicitly `--force`-bypassed) ⇒ the roll enters the
265
+ * transaction and MUST complete it — `upgrade` → `restart(agent,
266
+ * { leaveConfigUncommitted: true })` always runs together, never mutating
267
+ * `upgrade` without following through to `restart`. Dirty (and not forced) ⇒
268
+ * the roll does NOTHING to this agent (no `upgrade`, no `restart`) and OBJECTS
269
+ * via `onEvent` with the exact file list + an agent-directed message —
270
+ * reconcile is MANUAL: the agent (or operator) resolves the flagged files and
271
+ * a clean re-run completes it. This replaces the earlier (macf#722 Fix B)
272
+ * silent-skip + separately-force-stashed-restart shape, which could dirty the
273
+ * workspace via `upgrade` and then have `restart-self`'s OWN guard refuse —
274
+ * aborting mid-transaction with the workspace already mutated.
127
275
  */
128
276
  export declare function rollFleet(plans: readonly AgentUpgradePlan[], opts: RollFleetOptions, deps: RollFleetDeps): Promise<FleetRollResult>;
129
277
  /** Options for the multi-fleet orchestrator. */
@@ -134,9 +282,11 @@ export interface UpgradeFleetsOptions extends RollFleetOptions {
134
282
  /** Injected seams for the multi-fleet orchestrator. */
135
283
  export interface UpgradeFleetsDeps {
136
284
  /**
137
- * Resolve the driver for a fleet (registry identifier). Production binds
138
- * `createVmDriverFromConfig` at a representative workspace; tests return a fake.
139
- * `null` ⇒ the fleet cannot be reached (skip + report, NOT a halt).
285
+ * Resolve the driver for a fleet (a PROJECT identifier — macf#710). Production
286
+ * binds `createVmDriverFromConfig` at a representative workspace OF THAT
287
+ * PROJECT (so the driver's mTLS CA + registry namespace are the project's own,
288
+ * never a sibling project's sharing the same registry scope); tests return a
289
+ * fake. `null` ⇒ the fleet cannot be reached (skip + report, NOT a halt).
140
290
  */
141
291
  readonly resolveDriver: (fleet: string) => Promise<FleetDriver | null>;
142
292
  readonly verifyGreen: (opts: VerifyGreenOptions) => Promise<VerifyGreenResult>;
@@ -161,11 +311,14 @@ export interface FleetUpgradeReport {
161
311
  readonly halted: boolean;
162
312
  }
163
313
  /**
164
- * Orchestrate a rolling upgrade across the ORDERED `fleets` (registry
165
- * identifiers), fleet-by-fleet. Each fleet is probed + planned; in EXECUTE mode
166
- * it is then rolled, and a HALT in one fleet STOPS the whole run — later fleets
167
- * are never started (a bad release cannot cascade across fleets). An unresolvable
168
- * fleet is skipped + reported and does NOT halt the run.
314
+ * Orchestrate a rolling upgrade across the ORDERED `fleets` (PROJECT
315
+ * identifiers — macf#710: a "fleet" == a project, which owns its own CA +
316
+ * registry namespace + version cadence; a profile/org registry scope hosting N
317
+ * projects yields N fleets here, never one), fleet-by-fleet. Each fleet is
318
+ * probed + planned; in EXECUTE mode it is then rolled, and a HALT in one fleet
319
+ * STOPS the whole run — later fleets are never started (a bad release cannot
320
+ * cascade across fleets). An unresolvable fleet is skipped + reported and does
321
+ * NOT halt the run.
169
322
  */
170
323
  export declare function upgradeFleets(fleets: readonly string[], opts: UpgradeFleetsOptions, deps: UpgradeFleetsDeps): Promise<FleetUpgradeReport>;
171
324
  //# sourceMappingURL=fleet-upgrade.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fleet-upgrade.d.ts","sourceRoot":"","sources":["../src/fleet-upgrade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fleet-upgrade.d.ts","sourceRoot":"","sources":["../src/fleet-upgrade.ts"],"names":[],"mappings":"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"}
@@ -7,21 +7,46 @@
7
7
  * logic lives in macf-core; the per-runtime driver bodies live in `packages/macf`
8
8
  * or a future K8s package). It NEVER touches `/proc`, tmux, `capture-pane`, or
9
9
  * kubectl — it drives entirely off the injected `FleetDriver` verbs
10
- * (`probe`/`discoverWorkspaces`/`isBusy`/`upgrade`/`restart`) plus an injected
11
- * `verifyGreen` runner, so the SAME sequencer rolls a VM tmux fleet, a macOS
12
- * host, and a far-future K8s deployment by swapping only the driver.
10
+ * (`probe`/`discoverWorkspaces`/`isBusy`/`listDirtyConfig`/`upgrade`/`restart`/
11
+ * `listModifiedFiles`) plus an injected `verifyGreen` runner, so the SAME
12
+ * sequencer rolls a VM tmux fleet, a macOS host, and a far-future K8s deployment
13
+ * by swapping only the driver.
13
14
  *
14
15
  * The state machine (per fleet, one agent at a time):
15
16
  *
16
17
  * probe() + discoverWorkspaces()
17
18
  * → for each member whose RUNNING version < target (compareSemver):
18
- * busy-gate (driver.isBusy → busy ⇒ SKIP+REPORT, or `--wait` for idle)
19
- * → driver.upgrade(agent)
20
- * → driver.restart(agent)
21
- * → verifyGreen({agent, target}) // re-resolves the fresh endpoint
22
- * → green ⇒ next agent
23
- * → NOT green within the budget ⇒ HALT the roll (a bad release
24
- * stalls at agent 1 and CANNOT brick the fleet)
19
+ * PRE-FLIGHT gate (BEFORE any mutation — never touches the agent):
20
+ * config-dirty-gate (driver.listDirtyConfig → non-empty ⇒ OBJECT:
21
+ * SKIP+REPORT the list of uncommitted files + an agent-directed
22
+ * message to inspect-and-commit-or-delete-or-gitignore-then-retry,
23
+ * unless `--force`; macf#725 — TRANSACTIONAL revision of macf#722
24
+ * Fix B: rather than silently stashing operator dirt, the roll
25
+ * OBJECTS and does NOTHING until the agent resolves it)
26
+ * busy-gate (driver.isBusy → busy ⇒ SKIP+REPORT, or `--wait` for idle)
27
+ * → driver.upgrade(agent) // dirties the managed config surface —
28
+ * // this is EXPECTED, not a fault
29
+ * → driver.restart(agent, { leaveConfigUncommitted: true })
30
+ * // relaunches WITHOUT stashing macf update's own regeneration —
31
+ * // the pre-flight gate already proved the ONLY dirt is the
32
+ * // upgrade's, so leaving it uncommitted (visible via `git status`
33
+ * // in the relaunched agent) is safe + intended (macf#725)
34
+ * → verifyGreen({agent, target}) // re-resolves the fresh endpoint
35
+ * each poll, over a relaunch-aware grace budget (`--verify-timeout`)
36
+ * → green on TARGET ⇒ driver.listModifiedFiles(agent) → emit an
37
+ * agent-directed "review + commit what macf update regenerated"
38
+ * message + list, THEN next agent (`upgraded`)
39
+ * → confirmed back on the OLD (pre-upgrade) version ⇒ HALT the
40
+ * roll, reason `bad-release` (a crash-loop / stuck-old-process
41
+ * release stalls at agent 1 and CANNOT brick the fleet)
42
+ * → past-grace still NOT confirmed green (down / unreachable /
43
+ * some other unknown version) ⇒ HALT the roll, reason
44
+ * `relaunch-unconfirmed` — this is NOT a continue: "not yet
45
+ * green" cannot distinguish a slow-but-fine relaunch from a
46
+ * release that crashes on startup (which never shows the old
47
+ * version either), so continuing past an unconfirmed agent
48
+ * would risk cascading a crash-on-start release across the
49
+ * fleet (macf#722 Fix A)
25
50
  *
26
51
  * Multi-fleet (`--fleet a,b,c`) rolls fleet-by-fleet: each fleet's roll must
27
52
  * finish without a HALT before the next fleet starts (a bad release in fleet-1
@@ -29,8 +54,61 @@
29
54
  *
30
55
  * DRY-RUN is the default at the command boundary: `execute: false` computes +
31
56
  * reports the PLAN (probe + classify) and performs NO driver mutations.
57
+ *
58
+ * **Reconcile is MANUAL this iteration (macf#725).** The config-dirty OBJECT
59
+ * path surfaces the dirt via `onEvent` + a non-mutating skip; it does NOT
60
+ * auto-resolve (no auto-stash, no auto-commit, no auto-delete). A clean
61
+ * re-run, after the agent (or operator) resolves the flagged files, completes
62
+ * the roll for that agent.
32
63
  */
33
64
  import { compareSemver } from './semver.js';
65
+ /**
66
+ * The roll's TOUCHED-CONFIG-SURFACE UNION (macf#722 Fix B, corrected naming
67
+ * macf#725) — the path globs `rollFleet`'s pre-flight config-dirty gate checks
68
+ * for uncommitted tracked changes before touching an agent.
69
+ *
70
+ * **This is a UNION, not an "operator-preserved" set** (the DR-037 Amendment B
71
+ * naming was a misnomer, corrected here macf#725): it spans BOTH (a) the files
72
+ * `macf update` OVERWRITES (the managed surface — canonical rules/scripts/hooks
73
+ * under `.claude/**`, `.macf/*`) and (b) the files `restart-self` would STASH
74
+ * (the operator surface — `settings.local.json`, `rules/project/**`,
75
+ * `env.local.*`, `CLAUDE.md`, a hand-authored `claude.sh`). Both halves answer
76
+ * the SAME pre-flight question the gate asks — "would this roll's `upgrade` +
77
+ * `restart` silently clobber or stash SOMETHING uncommitted on this surface?"
78
+ * — so both belong in the one union the gate checks, regardless of which half
79
+ * of DR-029's managed-vs-operator taxonomy a given path falls in.
80
+ *
81
+ * Sourced from DR-029's Amendment (2026-06-27, macf#598) managed-vs-operator
82
+ * taxonomy: `.claude/**` (rules + scripts + settings — managed AND
83
+ * project-tier), `CLAUDE.md` (operator workbench doc), `claude.sh` (the
84
+ * launcher — operator-preserved when hand-authored/header-less, and harmless
85
+ * to include even when macf-managed since a macf-managed copy is never
86
+ * legitimately "dirty" outside an in-flight `macf update`), and `env.local.*`
87
+ * (the operator-custom env extension slot — see
88
+ * `design/decisions/DR-029-substrate-config-via-init-and-reintegrate.md`
89
+ * Amendment table). Deliberately excludes macf-managed/regenerated files
90
+ * (`env.*` canonical seven, `host-prelude.sh`) that are ONLY ever touched by
91
+ * `macf update` itself and never by an operator — dirtiness there pre-flight
92
+ * would still be a genuine conflict (someone hand-edited a regenerated file),
93
+ * so those ARE covered by `.claude/**`/`.macf/*` where they live; the excluded
94
+ * class is narrower than "everything macf update touches."
95
+ *
96
+ * NOTE (macf#724 review, still applicable post-rename): this gate's set is
97
+ * intentionally a slight SUPERSET of DR-029's *regenerate*-boundary for
98
+ * `claude.sh`. The two answer DIFFERENT questions — this gate: "does the roll
99
+ * need to OBJECT before touching this agent?"; DR-029's header-conditional
100
+ * rule: "should `macf update` REGENERATE this file?". So do NOT "align"
101
+ * `claude.sh` here to DR-029's header-conditional form: that would reintroduce
102
+ * the roll-past-a-dirty-managed-`claude.sh` hole. Unconditional here is
103
+ * harmless when clean (nothing flagged) and protective when dirty, regardless
104
+ * of header.
105
+ */
106
+ export const ROLL_TOUCHED_CONFIG_PATTERNS = [
107
+ '.claude/**',
108
+ 'CLAUDE.md',
109
+ 'claude.sh',
110
+ 'env.local.*',
111
+ ];
34
112
  /**
35
113
  * Classify each discovered fleet member against the target version. PURE — no
36
114
  * driver, no clock, no network. The single source of the behind/at-target/offline
@@ -53,7 +131,7 @@ export function planFleetUpgrade(members, state, targetVersion) {
53
131
  }
54
132
  return {
55
133
  agent: m.agent,
56
- fleet: m.registry,
134
+ fleet: m.project,
57
135
  runningVersion,
58
136
  pinnedVersion: m.versionPin,
59
137
  disposition,
@@ -82,20 +160,107 @@ async function waitForIdle(agent, opts, deps) {
82
160
  return false;
83
161
  }
84
162
  /**
85
- * Roll ONE fleet: for every `behind` plan (in order) run the busy-gate → upgrade
86
- * → restart → verify-green cycle, HALTING the roll on the first agent that fails
87
- * to come up green. Non-`behind` plans are ignored (planned skips). Busy agents
88
- * are skipped + reported (never a halt); with `wait`, they are re-polled for idle
89
- * first. The verb order + HALT semantics mirror `fleet/upgrade.sh`'s `roll_one`.
163
+ * Classify a failed verify-green against the agent's PRE-upgrade running
164
+ * version (macf#722 Fix A). `bad-release` requires POSITIVE confirmation that
165
+ * the agent came back reachable at the OLD pin — everything else (never
166
+ * reachable, or reachable at some other unrecognized version) is
167
+ * `relaunch-unconfirmed`. Never infer `bad-release` from absence of success;
168
+ * only from the last-seen version actually matching the old pin.
169
+ */
170
+ function classifyHalt(green, oldVersion) {
171
+ if (green.reason === 'wrong-version' &&
172
+ green.lastVersion !== null &&
173
+ oldVersion !== null &&
174
+ compareSemver(green.lastVersion, oldVersion) === 0) {
175
+ return 'bad-release';
176
+ }
177
+ return 'relaunch-unconfirmed';
178
+ }
179
+ /**
180
+ * Build the agent-directed OBJECT message for a config-dirty pre-flight skip
181
+ * (macf#725). Pure — exported for CLI-rendering reuse / tests.
182
+ */
183
+ export function buildConfigDirtyMessage(agent, files) {
184
+ return (`Fleet upgrade skipped ${agent} — these files have uncommitted changes ` +
185
+ `\`macf update\` would overwrite: ${files.join(', ')}. Inspect each and ` +
186
+ `commit, delete, or .gitignore it, then re-run the upgrade.`);
187
+ }
188
+ /**
189
+ * Build the agent-directed post-upgrade modified-files message (macf#725).
190
+ * Pure — exported for CLI-rendering reuse / tests.
191
+ *
192
+ * The message names the intended STEADY-STATE explicitly: a clean roll LEAVES
193
+ * this regeneration uncommitted (so the agent can review it), which means the
194
+ * NEXT roll's pre-flight WILL re-flag these same files as uncommitted unless
195
+ * they're committed. That re-flag is intended hygiene ("commit last update's
196
+ * regen before upgrading again"), not a surprise — so the message tells the
197
+ * agent to commit them, not merely review them.
198
+ */
199
+ export function buildModifiedFilesMessage(agent, files) {
200
+ return (`Fleet upgrade regenerated these files in ${agent}'s workspace: ` +
201
+ `${files.join(', ')}. Review with \`git diff\` and commit them (so the next ` +
202
+ `upgrade's pre-flight doesn't re-flag them as uncommitted) or act as needed.`);
203
+ }
204
+ /**
205
+ * Roll ONE fleet: for every `behind` plan (in order) run the PRE-FLIGHT gates
206
+ * (config-dirty, then busy) → upgrade → restart → verify-green cycle, HALTING
207
+ * the roll on the first agent whose post-restart state isn't confirmed-green.
208
+ * Non-`behind` plans are ignored (planned skips). Pre-flight-gated agents are
209
+ * skipped + reported and NEVER a halt (they were never mutated, so continuing
210
+ * is always safe) — config-dirty is checked first because a busy-but-clean
211
+ * agent may still become idle later (`--wait`), whereas a dirty agent is
212
+ * skip-only regardless. With `wait`, a busy agent is re-polled for idle first.
213
+ * The verb order + HALT semantics mirror `fleet/upgrade.sh`'s `roll_one`.
214
+ *
215
+ * **Transactional + OBJECT-with-message revision (macf#725).** The pre-flight
216
+ * config-dirty gate is the ONLY decision point that inspects PRE-upgrade
217
+ * state: clean (or explicitly `--force`-bypassed) ⇒ the roll enters the
218
+ * transaction and MUST complete it — `upgrade` → `restart(agent,
219
+ * { leaveConfigUncommitted: true })` always runs together, never mutating
220
+ * `upgrade` without following through to `restart`. Dirty (and not forced) ⇒
221
+ * the roll does NOTHING to this agent (no `upgrade`, no `restart`) and OBJECTS
222
+ * via `onEvent` with the exact file list + an agent-directed message —
223
+ * reconcile is MANUAL: the agent (or operator) resolves the flagged files and
224
+ * a clean re-run completes it. This replaces the earlier (macf#722 Fix B)
225
+ * silent-skip + separately-force-stashed-restart shape, which could dirty the
226
+ * workspace via `upgrade` and then have `restart-self`'s OWN guard refuse —
227
+ * aborting mid-transaction with the workspace already mutated.
90
228
  */
91
229
  export async function rollFleet(plans, opts, deps) {
92
230
  const results = [];
93
231
  let upgraded = 0;
94
232
  let busySkipped = 0;
233
+ let configDirtySkipped = 0;
95
234
  for (const plan of plans) {
96
235
  if (plan.disposition !== 'behind')
97
236
  continue;
98
237
  const agent = plan.agent;
238
+ // PRE-FLIGHT config-dirty gate. By-design inter-roll STEADY-STATE
239
+ // (macf#725): a clean roll LEAVES `macf update`'s regeneration uncommitted
240
+ // (so the relaunched agent reviews it — see `restart`'s
241
+ // `leaveConfigUncommitted` below + `buildModifiedFilesMessage`).
242
+ // Consequently, the NEXT roll's pre-flight WILL object on that
243
+ // still-uncommitted regen. This is INTENDED HYGIENE — "commit last update's
244
+ // regen before upgrading again" — NOT the mid-run abort bug this revision
245
+ // fixed: it is self-resolving via the object-with-message (the agent
246
+ // commits the flagged regen, then a clean re-run rolls). The alternative —
247
+ // auto-committing the deterministic canonical regen at end-of-transaction
248
+ // (zero inter-roll friction, but trades away the agent's review-visibility
249
+ // of what changed) — is a DEFERRED future option, the operator's call.
250
+ if (!opts.force) {
251
+ const dirtyFiles = await deps.driver.listDirtyConfig(agent);
252
+ if (dirtyFiles.length > 0) {
253
+ configDirtySkipped += 1;
254
+ const message = buildConfigDirtyMessage(agent, dirtyFiles);
255
+ results.push({
256
+ agent,
257
+ outcome: 'config-dirty-skipped',
258
+ detail: message,
259
+ });
260
+ deps.onEvent?.({ kind: 'config-dirty-skip', agent, files: dirtyFiles, message });
261
+ continue;
262
+ }
263
+ }
99
264
  let busy = await deps.driver.isBusy(agent);
100
265
  let waited = false;
101
266
  if (busy && opts.wait) {
@@ -108,9 +273,16 @@ export async function rollFleet(plans, opts, deps) {
108
273
  deps.onEvent?.({ kind: 'busy-skip', agent, waited });
109
274
  continue;
110
275
  }
276
+ // --- ENTERING THE TRANSACTION: upgrade + restart run together, always. ---
111
277
  deps.onEvent?.({ kind: 'roll-start', agent, from: plan.runningVersion, to: opts.targetVersion });
112
278
  await deps.driver.upgrade(agent);
113
- await deps.driver.restart(agent);
279
+ // The pre-flight gate above (clean, or explicitly `--force`-bypassed) is
280
+ // the only thing that decided whether to enter this transaction. Once
281
+ // entered, `restart` must NOT stash or refuse on the config surface —
282
+ // `upgrade` (macf update) is EXPECTED to have just dirtied it, and that
283
+ // dirt (plus any pre-existing `--force`-bypassed dirt) is deliberately
284
+ // LEFT UNCOMMITTED for the relaunched agent to see via `git status`.
285
+ await deps.driver.restart(agent, { leaveConfigUncommitted: true });
114
286
  const green = await deps.verifyGreen({
115
287
  agent,
116
288
  targetVersion: opts.targetVersion,
@@ -118,27 +290,33 @@ export async function rollFleet(plans, opts, deps) {
118
290
  });
119
291
  if (green.ok) {
120
292
  upgraded += 1;
121
- results.push({ agent, outcome: 'upgraded', detail: green.version });
122
- deps.onEvent?.({ kind: 'upgraded', agent, version: green.version });
293
+ const modifiedFiles = await deps.driver.listModifiedFiles(agent);
294
+ const message = buildModifiedFilesMessage(agent, modifiedFiles);
295
+ results.push({ agent, outcome: 'upgraded', detail: message });
296
+ deps.onEvent?.({ kind: 'upgraded', agent, version: green.version, modifiedFiles, message });
123
297
  continue;
124
298
  }
125
- const reason = green.reason;
299
+ const reason = classifyHalt(green, plan.runningVersion);
126
300
  results.push({
127
301
  agent,
128
302
  outcome: 'halted',
129
- detail: `verify-green ${reason} (last=${green.lastVersion ?? 'down'})`,
303
+ reason,
304
+ detail: `${reason}: verify-green ${green.reason} (last=${green.lastVersion ?? 'down'})`,
130
305
  });
131
306
  deps.onEvent?.({ kind: 'halt', agent, reason, lastVersion: green.lastVersion });
132
- return { results, halted: true, upgraded, busySkipped };
307
+ return { results, halted: true, upgraded, busySkipped, configDirtySkipped };
133
308
  }
134
- return { results, halted: false, upgraded, busySkipped };
309
+ return { results, halted: false, upgraded, busySkipped, configDirtySkipped };
135
310
  }
136
311
  /**
137
- * Orchestrate a rolling upgrade across the ORDERED `fleets` (registry
138
- * identifiers), fleet-by-fleet. Each fleet is probed + planned; in EXECUTE mode
139
- * it is then rolled, and a HALT in one fleet STOPS the whole run — later fleets
140
- * are never started (a bad release cannot cascade across fleets). An unresolvable
141
- * fleet is skipped + reported and does NOT halt the run.
312
+ * Orchestrate a rolling upgrade across the ORDERED `fleets` (PROJECT
313
+ * identifiers — macf#710: a "fleet" == a project, which owns its own CA +
314
+ * registry namespace + version cadence; a profile/org registry scope hosting N
315
+ * projects yields N fleets here, never one), fleet-by-fleet. Each fleet is
316
+ * probed + planned; in EXECUTE mode it is then rolled, and a HALT in one fleet
317
+ * STOPS the whole run — later fleets are never started (a bad release cannot
318
+ * cascade across fleets). An unresolvable fleet is skipped + reported and does
319
+ * NOT halt the run.
142
320
  */
143
321
  export async function upgradeFleets(fleets, opts, deps) {
144
322
  const reports = [];
@@ -150,7 +328,7 @@ export async function upgradeFleets(fleets, opts, deps) {
150
328
  deps.onEvent?.({ kind: 'fleet-skipped', fleet, reason: 'driver-unresolved' });
151
329
  continue;
152
330
  }
153
- const members = driver.discoverWorkspaces().filter((r) => r.registry === fleet);
331
+ const members = driver.discoverWorkspaces().filter((r) => r.project === fleet);
154
332
  const state = await driver.probe();
155
333
  const plans = planFleetUpgrade(members, state, opts.targetVersion);
156
334
  const behind = plans.filter((p) => p.disposition === 'behind').length;
@@ -1 +1 @@
1
- {"version":3,"file":"fleet-upgrade.js","sourceRoot":"","sources":["../src/fleet-upgrade.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fleet-upgrade.js","sourceRoot":"","sources":["../src/fleet-upgrade.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAmF5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,YAAY;IACZ,WAAW;IACX,WAAW;IACX,aAAa;CACL,CAAC;AAwCX;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAAmC,EACnC,KAAiB,EACjB,aAAqB;IAErB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACjC,MAAM,cAAc,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACpE,IAAI,WAA+B,CAAC;QACpC,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC5B,WAAW,GAAG,SAAS,CAAC;QAC1B,CAAC;aAAM,IAAI,aAAa,CAAC,cAAc,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,WAAW,GAAG,WAAW,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,WAAW,GAAG,QAAQ,CAAC;QACzB,CAAC;QACD,OAAO;YACL,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,CAAC,CAAC,OAAO;YAChB,cAAc;YACd,aAAa,EAAE,CAAC,CAAC,UAAU;YAC3B,WAAW;SACZ,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AA4CD,sEAAsE;AACtE,MAAM,CAAC,MAAM,uBAAuB,GAAG,OAAO,CAAC;AAC/C,8CAA8C;AAC9C,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC;AAE1C;;;;;GAKG;AACH,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,IAAsB,EAAE,IAAmB;IACnF,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,IAAI,uBAAuB,CAAC;IAC7D,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,oBAAoB,CAAC;IACrD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,KAAiD,EAAE,UAAyB;IAChG,IACE,KAAK,CAAC,MAAM,KAAK,eAAe;QAChC,KAAK,CAAC,WAAW,KAAK,IAAI;QAC1B,UAAU,KAAK,IAAI;QACnB,aAAa,CAAC,KAAK,CAAC,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,EAClD,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC;IACD,OAAO,sBAAsB,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAa,EAAE,KAAwB;IAC7E,OAAO,CACL,yBAAyB,KAAK,0CAA0C;QACxE,oCAAoC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB;QACzE,4DAA4D,CAC7D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAa,EAAE,KAAwB;IAC/E,OAAO,CACL,4CAA4C,KAAK,gBAAgB;QACjE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,0DAA0D;QAC7E,6EAA6E,CAC9E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAkC,EAClC,IAAsB,EACtB,IAAmB;IAEnB,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,WAAW,KAAK,QAAQ;YAAE,SAAS;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAEzB,kEAAkE;QAClE,2EAA2E;QAC3E,wDAAwD;QACxD,iEAAiE;QACjE,+DAA+D;QAC/D,4EAA4E;QAC5E,0EAA0E;QAC1E,qEAAqE;QACrE,2EAA2E;QAC3E,0EAA0E;QAC1E,2EAA2E;QAC3E,uEAAuE;QACvE,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;YAC5D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,kBAAkB,IAAI,CAAC,CAAC;gBACxB,MAAM,OAAO,GAAG,uBAAuB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBAC3D,OAAO,CAAC,IAAI,CAAC;oBACX,KAAK;oBACL,OAAO,EAAE,sBAAsB;oBAC/B,MAAM,EAAE,OAAO;iBAChB,CAAC,CAAC;gBACH,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;gBACjF,SAAS;YACX,CAAC;QACH,CAAC;QAED,IAAI,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC;YACd,IAAI,GAAG,CAAC,CAAC,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,IAAI,EAAE,CAAC;YACT,WAAW,IAAI,CAAC,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;YACtG,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACrD,SAAS;QACX,CAAC;QAED,4EAA4E;QAC5E,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;QACjG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACjC,yEAAyE;QACzE,sEAAsE;QACtE,sEAAsE;QACtE,wEAAwE;QACxE,uEAAuE;QACvE,qEAAqE;QACrE,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC;YACnC,KAAK;YACL,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,SAAS,EAAE,IAAI,CAAC,eAAe;SAChC,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;YACb,QAAQ,IAAI,CAAC,CAAC;YACd,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACjE,MAAM,OAAO,GAAG,yBAAyB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9D,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5F,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC;YACX,KAAK;YACL,OAAO,EAAE,QAAQ;YACjB,MAAM;YACN,MAAM,EAAE,GAAG,MAAM,kBAAkB,KAAK,CAAC,MAAM,UAAU,KAAK,CAAC,WAAW,IAAI,MAAM,GAAG;SACxF,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAChF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;IAC9E,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC;AAC/E,CAAC;AA0CD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAyB,EACzB,IAA0B,EAC1B,IAAuB;IAEvB,MAAM,OAAO,GAAsB,EAAE,CAAC;IACtC,IAAI,MAAM,GAAG,KAAK,CAAC;IAEnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;YAC9E,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,kBAAkB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC;QAC/E,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAE5E,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE;YAC1C,MAAM;YACN,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;SACtB,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACvC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,CAAC,kEAAkE;QAC3E,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACjE,CAAC"}