instar 1.3.389 → 1.3.391
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/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +1 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/InstarWorktreeManager.d.ts +15 -0
- package/dist/core/InstarWorktreeManager.d.ts.map +1 -1
- package/dist/core/InstarWorktreeManager.js +42 -0
- package/dist/core/InstarWorktreeManager.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts +13 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +25 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/ReapGuard.d.ts +10 -0
- package/dist/core/ReapGuard.d.ts.map +1 -1
- package/dist/core/ReapGuard.js +13 -2
- package/dist/core/ReapGuard.js.map +1 -1
- package/dist/core/types.d.ts +5 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/SessionReaper.d.ts +3 -0
- package/dist/monitoring/SessionReaper.d.ts.map +1 -1
- package/dist/monitoring/SessionReaper.js +2 -0
- package/dist/monitoring/SessionReaper.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +19 -19
- package/upgrades/1.3.390.md +50 -0
- package/upgrades/1.3.391.md +49 -0
- package/upgrades/side-effects/agent-data-spotlight-exclusion.md +46 -0
- package/upgrades/side-effects/reaper-stale-commitment-override.md +46 -0
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-07T04:05:00.344Z",
|
|
5
|
+
"instarVersion": "1.3.391",
|
|
6
6
|
"entryCount": 199,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1538,7 +1538,7 @@
|
|
|
1538
1538
|
"type": "subsystem",
|
|
1539
1539
|
"domain": "updates",
|
|
1540
1540
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1541
|
-
"contentHash": "
|
|
1541
|
+
"contentHash": "3e0828b523c2cece3ea4c3c73e77867c2d6884b7493c93e523318e63f5c09e30",
|
|
1542
1542
|
"since": "2025-01-01"
|
|
1543
1543
|
},
|
|
1544
1544
|
"subsystem:scheduler": {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
macOS `mediaanalysisd` (~72-78% of a core) and Spotlight `mds_stores` (~28-48%)
|
|
9
|
+
were top constant CPU consumers on a busy fleet box — pinning it at load average
|
|
10
|
+
30 — because the agent's OWN runtime data dir (`<agentHome>/.instar/`) was never
|
|
11
|
+
excluded from indexing. It holds `telegram-images/` (every user photo, vision-
|
|
12
|
+
analyzed by mediaanalysisd), `server-data/` (SQLite DBs rewritten continuously),
|
|
13
|
+
`logs/`, and `state/`. Instar already excluded `.worktrees/` (#588),
|
|
14
|
+
`node_modules/` (#606), and Claude transcripts (#903); this closes the last gap.
|
|
15
|
+
|
|
16
|
+
New `ensureAgentDataSpotlightExclusion()` helper drops the standard
|
|
17
|
+
`.metadata_never_index` marker in each high-churn subdir + a `PostUpdateMigrator`
|
|
18
|
+
backfill so existing agents get the relief on their next update.
|
|
19
|
+
`.instar/telegram-images/` and `.instar/server-data/` are also gitignored.
|
|
20
|
+
|
|
21
|
+
## What to Tell Your User
|
|
22
|
+
|
|
23
|
+
Nothing required — silent OS-level resource hygiene. If their Mac was running
|
|
24
|
+
hot, part of the cause was macOS endlessly indexing and photo-analyzing the
|
|
25
|
+
agent's own chat images and databases; this stops that going forward.
|
|
26
|
+
|
|
27
|
+
## Summary of New Capabilities
|
|
28
|
+
|
|
29
|
+
- `ensureAgentDataSpotlightExclusion(stateDir)` — drops `.metadata_never_index`
|
|
30
|
+
in the agent's `.instar/{telegram-images,server-data,logs,state}` so macOS
|
|
31
|
+
Spotlight + mediaanalysisd stop indexing the agent's own churning runtime data.
|
|
32
|
+
- `PostUpdateMigrator` backfill — existing agents get the exclusion on their next
|
|
33
|
+
update. Internal OS hygiene; no agent-facing API or config surface.
|
|
34
|
+
|
|
35
|
+
## Evidence
|
|
36
|
+
|
|
37
|
+
Unit + migration tests (both sides of every boundary: marker dropped in each
|
|
38
|
+
existing subdir, only-existing subdirs marked, `[]` for a new agent, idempotent;
|
|
39
|
+
migration backfills/skips/idempotent). 22/22 green in the spotlight-exclusion
|
|
40
|
+
suite. `tsc --noEmit` clean. Mirrors the existing node_modules/worktree/transcript
|
|
41
|
+
exclusion pattern exactly.
|
|
42
|
+
|
|
43
|
+
## Scope (honest)
|
|
44
|
+
|
|
45
|
+
This prevents FUTURE indexing/analysis. It does not instantly drop
|
|
46
|
+
`mediaanalysisd`/`mds_stores` — macOS releases already-indexed content on its own
|
|
47
|
+
schedule; forcing immediate eviction needs a one-time `sudo mdutil -E` the
|
|
48
|
+
operator runs. One of several resource-efficiency fixes (2026-06-06). Does not
|
|
49
|
+
address the ~300 accumulated worktrees (~100GB) — that is the AgentWorktreeReaper,
|
|
50
|
+
gated separately on operator approval.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The idle-session reaper's "never reap a session with an open commitment" safety
|
|
9
|
+
guard is now activity-aware. An open commitment protects a session only while a
|
|
10
|
+
user message arrived within a staleness window (default 24h); past that the
|
|
11
|
+
commitment is treated as abandoned and no longer blocks reaping. Found 2026-06-06
|
|
12
|
+
during a load-avg-30 overload: a reaper dry-run would have reaped NOTHING because
|
|
13
|
+
19 of 26 sessions were pinned by `open-commitment`, many on sessions untouched for
|
|
14
|
+
26h. The unconditional veto was the dominant blocker to idle-session cleanup.
|
|
15
|
+
|
|
16
|
+
New `staleCommitmentWindowMs` on `ReapGuard` (default 24h; `Infinity` = old
|
|
17
|
+
always-protect) + `monitoring.sessionReaper.staleCommitmentWindowMinutes`
|
|
18
|
+
(default 1440), threaded through to the terminate-time authority guard too.
|
|
19
|
+
|
|
20
|
+
## What to Tell Your User
|
|
21
|
+
|
|
22
|
+
Nothing required — internal reaper policy, and the reaper itself remains opt-in.
|
|
23
|
+
For operators turning the reaper on: idle sessions that have an open commitment
|
|
24
|
+
but no user message for 24h+ will now become reap-eligible (they previously stayed
|
|
25
|
+
alive forever). Active sessions and recently-touched sessions are unaffected.
|
|
26
|
+
|
|
27
|
+
## Summary of New Capabilities
|
|
28
|
+
|
|
29
|
+
- `ReapGuard.staleCommitmentWindowMs` — bounds the open-commitment KEEP-guard so a
|
|
30
|
+
stale commitment stops pinning an inactive session. Default 24h; `Infinity`
|
|
31
|
+
restores always-protect.
|
|
32
|
+
- `sessionReaper.staleCommitmentWindowMinutes` config (default 1440). Internal
|
|
33
|
+
reaper policy; no agent-facing API/CLI surface.
|
|
34
|
+
|
|
35
|
+
## Evidence
|
|
36
|
+
|
|
37
|
+
`tests/unit/reap-guard.test.ts` + `tests/unit/session-reaper.test.ts`: both sides
|
|
38
|
+
of the boundary (stale commitment ⇒ falls through to reap-eligible; fresh
|
|
39
|
+
commitment within window ⇒ still keeps; custom window honored; `Infinity` restores
|
|
40
|
+
always-protect; existing open-commitment cases updated to window-aware mocks).
|
|
41
|
+
49/49 green. `tsc --noEmit` clean.
|
|
42
|
+
|
|
43
|
+
## Scope (honest)
|
|
44
|
+
|
|
45
|
+
UNBLOCKS the reaper — it changes which sessions are eligible, it does not by itself
|
|
46
|
+
kill anything (the reaper is opt-in + dry-run-first). Pairs with enabling
|
|
47
|
+
sessionReaper + mcpProcessReaper + SleepController (which ship opt-in and were off
|
|
48
|
+
fleet-wide). Does NOT auto-expire the commitments themselves (separate follow-up);
|
|
49
|
+
it only stops a stale commitment from vetoing a reap.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Side-Effects Review - Agent runtime-data Spotlight exclusion
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `agent-data-spotlight-exclusion`
|
|
4
|
+
**Date:** `2026-06-06`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `not required (Tier 1)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Extends Instar's existing macOS Spotlight exclusion (currently covers `.worktrees/` #588, `node_modules/` #606, and Claude transcripts #903) to the agent's OWN runtime data dir (`<agentHome>/.instar/`). On a box pinned at load average 30 (2026-06-06, Justin's resource investigation), grounding showed the top CPU consumers were `mediaanalysisd` (~72-78% — analyzing the agent's `telegram-images/`) and `mds_stores`/Spotlight (~28-48% — re-indexing the constantly-rewritten `server-data/` SQLite dbs, `logs/`, `state/`). These were the remaining unexcluded churn source. Adds `ensureAgentDataSpotlightExclusion()` (reuses the generic marker-dropper) + a `PostUpdateMigrator` backfill, and gitignores the two runtime dirs that weren't already ignored.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `ensureAgentDataSpotlightExclusion(stateDir)` (new, exported) — drops `.metadata_never_index` in each existing high-churn subdir (`telegram-images`, `server-data`, `logs`, `state`); returns the list created. Reuses `ensureWorktreeSpotlightExclusion` (the dir-agnostic dropper).
|
|
15
|
+
- `PostUpdateMigrator.migrateAgentDataSpotlightExclusion` (new, private) — runs the helper on every update, pushes an `upgraded`/`errors` entry.
|
|
16
|
+
- Wired into the migrate() sequence right after `migrateClaudeTranscriptSpotlightExclusion`.
|
|
17
|
+
- `.gitignore` — adds `.instar/telegram-images/` and `.instar/server-data/` (per-machine runtime data; `logs/`, `state/`, `telegram-inbound/` were already ignored).
|
|
18
|
+
|
|
19
|
+
## 1. Behavior change / gating
|
|
20
|
+
|
|
21
|
+
NONE that affects message flow, sessions, or any gate. The only effect is writing empty marker files into the agent's own `.instar/` data subdirs, telling macOS Spotlight + mediaanalysisd to stop indexing them. No runtime behavior of the agent changes; instar's own reads of these dirs (TokenLedger, server-data DBs, log tailing) are filesystem reads, unaffected by Spotlight indexing.
|
|
22
|
+
|
|
23
|
+
## 2. Over/under-signal
|
|
24
|
+
|
|
25
|
+
N/A — not a signal/gate. The only "decision" is whether each subdir exists (drop the marker) or not (skip). Both branches are covered by tests.
|
|
26
|
+
|
|
27
|
+
## 3. Blast radius
|
|
28
|
+
|
|
29
|
+
Filesystem only, additive, and scoped ENTIRELY INSIDE the agent's own `<agentHome>/.instar/` — unlike #903 it never reaches outside the agent home. Writes up to four empty marker files. No state mutation, no data migration, no config change. On a non-macOS host the markers are inert. The `.gitignore` additions only prevent committing per-machine runtime data (which was never intended to be committed).
|
|
30
|
+
|
|
31
|
+
## 4. Failure modes
|
|
32
|
+
|
|
33
|
+
The underlying `ensureWorktreeSpotlightExclusion` swallows write errors (`@silent-fallback-ok`) and returns false — a failed marker write just means Spotlight keeps indexing (status quo), and can never block the migration or an update. `existsSync` guards each absent subdir (brand-new agent with no data yet → returns `[]`). No throw path.
|
|
34
|
+
|
|
35
|
+
## 5. Migration parity
|
|
36
|
+
|
|
37
|
+
Covered: the `PostUpdateMigrator` backfill means existing agents get the markers on their next update (fast release cadence drops them within minutes). New agents get them once the subdirs exist. No agent-installed config/hooks/skills/CLAUDE.md change — this is internal OS hygiene with no agent-facing surface, consistent with the precedent (#588/#606/#903 also have no CLAUDE.md template line; they are not capabilities the agent surfaces to a user). No init-path call is needed because the data subdirs don't exist at init time — it would no-op; the migration is the correct single mechanism.
|
|
38
|
+
|
|
39
|
+
## 6. Scope honesty (what this is NOT)
|
|
40
|
+
|
|
41
|
+
- One fix in the resource-efficiency initiative (Justin, 2026-06-06). The marker prevents FUTURE indexing/analysis; it does NOT instantly drop `mediaanalysisd`/`mds_stores` — macOS releases already-indexed content on its own schedule, and an immediate purge needs a one-time `sudo mdutil -E` the operator runs (instar cannot run sudo). The durable guarantee is that no agent keeps feeding the churn.
|
|
42
|
+
- Does NOT address the ~300 accumulated worktrees (~100GB) — that is the AgentWorktreeReaper's job, gated separately on operator approval because it deletes checkouts.
|
|
43
|
+
|
|
44
|
+
## 7. Causal autopsy
|
|
45
|
+
|
|
46
|
+
Origin: **latent** (not a prior-PR regression). The agent's `.instar/` runtime data (images, DBs, logs, state) has been indexed by macOS since agents began writing it. The prior Spotlight-exclusion PRs (#588 worktrees, #606 node_modules, #903 transcripts) progressively closed the largest known trees but never extended to the agent's own data dir — which 2026-06-06 grounding (`ps`/`uptime` census during the load-30 incident) showed was the live `mediaanalysisd` + `mds_stores` fuel via `telegram-images/` and `server-data/`. This PR closes that latent gap by reusing the same marker mechanism. No behavior was broken by a prior change; an existing cost was simply never excluded.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Side-Effects Review - Reaper stale-commitment override
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `reaper-stale-commitment-override`
|
|
4
|
+
**Date:** `2026-06-06`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `not required (Tier 1)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
The `ReapGuard` open-commitment KEEP-guard now protects a session only while a user message arrived within a staleness window (`staleCommitmentWindowMs`, default 24h). Past that window the open commitment is treated as abandoned and no longer vetoes reaping. Surfaced because a 2026-06-06 dry-run (during a load-avg-30 overload investigation) showed the idle-session reaper would reap NOTHING — 19 of 26 sessions were pinned by `open-commitment`, many on sessions the user hadn't touched in 26h. Adds `staleCommitmentWindowMs` to `ReapGuardOptions` (+ `DEFAULT_REAP_GUARD_OPTIONS`), `staleCommitmentWindowMinutes` to `SessionReaperConfig` + `ConfigDefaults` + the `InstarConfig` type, threaded `SessionReaper`→`ReapGuard`.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `ReapGuard.evaluate()` guard J (open-commitment): now gated on `recentUserMessage(topicId, staleCommitmentWindowMs)`. Fresh ⇒ keep('open-commitment'); stale ⇒ fall through to the activeness guards (unchanged).
|
|
15
|
+
- `ReapGuardOptions.staleCommitmentWindowMs` (new; default 24h; `Infinity` = old always-protect).
|
|
16
|
+
- `SessionReaperConfig.staleCommitmentWindowMinutes` (new; default 1440) → mapped to ms in the `SessionReaper` constructor's `new ReapGuard(...)`.
|
|
17
|
+
- `ConfigDefaults` + `types.ts` `sessionReaper` block gain `staleCommitmentWindowMinutes`.
|
|
18
|
+
|
|
19
|
+
## 1. Behavior change / gating
|
|
20
|
+
|
|
21
|
+
This is a guard-loosening, in ONE direction only: it makes MORE sessions reap-ELIGIBLE, and only those that are BOTH commitment-pinned AND have had no user message for ≥24h. It never makes a session that was reapable into kept. Every other KEEP-guard (protected, spawn-grace, recovery, pending-injection, relay-lease, recent-user-message, active-subagent, structural-long-work, active-process, main-process) is unchanged and still fires in the same order. A session must STILL clear all remaining activeness guards (and, in the reaper, transcript-growth + positive-idle + confirmObservations) before it is actually reaped — this only removes the stale-commitment veto.
|
|
22
|
+
|
|
23
|
+
## 2. Over/under-signal
|
|
24
|
+
|
|
25
|
+
The risk direction is OVER-reaping a session whose commitment is genuinely active but whose user simply hasn't messaged in 24h. Mitigations: (a) 24h is a long, conservative horizon — Justin's explicit "no message today" intent; (b) the session must additionally have NO active processes, NO active subagent, NO recent transcript growth, and be positively idle to actually reap; (c) `Infinity` disables entirely; (d) the terminate-time authority guard uses the same default so a single chokepoint enforces it. UNDER-signal (failing to reap) is the prior behavior being fixed.
|
|
26
|
+
|
|
27
|
+
## 3. Blast radius
|
|
28
|
+
|
|
29
|
+
Pure in-memory guard logic; no I/O, no new deps (reuses the existing `recentUserMessage` dep with a longer window). Affects only the reap-eligibility decision for commitment-pinned, 24h-silent sessions. Ships behind the sessionReaper (which is itself opt-in + dry-run-first). No API route, no persistent state, no migration of data.
|
|
30
|
+
|
|
31
|
+
## 4. Failure modes
|
|
32
|
+
|
|
33
|
+
`recentUserMessage` throwing is already caught by `blockedReason()`'s try/catch → KEEP ('guard-error'), so a signal failure fails SAFE (never reaps). `staleCommitmentWindowMs` defaults are always present (DEFAULT_REAP_GUARD_OPTIONS / DEFAULT_SESSION_REAPER_CONFIG), so an old config missing the field gets 24h, not 0. `Infinity` is honored (any finite withinMs < Infinity ⇒ a correct mock keeps).
|
|
34
|
+
|
|
35
|
+
## 5. Migration parity
|
|
36
|
+
|
|
37
|
+
`staleCommitmentWindowMinutes` is an OPTIONAL config field with a code default (1440) in both `DEFAULT_SESSION_REAPER_CONFIG` and `ConfigDefaults`, so existing agents whose config omits it get the 24h behavior automatically — no `PostUpdateMigrator` entry needed (absence ⇒ default, the established pattern for sessionReaper sub-fields). No agent-installed file (hooks/skills/CLAUDE.md) changes; this is internal reaper policy with no agent-facing surface. The reaper remains opt-in (enabled:false default), so this changes nothing until an operator enables it.
|
|
38
|
+
|
|
39
|
+
## 6. Scope honesty (what this is NOT)
|
|
40
|
+
|
|
41
|
+
- This UNBLOCKS the reaper; it does not by itself reduce a live process count. It changes which sessions are eligible; the reaper (dry-run first, then live) acts on them. It's paired with enabling sessionReaper + mcpProcessReaper + SleepController (which ship opt-in and were off fleet-wide — the 2026-06-06 finding).
|
|
42
|
+
- It does NOT touch the commitments themselves (no auto-expiry of stale commitments — that's a separate follow-up). It only stops a stale commitment from VETOING a reap.
|
|
43
|
+
|
|
44
|
+
## 7. Causal autopsy
|
|
45
|
+
|
|
46
|
+
Origin: **latent**. The open-commitment guard has unconditionally protected commitment-bearing sessions since it was added; that was correct when sessions were short-lived and commitments closed promptly. As the fleet grew to dozens of multi-day sessions with commitments left open, the unconditional veto became the dominant blocker to idle-session reaping (grounded 2026-06-06: 19/26 keeps were open-commitment, many 26h-idle). No prior PR regressed it; an always-on protection simply never had a staleness bound. This adds the bound.
|