@matt82198/aesop 0.1.0-beta.3 → 0.1.0-beta.4

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.
Files changed (108) hide show
  1. package/CHANGELOG.md +37 -94
  2. package/CLAUDE-TEMPLATE.md +115 -0
  3. package/README.md +89 -264
  4. package/aesop.config.example.json +27 -26
  5. package/bin/CLAUDE.md +39 -0
  6. package/bin/cli.js +368 -24
  7. package/daemons/CLAUDE.md +33 -0
  8. package/daemons/backup-fleet.sh +92 -21
  9. package/daemons/run-watchdog.sh +90 -10
  10. package/dash/CLAUDE.md +32 -0
  11. package/dash/dash-extra.mjs +194 -21
  12. package/dash/watchdog-gui.sh +23 -6
  13. package/docs/BEHAVIORAL-PR-REVIEW.md +86 -0
  14. package/docs/CHECKPOINTING.md +100 -0
  15. package/docs/DISPATCH-MODEL.md +11 -7
  16. package/docs/FORENSICS.md +204 -0
  17. package/docs/GOVERNANCE.md +4 -2
  18. package/docs/HOOK-INSTALL.md +307 -0
  19. package/docs/HOW-THE-LOOP-WORKS.md +175 -0
  20. package/docs/MEMORY-TEMPLATE.md +61 -0
  21. package/docs/README.md +44 -0
  22. package/docs/RELIABILITY.md +61 -0
  23. package/docs/RESTORE.md +397 -0
  24. package/docs/SCRIPTS-POLICY.md +97 -0
  25. package/docs/spikes/tiered-cognition/ACTIVATION.md +125 -0
  26. package/docs/spikes/tiered-cognition/DESIGN.md +287 -0
  27. package/docs/spikes/tiered-cognition/FINDINGS.md +113 -0
  28. package/docs/spikes/tiered-cognition/README.md +29 -0
  29. package/docs/spikes/tiered-cognition/aesop-cognition.example.md +32 -0
  30. package/docs/spikes/tiered-cognition/force-model-policy.merged.mjs +673 -0
  31. package/docs/spikes/tiered-cognition/strip-tools-hook.mjs +434 -0
  32. package/hooks/CLAUDE.md +38 -0
  33. package/hooks/claude/force-model-policy.mjs +159 -0
  34. package/hooks/pre-push-policy.sh +753 -0
  35. package/monitor/.signal-state.json +3 -0
  36. package/monitor/ACTIONS.log +1 -0
  37. package/monitor/BRIEF.md +24 -0
  38. package/monitor/CHARTER.md +29 -8
  39. package/monitor/CLAUDE.md +40 -0
  40. package/monitor/SIGNALS.json +54 -0
  41. package/monitor/collect-signals.mjs +529 -62
  42. package/package.json +12 -3
  43. package/skills/CLAUDE.md +3 -0
  44. package/skills/power/SKILL.md +161 -0
  45. package/tools/CLAUDE.md +191 -0
  46. package/tools/__pycache__/buildlog.cpython-314.pyc +0 -0
  47. package/tools/__pycache__/ci_merge_wait.cpython-314.pyc +0 -0
  48. package/tools/__pycache__/ensure_state.cpython-314.pyc +0 -0
  49. package/tools/__pycache__/eod_sweep.cpython-314.pyc +0 -0
  50. package/tools/__pycache__/fleet_ledger.cpython-314.pyc +0 -0
  51. package/tools/__pycache__/heartbeat.cpython-314.pyc +0 -0
  52. package/tools/__pycache__/inbox_drain.cpython-314.pyc +0 -0
  53. package/tools/__pycache__/launch_tui.cpython-314.pyc +0 -0
  54. package/tools/__pycache__/orchestrator_status.cpython-314.pyc +0 -0
  55. package/tools/__pycache__/power_selftest.cpython-314.pyc +0 -0
  56. package/tools/__pycache__/prepublish_scan.cpython-314.pyc +0 -0
  57. package/tools/__pycache__/rotate_logs.cpython-314.pyc +0 -0
  58. package/tools/__pycache__/scanner_selftest.cpython-314.pyc +0 -0
  59. package/tools/__pycache__/secret_scan.cpython-314.pyc +0 -0
  60. package/tools/__pycache__/stall_check.cpython-314.pyc +0 -0
  61. package/tools/__pycache__/verify_dash.cpython-314.pyc +0 -0
  62. package/tools/__pycache__/verify_submit_encoding.cpython-314.pyc +0 -0
  63. package/tools/agent-forensics.sh +186 -0
  64. package/tools/buildlog.py +182 -0
  65. package/tools/ci_merge_wait.py +204 -0
  66. package/tools/ensure_state.py +94 -0
  67. package/tools/eod_sweep.py +239 -0
  68. package/tools/fleet_ledger.py +272 -0
  69. package/tools/heartbeat.py +131 -0
  70. package/tools/inbox_drain.py +249 -0
  71. package/tools/launch_tui.py +51 -3
  72. package/tools/lock.mjs +211 -0
  73. package/tools/metrics_gate.py +205 -0
  74. package/tools/orchestrator_status.py +99 -0
  75. package/tools/power_selftest.py +386 -0
  76. package/tools/prepublish_scan.py +84 -0
  77. package/tools/proposals.mjs +248 -0
  78. package/tools/reconstitute.sh +467 -0
  79. package/tools/rotate_logs.py +228 -0
  80. package/tools/scanner_selftest.py +303 -0
  81. package/tools/secret_scan.py +131 -31
  82. package/tools/stall_check.py +172 -0
  83. package/tools/verify_dash.py +694 -0
  84. package/tools/verify_submit_encoding.py +194 -0
  85. package/ui/CLAUDE.md +109 -0
  86. package/ui/__pycache__/agents.cpython-314.pyc +0 -0
  87. package/ui/__pycache__/collectors.cpython-314.pyc +0 -0
  88. package/ui/__pycache__/config.cpython-314.pyc +0 -0
  89. package/ui/__pycache__/csrf.cpython-314.pyc +0 -0
  90. package/ui/__pycache__/handler.cpython-314.pyc +0 -0
  91. package/ui/__pycache__/render.cpython-314.pyc +0 -0
  92. package/ui/__pycache__/serve.cpython-314.pyc +0 -0
  93. package/ui/__pycache__/sse.cpython-314.pyc +0 -0
  94. package/ui/agents.py +179 -0
  95. package/ui/api/__init__.py +84 -0
  96. package/ui/api/__pycache__/__init__.cpython-314.pyc +0 -0
  97. package/ui/api/__pycache__/submit.cpython-314.pyc +0 -0
  98. package/ui/api/__pycache__/tracker.cpython-314.pyc +0 -0
  99. package/ui/api/submit.py +58 -0
  100. package/ui/api/tracker.py +116 -0
  101. package/ui/collectors.py +586 -0
  102. package/ui/config.py +114 -0
  103. package/ui/csrf.py +140 -0
  104. package/ui/handler.py +426 -0
  105. package/ui/render.py +29 -0
  106. package/ui/serve.py +68 -796
  107. package/ui/sse.py +168 -0
  108. package/ui/templates/dashboard.html +1202 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ "cycleCount": 10
