session-orchestrator 3.21.0 → 3.23.0
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor/commands/autopilot-multi.md +14 -0
- package/.cursor/commands/autopilot.md +14 -0
- package/.cursor/commands/bootstrap.md +14 -0
- package/.cursor/commands/brainstorm.md +14 -0
- package/.cursor/commands/close.md +13 -0
- package/.cursor/commands/contract-version-bump.md +14 -0
- package/.cursor/commands/debug.md +14 -0
- package/.cursor/commands/discovery.md +14 -0
- package/.cursor/commands/dispatcher.md +14 -0
- package/.cursor/commands/eli5.md +14 -0
- package/.cursor/commands/eval.md +14 -0
- package/.cursor/commands/evolve.md +14 -0
- package/.cursor/commands/go.md +14 -0
- package/.cursor/commands/grill.md +14 -0
- package/.cursor/commands/harness-audit.md +13 -0
- package/.cursor/commands/journey-audit.md +14 -0
- package/.cursor/commands/memory-cleanup.md +14 -0
- package/.cursor/commands/persona-panel.md +14 -0
- package/.cursor/commands/plan.md +14 -0
- package/.cursor/commands/portfolio.md +14 -0
- package/.cursor/commands/reconcile.md +14 -0
- package/.cursor/commands/release.md +14 -0
- package/.cursor/commands/repo-audit.md +13 -0
- package/.cursor/commands/session.md +14 -0
- package/.cursor/commands/spinout.md +14 -0
- package/.cursor/commands/sunset-review.md +14 -0
- package/.cursor/commands/templates-ack.md +14 -0
- package/.cursor/commands/test.md +14 -0
- package/.cursor/hooks.json +60 -0
- package/.cursor/rules/000-session-orchestrator.mdc +11 -2
- package/.cursor/rules/010-session-workflow.mdc +9 -1
- package/.cursor/rules/020-quality-gates.mdc +1 -1
- package/.cursor/rules/030-wave-execution.mdc +1 -1
- package/.cursor/rules/040-discovery.mdc +6 -6
- package/.cursor/rules/050-plan.mdc +10 -10
- package/.cursor/rules/070-gitlab-ops.mdc +73 -57
- package/.cursor/rules/080-ecosystem-health.mdc +7 -7
- package/.cursor/skills/architecture/SKILL.md +13 -0
- package/.cursor/skills/autopilot/SKILL.md +12 -0
- package/.cursor/skills/bootstrap/SKILL.md +12 -0
- package/.cursor/skills/brainstorm/SKILL.md +13 -0
- package/.cursor/skills/claude-md-drift-check/SKILL.md +13 -0
- package/.cursor/skills/contract-version-bump/SKILL.md +12 -0
- package/.cursor/skills/convergence-monitoring/SKILL.md +12 -0
- package/.cursor/skills/daily/SKILL.md +12 -0
- package/.cursor/skills/debug/SKILL.md +13 -0
- package/.cursor/skills/discovery/SKILL.md +13 -0
- package/.cursor/skills/dispatcher/SKILL.md +13 -0
- package/.cursor/skills/docs-orchestrator/SKILL.md +13 -0
- package/.cursor/skills/domain-model/SKILL.md +13 -0
- package/.cursor/skills/ecosystem-health/SKILL.md +13 -0
- package/.cursor/skills/eli5/SKILL.md +13 -0
- package/.cursor/skills/eval/SKILL.md +12 -0
- package/.cursor/skills/evolve/SKILL.md +13 -0
- package/.cursor/skills/frontmatter-guard/SKILL.md +13 -0
- package/.cursor/skills/gitlab-ops/SKILL.md +13 -0
- package/.cursor/skills/gitlab-portfolio/SKILL.md +13 -0
- package/.cursor/skills/grill/SKILL.md +13 -0
- package/.cursor/skills/hook-development/SKILL.md +13 -0
- package/.cursor/skills/journey-audit/SKILL.md +13 -0
- package/.cursor/skills/mcp-builder/SKILL.md +13 -0
- package/.cursor/skills/memory-cleanup/SKILL.md +12 -0
- package/.cursor/skills/mode-selector/SKILL.md +13 -0
- package/.cursor/skills/npm-publish/SKILL.md +12 -0
- package/.cursor/skills/peekaboo-driver/SKILL.md +13 -0
- package/.cursor/skills/persona-panel/SKILL.md +12 -0
- package/.cursor/skills/plan/SKILL.md +13 -0
- package/.cursor/skills/playwright-driver/SKILL.md +13 -0
- package/.cursor/skills/quality-gates/SKILL.md +13 -0
- package/.cursor/skills/reconcile/SKILL.md +12 -0
- package/.cursor/skills/repo-audit/SKILL.md +13 -0
- package/.cursor/skills/session-end/SKILL.md +13 -0
- package/.cursor/skills/session-plan/SKILL.md +13 -0
- package/.cursor/skills/session-start/SKILL.md +13 -0
- package/.cursor/skills/skill-creator/SKILL.md +13 -0
- package/.cursor/skills/spinout/SKILL.md +12 -0
- package/.cursor/skills/sunset-review/SKILL.md +13 -0
- package/.cursor/skills/test-runner/SKILL.md +13 -0
- package/.cursor/skills/tmux-layout/SKILL.md +13 -0
- package/.cursor/skills/ubiquitous-language/SKILL.md +13 -0
- package/.cursor/skills/using-orchestrator/SKILL.md +13 -0
- package/.cursor/skills/vault-mirror/SKILL.md +13 -0
- package/.cursor/skills/vault-sync/SKILL.md +13 -0
- package/.cursor/skills/wave-executor/SKILL.md +13 -0
- package/.cursor/skills/write-executable-plan/SKILL.md +13 -0
- package/.mcp.json +4 -1
- package/CHANGELOG.md +269 -0
- package/README.md +18 -15
- package/agents/AGENTS.md +23 -4
- package/agents/code-implementer.md +2 -1
- package/agents/db-specialist.md +2 -1
- package/agents/docs-writer.md +3 -1
- package/agents/eval-judge.md +1 -1
- package/agents/memory-proposal-collector.md +6 -4
- package/agents/session-reviewer.md +7 -1
- package/agents/test-writer.md +2 -1
- package/agents/ui-developer.md +2 -1
- package/commands/bootstrap.md +2 -2
- package/commands/close.md +3 -1
- package/commands/eli5.md +33 -0
- package/commands/go.md +1 -1
- package/commands/journey-audit.md +43 -0
- package/commands/release.md +5 -3
- package/commands/test.md +2 -2
- package/docs/USER-GUIDE.md +2 -2
- package/docs/ci-setup.md +14 -0
- package/docs/codex-setup.md +64 -0
- package/docs/components.md +7 -6
- package/docs/cursor-setup.md +26 -47
- package/docs/events-schema.md +76 -4
- package/docs/github-mirror-protection.md +197 -0
- package/docs/pi-setup.md +2 -0
- package/docs/rule-authoring.md +3 -1
- package/docs/scope-collision-guard.md +52 -5
- package/docs/session-config-reference.md +57 -12
- package/docs/session-config-template.md +4 -3
- package/docs/telemetry.md +22 -0
- package/hooks/_lib/lock-bootstrap.mjs +26 -16
- package/hooks/_lib/vcs-create-matcher.mjs +397 -38
- package/hooks/enforce-scope.mjs +64 -0
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +201 -20
- package/hooks/hooks-pi.json +1 -1
- package/hooks/hooks.json +12 -2
- package/hooks/on-session-end.mjs +237 -104
- package/hooks/on-session-start.mjs +404 -110
- package/hooks/on-stop.mjs +48 -9
- package/hooks/post-subagent-discovery-validator.mjs +34 -3
- package/hooks/post-tool-batch-wave-signal.mjs +11 -2
- package/hooks/pre-auq-clarity.mjs +787 -0
- package/hooks/pre-bash-issue-budget.mjs +133 -21
- package/hooks/pre-bash-sessions-ledger-guard.mjs +159 -0
- package/hooks/pre-bash-staging-fence.mjs +4 -0
- package/hooks/pre-task-scope-disjoint.mjs +368 -35
- package/hooks/skill-invocation-telemetry.mjs +21 -10
- package/monitors/monitors.json +6 -0
- package/package.json +3 -1
- package/pi/prompts/eli5.md +12 -0
- package/pi/prompts/journey-audit.md +12 -0
- package/rules/_index.md +9 -1
- package/rules/always-on/ask-via-tool.md +62 -0
- package/rules/always-on/bash-harness-pitfalls.md +168 -0
- package/rules/always-on/build-value.md +47 -0
- package/rules/always-on/cross-session-messaging.md +59 -0
- package/rules/always-on/loop-and-monitor.md +221 -0
- package/rules/always-on/parallel-sessions.md +142 -12
- package/rules/always-on/receiving-review.md +108 -0
- package/rules/always-on/test-value.md +40 -0
- package/rules/always-on/verification-before-completion.md +77 -0
- package/scripts/archive-closed-prds.mjs +258 -18
- package/scripts/auq-audit.mjs +825 -0
- package/scripts/autopilot.mjs +12 -8
- package/scripts/backfill-evidence-digest.mjs +376 -0
- package/scripts/cursor-install.mjs +89 -48
- package/scripts/export-hw-learnings.mjs +143 -2
- package/scripts/express-path.mjs +299 -0
- package/scripts/generate-cursor-adapter.mjs +253 -0
- package/scripts/github-protection-audit.mjs +358 -0
- package/scripts/lib/auq/clarity.mjs +1314 -0
- package/scripts/lib/auq/parse.mjs +1006 -0
- package/scripts/lib/auq/schema.mjs +1457 -0
- package/scripts/lib/autopilot/worktree-pipeline.mjs +240 -16
- package/scripts/lib/build-live-signals.mjs +24 -5
- package/scripts/lib/ci-status-banner.mjs +221 -68
- package/scripts/lib/command-blocker.mjs +70 -0
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +32 -9
- package/scripts/lib/config/reconcile.mjs +79 -4
- package/scripts/lib/config/section-extractor.mjs +235 -36
- package/scripts/lib/config/vault-integration.mjs +12 -1
- package/scripts/lib/config-schema.mjs +9 -1
- package/scripts/lib/config.mjs +57 -6
- package/scripts/lib/convergence-monitor.mjs +13 -2
- package/scripts/lib/cursor-hook-bridge.mjs +443 -0
- package/scripts/lib/dispatcher/cli.mjs +2 -2
- package/scripts/lib/dispatcher/rank.mjs +4 -7
- package/scripts/lib/express-path.mjs +327 -0
- package/scripts/lib/file-lock.mjs +22 -4
- package/scripts/lib/gates/gate-full.mjs +84 -11
- package/scripts/lib/gates/gate-helpers.mjs +93 -21
- package/scripts/lib/git-config-drift.mjs +134 -5
- package/scripts/lib/host-identity.mjs +247 -2
- package/scripts/lib/instruction-budget-guard.mjs +31 -1
- package/scripts/lib/io.mjs +239 -0
- package/scripts/lib/issue-budget.mjs +284 -31
- package/scripts/lib/learnings/io.mjs +55 -10
- package/scripts/lib/learnings/schema.mjs +95 -28
- package/scripts/lib/lock-reaper.mjs +7 -1
- package/scripts/lib/locks/staging-fence-lock.mjs +5 -1
- package/scripts/lib/locks/state-md-lock.mjs +8 -1
- package/scripts/lib/memory-banner.mjs +5 -2
- package/scripts/lib/memory-paths.mjs +15 -6
- package/scripts/lib/mode-selector/scoring.mjs +53 -6
- package/scripts/lib/owner-interview.mjs +78 -32
- package/scripts/lib/peer-discovery.mjs +73 -22
- package/scripts/lib/platform.mjs +72 -9
- package/scripts/lib/plugin-root.mjs +143 -19
- package/scripts/lib/project-hygiene.mjs +104 -4
- package/scripts/lib/quality-gate.mjs +271 -13
- package/scripts/lib/reconcile/emitter.mjs +87 -19
- package/scripts/lib/reconcile/engine.mjs +281 -13
- package/scripts/lib/reconcile/idempotency.mjs +102 -1
- package/scripts/lib/reconcile/renderer.mjs +165 -7
- package/scripts/lib/reconcile/sanitize.mjs +40 -17
- package/scripts/lib/reconcile/writer.mjs +415 -84
- package/scripts/lib/resource-probe/evaluate.mjs +330 -149
- package/scripts/lib/resource-probe/probe-platform.mjs +35 -0
- package/scripts/lib/resource-probe.mjs +18 -2
- package/scripts/lib/rule-loader.mjs +37 -2
- package/scripts/lib/rules-sync.mjs +51 -8
- package/scripts/lib/scope-gate.mjs +90 -0
- package/scripts/lib/session-close-backfill.mjs +369 -28
- package/scripts/lib/session-discovery.mjs +13 -3
- package/scripts/lib/session-end/phase-skip.mjs +37 -4
- package/scripts/lib/session-end/worktree-cleanup.mjs +154 -7
- package/scripts/lib/session-id.mjs +30 -14
- package/scripts/lib/session-identity/own-session.mjs +159 -0
- package/scripts/lib/session-lock.mjs +85 -30
- package/scripts/lib/session-schema/normalizer.mjs +70 -3
- package/scripts/lib/session-schema/validator.mjs +40 -0
- package/scripts/lib/session-start-probes.mjs +608 -0
- package/scripts/lib/session-transition.mjs +277 -0
- package/scripts/lib/sessions-staleness-banner.mjs +124 -57
- package/scripts/lib/spiral-carryover.mjs +111 -9
- package/scripts/lib/state-md/frontmatter-mutators.mjs +41 -8
- package/scripts/lib/state-md/mission-status.mjs +467 -72
- package/scripts/lib/state-md/yaml-parser.mjs +145 -16
- package/scripts/lib/state-md.mjs +12 -2
- package/scripts/lib/telemetry/sync.mjs +46 -8
- package/scripts/lib/validate/check-agents.mjs +66 -0
- package/scripts/lib/validate/check-auq-clarity.mjs +274 -0
- package/scripts/lib/validate/check-cursor-adapter.mjs +102 -0
- package/scripts/lib/validate/check-dead-bridge.mjs +24 -2
- package/scripts/lib/validate/check-doc-cli-commands.mjs +16 -32
- package/scripts/lib/validate/check-hooks-symmetry.mjs +59 -63
- package/scripts/lib/validate/check-playwright-mcp-canary.mjs +13 -22
- package/scripts/lib/validate/check-plugin-monitors.mjs +10 -4
- package/scripts/lib/validate/check-rules.mjs +153 -9
- package/scripts/lib/validate/check-test-value-bans.mjs +165 -17
- package/scripts/lib/validate/check-unwired-features.mjs +340 -32
- package/scripts/lib/validate/repo-files.mjs +275 -0
- package/scripts/lib/validate-vendored-rules.mjs +229 -7
- package/scripts/lib/vault-backfill/glab.mjs +91 -58
- package/scripts/lib/vault-backfill/manifest.mjs +28 -8
- package/scripts/lib/vault-mirror/process.mjs +99 -43
- package/scripts/lib/vault-mirror/telemetry.mjs +210 -0
- package/scripts/lib/vault-staleness-banner.mjs +76 -6
- package/scripts/lib/vault-status/board-writer.mjs +211 -10
- package/scripts/lib/vault-status/narrative-mirror.mjs +188 -8
- package/scripts/lib/vcs-repo-spec.mjs +182 -13
- package/scripts/lib/wave-executor/foreign-dispatch.mjs +832 -0
- package/scripts/lib/wave-resource-gate.mjs +67 -73
- package/scripts/lib/wave-transcript-tail.mjs +869 -0
- package/scripts/materialize-wave-scope.mjs +478 -0
- package/scripts/mcp-server.sh +11 -2
- package/scripts/parse-config.mjs +65 -0
- package/scripts/release.mjs +443 -122
- package/scripts/run-quality-gate.mjs +14 -0
- package/scripts/token-audit.sh +9 -2
- package/scripts/validate-plugin.mjs +6 -0
- package/scripts/validate-wave-scope.mjs +73 -1
- package/scripts/vault-backfill.mjs +32 -5
- package/scripts/vault-mirror.mjs +203 -34
- package/skills/_shared/monitor-patterns.md +31 -5
- package/skills/_shared/parallel-aware-auq.md +31 -25
- package/skills/_shared/parallel-aware-preamble.md +35 -4
- package/skills/_shared/platform-tools.md +11 -5
- package/skills/_shared/state-ownership.md +61 -8
- package/skills/autopilot/SKILL.md +5 -1
- package/skills/bootstrap/SKILL.md +5 -4
- package/skills/bootstrap/_shared-template.md +18 -10
- package/skills/bootstrap/deep-template.md +10 -6
- package/skills/bootstrap/fast-template.md +15 -8
- package/skills/bootstrap/standard-template.md +10 -6
- package/skills/brainstorm/SKILL.md +18 -18
- package/skills/brainstorm/soul.md +12 -0
- package/skills/claude-md-drift-check/checker.mjs +39 -11
- package/skills/discovery/SKILL.md +28 -24
- package/skills/dispatcher/SKILL.md +1 -1
- package/skills/eli5/SKILL.md +43 -0
- package/skills/evolve/SKILL.md +8 -9
- package/skills/gitlab-ops/SKILL.md +30 -26
- package/skills/grill/SKILL.md +6 -6
- package/skills/grill/soul.md +16 -0
- package/skills/journey-audit/SKILL.md +269 -0
- package/skills/memory-cleanup/SKILL.md +2 -2
- package/skills/npm-publish/SKILL.md +4 -4
- package/skills/peekaboo-driver/SKILL.md +18 -6
- package/skills/persona-panel/SKILL.md +1 -1
- package/skills/plan/SKILL.md +18 -16
- package/skills/plan/mode-feature.md +1 -1
- package/skills/plan/mode-new.md +35 -23
- package/skills/plan/soul.md +12 -0
- package/skills/reconcile/SKILL.md +44 -4
- package/skills/session-end/SKILL.md +70 -24
- package/skills/session-end/metrics-collection.md +7 -4
- package/skills/session-end/phase-3-6-tail.md +48 -5
- package/skills/session-end/phase-3-7a-recommendations.md +16 -2
- package/skills/session-plan/SKILL.md +6 -1
- package/skills/session-plan/wave-template.md +1 -0
- package/skills/session-start/SKILL.md +96 -48
- package/skills/session-start/phase-2-5-docs-planning.md +8 -8
- package/skills/session-start/phase-4-5-resource-health.md +82 -19
- package/skills/session-start/phase-7-5-mode-selector.md +15 -3
- package/skills/session-start/phase-8-5-express-path.md +77 -12
- package/skills/session-start/soul.md +110 -0
- package/skills/test-runner/SKILL.md +2 -2
- package/skills/using-orchestrator/SKILL.md +1 -1
- package/skills/vault-sync/validator.mjs +31 -0
- package/skills/wave-executor/SKILL.md +4 -2
- package/skills/wave-executor/circuit-breaker.md +34 -9
- package/skills/wave-executor/wave-loop.md +129 -24
- package/skills/write-executable-plan/SKILL.md +6 -6
- package/templates/_shared/journey-manifest.md +110 -0
- package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +0 -8
- package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +0 -8
- package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +0 -8
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +0 -8
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +0 -8
- package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +0 -8
- package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +0 -10
- package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +0 -8
- package/skills/vault-sync/tests/fixtures/clean-vault/README.md +0 -3
- package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +0 -11
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +0 -9
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +0 -8
- package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +0 -7
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +0 -9
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +0 -11
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +0 -3
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +0 -3
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +0 -11
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +0 -11
- package/skills/vault-sync/tests/schema-drift.test.mjs +0 -133
- package/templates/_shared/rules/parallel-sessions.md +0 -77
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Part of v3.1.0 Epic #157, Sub-Epic resource-gate. Issue #193.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { probe } from './resource-probe.mjs';
|
|
10
|
+
import { probe, evaluate } from './resource-probe.mjs';
|
|
11
11
|
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
// Public API
|
|
@@ -30,10 +30,23 @@ async function extractMeasurements(opts) {
|
|
|
30
30
|
ramFreeGb: probeOverride.ramFreeGb,
|
|
31
31
|
// Tests may supply ramAvailableGb to exercise the macOS path; absent → null.
|
|
32
32
|
ramAvailableGb: probeOverride.ramAvailableGb ?? null,
|
|
33
|
+
// macOS memory_pressure — the highest-precedence memory signal (#1089).
|
|
34
|
+
memoryPressurePctFree: probeOverride.memoryPressurePctFree ?? null,
|
|
33
35
|
cpuLoadPct: probeOverride.cpuLoadPct,
|
|
34
36
|
// 5m-average CPU pct (#943); absent → null (legacy overrides → 1m-only judging).
|
|
35
37
|
cpuLoad5mPct: probeOverride.cpuLoad5mPct ?? null,
|
|
38
|
+
// #1089: live peer SESSIONS from the registry — the unit
|
|
39
|
+
// `concurrent-sessions-warn` is named for. Absent → null, and the
|
|
40
|
+
// rescaled process-count fallback applies.
|
|
41
|
+
peerSessions: probeOverride.peerSessions ?? null,
|
|
42
|
+
// Raw Claude PROCESS count. Historically (and misleadingly) named
|
|
43
|
+
// `concurrentSessions` on this override object; kept as an accepted alias
|
|
44
|
+
// so existing callers keep working, but it is compared against a
|
|
45
|
+
// process-denominated threshold now, never a session-denominated one.
|
|
46
|
+
claudeProcesses: probeOverride.claudeProcesses ?? probeOverride.concurrentSessions ?? null,
|
|
36
47
|
concurrentSessions: probeOverride.concurrentSessions,
|
|
48
|
+
swapUsedMb: probeOverride.swapUsedMb ?? null,
|
|
49
|
+
zombieProcesses: probeOverride.zombieProcesses ?? null,
|
|
37
50
|
};
|
|
38
51
|
}
|
|
39
52
|
|
|
@@ -48,12 +61,22 @@ async function extractMeasurements(opts) {
|
|
|
48
61
|
// macOS: free + reclaimable (vm_stat). null on Linux/Windows where
|
|
49
62
|
// os.freemem() is already accurate. (#667)
|
|
50
63
|
ramAvailableGb: snapshot.ram_available_gb ?? null,
|
|
64
|
+
// macOS memory_pressure — outranks both of the above (#1089).
|
|
65
|
+
memoryPressurePctFree: snapshot.memory_pressure_pct_free ?? null,
|
|
51
66
|
cpuLoadPct: snapshot.cpu_load_pct,
|
|
52
67
|
// 5m load-average as pct-of-cores (#943). null on Windows/zero-load, where
|
|
53
68
|
// the gate falls back to judging the 1m-derived cpu_load_pct alone.
|
|
54
69
|
cpuLoad5mPct: snapshot.cpu_load_5m_pct ?? null,
|
|
55
|
-
//
|
|
70
|
+
// #1089: live peer SESSIONS (registry, self excluded) — what
|
|
71
|
+
// `concurrent-sessions-warn` was always named for. This line used to read
|
|
72
|
+
// `concurrentSessions: snapshot.claude_processes_count`, a measured 6x unit
|
|
73
|
+
// error that made the gate reduce waves on essentially every dispatch.
|
|
74
|
+
peerSessions: snapshot.peer_sessions_count ?? null,
|
|
75
|
+
claudeProcesses: snapshot.claude_processes_count ?? null,
|
|
76
|
+
// Retained for the returned `measurements` object, which callers log.
|
|
56
77
|
concurrentSessions: snapshot.claude_processes_count ?? 0,
|
|
78
|
+
swapUsedMb: snapshot.swap_used_mb ?? null,
|
|
79
|
+
zombieProcesses: snapshot.zombie_processes_count ?? null,
|
|
57
80
|
};
|
|
58
81
|
}
|
|
59
82
|
|
|
@@ -131,29 +154,32 @@ function applyHeavyRepoCap(result, opts) {
|
|
|
131
154
|
}
|
|
132
155
|
|
|
133
156
|
/**
|
|
134
|
-
*
|
|
135
|
-
* Extracted so `applyDecisionRules` can layer the HR-004 heavy-repo cap on
|
|
136
|
-
* top without duplicating this sequence.
|
|
157
|
+
* Resource-driven decision, delegated to `evaluate()` (#1089).
|
|
137
158
|
*
|
|
138
|
-
*
|
|
159
|
+
* This function used to carry its OWN copy of the RAM/CPU/concurrency rules,
|
|
160
|
+
* running in sequence with first-match-wins. That duplication is exactly why
|
|
161
|
+
* the #667 available-RAM correction only ever landed halfway: it was applied
|
|
162
|
+
* here and in `evaluate()` separately, and the memory_pressure precedence that
|
|
163
|
+
* followed reached only one of the two. There is now one rule engine and this
|
|
164
|
+
* is a translation layer over it.
|
|
165
|
+
*
|
|
166
|
+
* Verdict → decision mapping:
|
|
167
|
+
* critical (hard signal) → coordinator-direct, 0 agents
|
|
168
|
+
* warn (2+ soft signals) → reduce, plannedAgents / 2 (floor 1)
|
|
169
|
+
* green (0-1 soft signals) → proceed at plannedAgents, reasons retained
|
|
170
|
+
*
|
|
171
|
+
* The halving on `warn` is this gate's own policy and deliberately differs
|
|
172
|
+
* from `evaluate()`'s flat cap of 2: the gate knows `plannedAgents` (a wave of
|
|
173
|
+
* 3 should not be "capped" UP to nothing), `evaluate()` does not.
|
|
174
|
+
*
|
|
175
|
+
* @param {object} measurements — from extractMeasurements
|
|
139
176
|
* @param {object} opts - Same opts shape as evaluateWaveResourceGate
|
|
140
177
|
* @returns {{decision: string, agents: number, reasons: string[], measurements: object}}
|
|
141
178
|
*/
|
|
142
179
|
function computeResourceDecision(measurements, opts) {
|
|
143
180
|
const { config, plannedAgents } = opts;
|
|
144
|
-
const { ramFreeGb, ramAvailableGb, cpuLoadPct, cpuLoad5mPct, concurrentSessions } = measurements;
|
|
145
181
|
const T = config['resource-thresholds'];
|
|
146
182
|
|
|
147
|
-
// macOS fix (#667): os.freemem() reports only `Pages free`, which reads
|
|
148
|
-
// sub-1 GB even on a 128 GB host with 80+ GB reclaimable cache — a false
|
|
149
|
-
// RAM-critical that forced spurious coordinator-direct fallbacks. When the
|
|
150
|
-
// probe supplied a numeric `ramAvailableGb` (free + reclaimable, via vm_stat),
|
|
151
|
-
// judge RAM thresholds on AVAILABLE; otherwise fall back to FREE (Linux/Win,
|
|
152
|
-
// where os.freemem() is already accurate).
|
|
153
|
-
const hasAvailable = ramAvailableGb !== null && ramAvailableGb !== undefined;
|
|
154
|
-
const effectiveRamGb = hasAvailable ? ramAvailableGb : ramFreeGb;
|
|
155
|
-
const ramLabel = hasAvailable ? 'RAM available' : 'RAM free';
|
|
156
|
-
|
|
157
183
|
// Rule 3: resource-thresholds missing → degrade to proceed (defensive).
|
|
158
184
|
// Handles legacy pre-#166 configs and test fixtures that omit the key.
|
|
159
185
|
// The gate is considered "ran" — caller receives measurements but no enforcement.
|
|
@@ -166,77 +192,45 @@ function computeResourceDecision(measurements, opts) {
|
|
|
166
192
|
};
|
|
167
193
|
}
|
|
168
194
|
|
|
169
|
-
//
|
|
170
|
-
|
|
195
|
+
// Translate the gate's measurement shape into a probe-shaped snapshot so the
|
|
196
|
+
// single rule engine can judge it. Field names differ because the override
|
|
197
|
+
// object is a documented public test seam that predates the snapshot shape.
|
|
198
|
+
const snapshot = {
|
|
199
|
+
ram_free_gb: measurements.ramFreeGb,
|
|
200
|
+
ram_available_gb: measurements.ramAvailableGb ?? null,
|
|
201
|
+
memory_pressure_pct_free: measurements.memoryPressurePctFree ?? null,
|
|
202
|
+
cpu_load_pct: measurements.cpuLoadPct,
|
|
203
|
+
cpu_load_5m_pct: measurements.cpuLoad5mPct ?? null,
|
|
204
|
+
peer_sessions_count: measurements.peerSessions ?? null,
|
|
205
|
+
claude_processes_count: measurements.claudeProcesses ?? null,
|
|
206
|
+
swap_used_mb: measurements.swapUsedMb ?? null,
|
|
207
|
+
zombie_processes_count: measurements.zombieProcesses ?? null,
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// heavyRepo is applied by applyHeavyRepoCap() on the way out, so it is
|
|
211
|
+
// deliberately NOT passed here — passing it would apply the ceiling twice.
|
|
212
|
+
const verdict = evaluate(snapshot, T);
|
|
213
|
+
|
|
214
|
+
if (verdict.verdict === 'critical') {
|
|
171
215
|
return {
|
|
172
216
|
decision: 'coordinator-direct',
|
|
173
217
|
agents: 0,
|
|
174
|
-
reasons:
|
|
175
|
-
`${ramLabel} ${effectiveRamGb}GB < critical ${T['ram-free-critical-gb']}GB — escalating to coordinator-direct`,
|
|
176
|
-
],
|
|
177
|
-
measurements,
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Rule 5: RAM below min (but above critical) → reduce.
|
|
182
|
-
if (effectiveRamGb < T['ram-free-min-gb']) {
|
|
183
|
-
return {
|
|
184
|
-
decision: 'reduce',
|
|
185
|
-
agents: Math.max(1, Math.floor(plannedAgents / 2)),
|
|
186
|
-
reasons: [
|
|
187
|
-
`${ramLabel} ${effectiveRamGb}GB < min ${T['ram-free-min-gb']}GB — reducing agent count`,
|
|
188
|
-
],
|
|
218
|
+
reasons: verdict.reasons,
|
|
189
219
|
measurements,
|
|
190
220
|
};
|
|
191
221
|
}
|
|
192
|
-
|
|
193
|
-
// Rule 6: CPU overloaded → reduce. #943: this gate runs, by construction,
|
|
194
|
-
// right after the coordinator's own CPU-saturating quality-gate run — the 1m
|
|
195
|
-
// load average still carries that decaying tail (observed 2026-07-30:
|
|
196
|
-
// 96% → 91% → 78% → 75% within 36s), so a 1m-only reading systematically
|
|
197
|
-
// over-reports and halves waves without a real bottleneck. When the probe
|
|
198
|
-
// supplied a numeric 5m percentage, judge on min(1m, 5m): only-1m-high is a
|
|
199
|
-
// decaying transient (informational, no reduce), both-high is genuine
|
|
200
|
-
// sustained load. `cpuLoad5mPct` null (legacy overrides, Windows) → 1m-only.
|
|
201
|
-
const has5mCpu = typeof cpuLoad5mPct === 'number' && Number.isFinite(cpuLoad5mPct);
|
|
202
|
-
const effectiveCpuLoadPct = has5mCpu ? Math.min(cpuLoadPct, cpuLoad5mPct) : cpuLoadPct;
|
|
203
|
-
if (effectiveCpuLoadPct > T['cpu-load-max-pct']) {
|
|
204
|
-
const detail = has5mCpu ? ` (min of 1m ${cpuLoadPct}% / 5m ${cpuLoad5mPct}%)` : '';
|
|
222
|
+
if (verdict.verdict === 'warn') {
|
|
205
223
|
return {
|
|
206
224
|
decision: 'reduce',
|
|
207
225
|
agents: Math.max(1, Math.floor(plannedAgents / 2)),
|
|
208
|
-
reasons:
|
|
209
|
-
`CPU load ${effectiveCpuLoadPct}%${detail} > max ${T['cpu-load-max-pct']}% — reducing agent count`,
|
|
210
|
-
],
|
|
211
|
-
measurements,
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
const cpuTransientNote =
|
|
215
|
-
has5mCpu && cpuLoadPct > T['cpu-load-max-pct']
|
|
216
|
-
? `info: CPU 1m load ${cpuLoadPct}% > max ${T['cpu-load-max-pct']}% but 5m load ${cpuLoad5mPct}% is below — decaying transient (typically the coordinator's own just-finished gate run), not reducing (#943)`
|
|
217
|
-
: null;
|
|
218
|
-
|
|
219
|
-
// Rule 7: concurrent sessions above warn → proceed with warning.
|
|
220
|
-
if (concurrentSessions > T['concurrent-sessions-warn']) {
|
|
221
|
-
return {
|
|
222
|
-
decision: 'proceed',
|
|
223
|
-
agents: plannedAgents,
|
|
224
|
-
reasons: [
|
|
225
|
-
...(cpuTransientNote ? [cpuTransientNote] : []),
|
|
226
|
-
`warn: ${concurrentSessions} concurrent sessions`,
|
|
227
|
-
],
|
|
226
|
+
reasons: verdict.reasons,
|
|
228
227
|
measurements,
|
|
229
228
|
};
|
|
230
229
|
}
|
|
231
|
-
|
|
232
|
-
// Rule 8: all within bounds.
|
|
233
230
|
return {
|
|
234
231
|
decision: 'proceed',
|
|
235
232
|
agents: plannedAgents,
|
|
236
|
-
reasons: [
|
|
237
|
-
...(cpuTransientNote ? [cpuTransientNote] : []),
|
|
238
|
-
'all thresholds within bounds',
|
|
239
|
-
],
|
|
233
|
+
reasons: verdict.reasons.length > 0 ? verdict.reasons : ['all thresholds within bounds'],
|
|
240
234
|
measurements,
|
|
241
235
|
};
|
|
242
236
|
}
|