3
+ }
@@ -0,0 +1 @@
1
+ [2026-07-12T13:08:06-05:00] CYCLE 4: clean run (0 stale loops, 0 dirty repos, 0 log rotations, 0 junk quarantined). Security alert proposal stale (0 current alerts); separate triage agent handling. All checks passed.
@@ -0,0 +1,24 @@
1
+ # Aesop Monitor Brief — 2026-07-12T19:11:11.520Z
2
+
3
+ ## Heartbeat check
4
+ ✓ All heartbeats fresh (watchdog 300s, monitor 3600s, others 1800s).
5
+
6
+ ## Git state
7
+ No repos configured.
8
+
9
+ ## Memory
10
+ - 26 memory file(s)
11
+
12
+ ## Log files
13
+ ✓ All logs within thresholds.
14
+
15
+ ## Extended signal checks
16
+ Checks 5 (junk-script sprawl), 6 (stray-repo scripts), 8 (respawn-watch), 10 (unreviewed-prompts) are **extended (off)** — enable via `monitor.extended_signals: true` in aesop.config.json or `AESOP_EXTENDED_SIGNALS=true`.
17
+
18
+ ## Security
19
+ - Alert log: 0 entries, 0 HIGH/MED
20
+
21
+ ## Cost tracking
22
+ - Cycle: 10
23
+
24
+ _Refinement points → act per CHARTER.md (AUTO safe, PROPOSE rule changes). Goal is fixed._
@@ -27,18 +27,18 @@ Each cycle, `collect-signals.mjs` runs these checks and emits `BRIEF.md` + `SIGN
27
27
  default 500 lines / 40 KB). If a log exceeds threshold, emit rotation signal (AUTO tier can
28
28
  invoke rotate_logs.py if available); append rotation summary to BRIEF.md.
29
29
 
30
- 5. **Junk-script sprawl detection** — scan temp/scratch roots for throwaway `.py`/.mjs`/`.js` files
30
+ 5. **Junk-script sprawl detection** *(extended, opt-in via `monitor.extended_signals`)* — scan temp/scratch roots for throwaway `.py`/.mjs`/`.js` files
31
31
  older than 24 hours, not in a live session directory (avoid false-positives during active work).
32
32
  Count total, estimate quarantinable, list oldest. AUTO tier quarantines confirmed junk into
33
33
  `monitor/quarantine/` with manifest.
34
34
 
35
- 6. **Stray scripts in repo roots** — scan recent commits (7d) to detect one-off `.py`/`.mjs`/`.sql`
35
+ 6. **Stray scripts in repo roots** *(extended, opt-in via `monitor.extended_signals`)* — scan recent commits (7d) to detect one-off `.py`/`.mjs`/`.sql`
36
36
  scripts committed directly to repo root (not under proper src/scripts paths). Flag for cleanup.
37
37
 
38
38
  7. **Security alert review loop** — tail SECURITY-ALERTS.log for new HIGH/MED entries (skip suppressed);
39
39
  each new alert noted in BRIEF.md. Monitor agent does semantic review (REAL vs FP) each cycle.
40
40
 
41
- 8. **Respawn watch (Rule 6 retry cap)** — parse agent spawn records; normalize descriptions to
41
+ 8. **Respawn watch (Rule 6 retry cap)** *(extended, opt-in via `monitor.extended_signals`)* — parse agent spawn records; normalize descriptions to
42
42
  prompt-signatures (first ~40 chars, lowercased); count occurrences in recent window (last 50 rows).
43
43
  Flag any signature appearing >3 times as probable hung-agent loop → rule 6 cap breached.
44
44
  Limitation: heuristic may have false positives for intentional similar-task fan-outs.
@@ -46,9 +46,23 @@ Each cycle, `collect-signals.mjs` runs these checks and emits `BRIEF.md` + `SIGN
46
46
  9. **Cost cadence tracking** — every 3rd cycle, harvest agent spawn ledger and append cost tick
47
47
  to COST-LOG.md (cycle count, timestamp, model distribution). Flags non-haiku specializations.
48
48
 
49
- 10. **Unreviewed agent prompts** — run fleet-prompt-extractor.py (if available) to collect NEW
49
+ 10. **Unreviewed agent prompts** *(extended, opt-in via `monitor.extended_signals`)* — run fleet-prompt-extractor.py (if available) to collect NEW
50
50
  spawns since last review; emit count in SIGNALS.json + note in BRIEF.md.
51
51
 
52
+ ## Extended signals (opt-in)
53
+
54
+ Checks 5, 6, 8, and 10 are marked as "extended" — they are disabled by default but can be
55
+ enabled via configuration:
56
+
57
+ - **Config key:** `monitor.extended_signals` (boolean, default: `false`) in aesop.config.json
58
+ - **Env override:** `AESOP_EXTENDED_SIGNALS` (string `'true'` or `'1'` to enable)
59
+ - **Precedence:** env var > config file > default (false)
60
+
61
+ When disabled, extended checks emit `{"skipped": true}` in SIGNALS.json and BRIEF.md notes them
62
+ as "extended (off)". AUTO junk-quarantine action only runs when the junk check is enabled.
63
+ PROPOSE-tier signals for extended checks (respawn-watch-breach, stray-repo-scripts) are only
64
+ emitted when extended_signals is ON.
65
+
52
66
  ## Action tiers
53
67
 
54
68
  - **AUTO (apply immediately, then log to `ACTIONS.log`):**
@@ -56,7 +70,7 @@ Each cycle, `collect-signals.mjs` runs these checks and emits `BRIEF.md` + `SIGN
56
70
  - Log rotation (invoke rotate_logs.py if available; fail-open if not).
57
71
  - Persist heartbeat write (`.monitor-heartbeat` update after cycle).
58
72
  - Quarantine confirmed-junk scripts: move old temp `.py`/`.mjs` (not live session) into
59
- `monitor/quarantine/` with manifest — never delete outright.
73
+ `monitor/quarantine/` with manifest — never delete outright (only when extended_signals is ON).
60
74
 
61
75
  - **PROPOSE (write to `PROPOSALS.md`, do NOT apply — needs user approval):**
62
76
  - Changes to cardinal rules or agent configuration.
@@ -107,10 +121,17 @@ continuations; maintain Windows+POSIX compatibility).
107
121
  ## Single-instance guard
108
122
 
109
123
  Before running, check `.monitor-heartbeat` — if <300s old, skip cycle (another monitor is running).
110
- After cycle completes, update `.monitor-heartbeat` with current epoch.
124
+ After cycle completes, update `.monitor-heartbeat` with current epoch.
125
+ Override with `AESOP_MONITOR_FORCE=true` or `AESOP_MONITOR_FORCE=1` for manual runs or tests (explicit comparison, not truthiness: strings like `'0'` or `'false'` do NOT bypass the guard).
111
126
 
112
- ## Single-writer discipline
127
+ ## Single-writer discipline with atomic operations
113
128
 
114
129
  - Only the monitor edits `BRIEF.md`, `SIGNALS.json`, `ACTIONS.log`, `.monitor-heartbeat`, `.signal-state.json`.
115
- - External processes (human, other agents) write to `PROPOSALS.md` (append or structured inbox).
130
+ - Writes are atomic (temp file + rename) to prevent mid-write corruption if a kill occurs.
131
+ - Rename is retried on EPERM/EBUSY (Windows readers holding file) with exponential backoff; .tmp is cleaned up on final failure; prior file is preserved (degrade gracefully).
132
+ - `PROPOSALS.md` uses atomic operations (mkdir-style lockfile) to prevent race conditions between concurrent appends (emitProposal) and full rewrites (accept/reject).
133
+ - **Both emitProposal and moveProposal (accept/reject) acquire the PROPOSALS.md.lock before read-check-append/write**.
134
+ - Lock contains pid+timestamp for staleness detection (>60s stale locks are reclaimed).
135
+ - Lock is acquired, held during read-modify-write, released after write completes.
136
+ - **Fail-closed (P0 wave-8 fix)**: If lock acquisition fails after timeout (default 30s, configurable via AESOP_LOCK_TIMEOUT_MS env var or config), the operation throws an error instead of proceeding. In emitProposal (monitor context), lock failures skip proposal emission for that cycle and retry next cycle. In proposals.mjs CLI (accept/reject), lock failures exit with error code 1 (caller should retry).
116
137
  - Quarantine manifest is append-only; never edit entries, only add new ones.
@@ -0,0 +1,40 @@
1
+ # monitor/ — Orchestration monitor
2
+
3
+ **Purpose**: Continuous background signal collector and refinement proposer — watches fleet machinery health deterministically (Node.js, no LLM), emits cycle snapshots, and proposes rule changes via append-only PROPOSALS.md; GOAL IS FIXED (improve machinery, never mission).
4
+
5
+ ## Files
6
+
7
+ - **CHARTER.md** — Governance document; defines 10 signal checks (4 of them extended/opt-in), action tiers (AUTO/PROPOSE), outputs, single-instance guard, single-writer discipline. Read-only; behavior changes only via PROPOSALS/behavioral-PR flow.
8
+ - **collect-signals.mjs** — Deterministic signal collector (Node.js built-ins only); emits BRIEF.md + SIGNALS.json each cycle; reads config from env or aesop.config.json.
9
+ - **BRIEF.md** — Human-readable cycle snapshot (heartbeats, git state, memory freshness, log rotation, junk sprawl, stray scripts, security alerts, respawn watch, cost cadence, unreviewed prompts); overwritten each cycle; runtime.
10
+ - **SIGNALS.json** — Machine-readable metrics (same signal keys as BRIEF); JSON; overwritten each cycle; runtime.
11
+ - **PROPOSALS.md** — Structured inbox for user approval (idempotent per signal key, append-only); never edited by monitor after emission; tracks respawn-watch-breach, stray-repo-scripts, security-alerts-high-med, stale-memory-files; gitignored.
12
+ - **ACTIONS.log** — Append-only log of AUTO tier actions taken (heartbeat updates, log rotation invokes, junk quarantine); runtime; gitignored.
13
+ - **.monitor-heartbeat** — Epoch timestamp (line 1) for single-instance liveness check (<300s = skip cycle); runtime; gitignored.
14
+ - **.signal-state.json** — Sidecar state (cycleCount, etc.); runtime; gitignored.
15
+
16
+ ## Contracts
17
+
18
+ **Signal keys collected**: heartbeats, git, memory, logs, junk, strayRepo, alerts, respawnWatch, costTick, unreviewedPrompts. Outputs: BRIEF.md (human), SIGNALS.json (machine); both runtime/gitignored. PROPOSALS.md (tracked, append-only); ACTIONS.log (runtime/gitignored).
19
+
20
+ **Extended signals (opt-in, default OFF)**: checks 5 (junk), 6 (strayRepo), 8 (respawnWatch), and 10 (unreviewedPrompts) are extended — disabled by default.
21
+ - Config key: `monitor.extended_signals` (boolean, default `false`) in aesop.config.json.
22
+ - Env override: `AESOP_EXTENDED_SIGNALS` (`'true'` or `'1'` to enable).
23
+ - Precedence: env var > config file > default (false).
24
+ - When disabled, extended checks emit `{"skipped": true}` in SIGNALS.json and BRIEF.md notes them as "extended (off)"; their dirs are not walked. PROPOSE-tier signals for extended checks (respawn-watch-breach, stray-repo-scripts) are only emitted when extended_signals is ON.
25
+
26
+ **AUTO tier actions** (apply immediately, log to ACTIONS.log): heartbeat checks (read-only); log rotation (invoke rotate_logs.py if available, fail-open); heartbeat write (.monitor-heartbeat update); junk script quarantine (move old temp .py/.mjs to monitor/quarantine/ + manifest — only when extended_signals is ON).
27
+
28
+ **PROPOSE tier actions** (write to PROPOSALS.md, await user approval): rule changes, agent config changes, deletions outside monitor/quarantine/, orchestration policy changes.
29
+
30
+ **Idempotency rule**: Proposal emission keyed on signal key (e.g., 'respawn-watch-breach'); only emitted if not already present in PROPOSALS.md (check: `**Signal:** <key>` exists). Idempotent + append-only; safe to run repeatedly.
31
+
32
+ ## Invariants & Gotchas
33
+
34
+ - CHARTER.md is authority; monitor logic is faithful to it; never edit CHARTER.md or collect-signals.mjs directly — propose via PROPOSALS.md.
35
+ - Goal is FIXED (improve machinery, never mission); if monitor thinks goal should change, it writes note to PROPOSALS.md and stops.
36
+ - Single-instance guard via .monitor-heartbeat; if <300s old, skip cycle.
37
+ - Single-writer discipline: only monitor writes BRIEF.md, SIGNALS.json, ACTIONS.log, .monitor-heartbeat, .signal-state.json.
38
+ - Config from env (AESOP_ROOT, BRAIN_ROOT, SCRIPTS_ROOT, TEMP_ROOT, AESOP_EXTENDED_SIGNALS) or aesop.config.json; falls back to safe defaults.
39
+ - Robust to missing files; treats missing dirs/logs as empty, never crashes.
40
+ - Node.js only (no Python, no LLM, no cloud); deterministic + cheap.
@@ -0,0 +1,54 @@
1
+ {
2
+ "timestamp": "2026-07-12T19:11:11.520Z",
3
+ "cycleCount": 10,
4
+ "heartbeats": {
5
+ "staleCount": 0,
6
+ "details": []
7
+ },
8
+ "git": [],
9
+ "memory": {
10
+ "count": 26,
11
+ "staleMemories": [],
12
+ "staleCount": 0
13
+ },
14
+ "logs": [
15
+ {
16
+ "name": "FLEET-BACKUP.log",
17
+ "exists": true,
18
+ "sizeKb": "1.8",
19
+ "lineCount": 37,
20
+ "needsRotation": false
21
+ },
22
+ {
23
+ "name": "SECURITY-ALERTS.log",
24
+ "exists": false,
25
+ "sizeKb": 0,
26
+ "lineCount": 0,
27
+ "needsRotation": null
28
+ },
29
+ {
30
+ "name": "ACTIONS.log",
31
+ "exists": true,
32
+ "sizeKb": "0.2",
33
+ "lineCount": 1,
34
+ "needsRotation": false
35
+ }
36
+ ],
37
+ "junk": {
38
+ "skipped": true
39
+ },
40
+ "strayRepo": {
41
+ "skipped": true
42
+ },
43
+ "alerts": {
44
+ "count": 0,
45
+ "highMedCount": 0
46
+ },
47
+ "respawnWatch": {
48
+ "skipped": true
49
+ },
50
+ "costTick": null,
51
+ "unreviewedPrompts": {
52
+ "skipped": true
53
+ }
54
+ }