Skip to content

feat: [HIMMEL-654] leg-3 batch — GLM startup watchdog, lane readiness, session telemetry, alert rules, review-freshness gate, PHI fence hardening (8 PRs) - #556

Merged
yotamleo merged 2 commits into
mainfrom
feat/leg3-dispatch-public-ship
Aug 7, 2026
Merged

Conversation

@yotamleo

@yotamleo yotamleo commented Aug 7, 2026

Copy link
Copy Markdown
Owner

HIMMEL-654 leg-3 batch (8 private PRs)

Propagates the 2026-08-07 dispatch-session leg-3 merges (private #1612, #1614–#1620) onto the freshly-merged wave-2k base:

Ticket What lands here
HIMMEL-1575 GLM startup-hang fail-fast: transcript-growth watchdog + failure_class="startup-hang" accounting (GLM_STARTUP_FAILFAST_MINS, 0=off)
HIMMEL-1626 Guard lane-READINESS measured from the verify-return ledger: scripts/lanes/lane-readiness.mjs, lanes.json readiness.passesRequired gates (glm 10 / claudex 5), lane_ready() in the dispatch guard — a ruled-down lane is skipped like a spent bank; fail-open on every probe failure
HIMMEL-1629 cli-proxy-api pin 7.2.115 → 7.2.122 (mechanical fork-drift bump)
HIMMEL-1052 Live session + subagent telemetry: session-runs ledger + hook entrypoint, six exporter families, /sessions.json, war-room Sessions row (exporter stays a pure reader)
HIMMEL-845 Cross-drive X:tail fail-open closed FAIL-CLOSED in both PHI fence twins + lockstep regression tests
HIMMEL-924 Nine alert rules + Telegram delivery (both Prometheus and Grafana-provisioning dialects), HIMMEL-918 coverage invariant, promtool suite
HIMMEL-1181 Review-freshness gate: stale bot review anchor hard-blocks both check-ci modes (exit 4) + the merge gate (rc 2); body-only findings surfaced with counts, never blocking
HIMMEL-1631 Already on public main via the #554 reship — carried as a fail-closed verified --skip-path

Every item passed the private gate (critic panel, per-suite runs, check-ci) and merged to private main today. Public notes: the HIMMEL-1632 hardening batch (from #554's public CR pass) is tracked privately and will follow the same private-first path.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added review-freshness checks to CI and merge validation.
    • Added lane readiness checks before dispatching work.
    • Added session and subagent monitoring, dashboards, and a sessions endpoint.
    • Added Prometheus and Grafana alerts with Telegram notifications.
    • Added startup-hang detection for inactive workers.
  • Bug Fixes

    • Guardrails now safely reject ambiguous Windows cross-drive relative paths.
  • Documentation

    • Updated CI, enforcement, observability, and configuration guidance.

…, session telemetry, alert rules, review-freshness gate, PHI fence hardening (8 PRs)

Batch propagation of the HIMMEL-654 dispatch-session leg-3 merges
(private #1612, #1614-#1620):

- HIMMEL-1575: GLM startup-hang fail-fast — transcript-growth watchdog
  + failure_class accounting (default 10-min window,
  GLM_STARTUP_FAILFAST_MINS).
- HIMMEL-1626: guard lane-READINESS, measured from the verify-return
  flow-runs ledger — lane-readiness.mjs probe, lanes.json
  readiness.passesRequired gates (glm 10, claudex 5), lane_ready() in
  guard-implementor-dispatch (fail-open on probe failure; a clean
  `down` skips the lane like a spent bank).
- HIMMEL-1629: cli-proxy-api pin 7.2.115 -> 7.2.122 (fork-drift).
- HIMMEL-1052: live session + subagent telemetry — session-runs ledger
  + hook, six exporter metric families, /sessions.json, war-room
  Sessions row (passive-reader charter intact).
- HIMMEL-845: cross-drive X:tail fail-open closed FAIL-CLOSED in both
  PHI fence twins (lesson-write-fence, graphify-fence) + regression
  tests.
- HIMMEL-924: nine Grafana/Prometheus alert rules + Telegram delivery
  (D18); HIMMEL-918 coverage invariant; promtool tests + provisioning.
- HIMMEL-1181: review-freshness gate — cr-review-freshness.sh; a stale
  bot review anchor hard-blocks both check-ci modes (exit 4) and the
  merge gate (rc 2); body findings surfaced, never blocking.
- HIMMEL-1631: already public via the #554 reship (test-worker-lifecycle
  ARM_TEMP_CWD_OK shield) — carried as a verified skip-path.

All eight passed the private gate (critic panel + suites + check-ci) and
merged to private main 2026-08-07.
@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The pull request adds CodeRabbit freshness gates, fail-closed Windows path handling, lane readiness checks, session observability and alerting, a GLM startup watchdog, and a CLIProxyAPI update.

Changes

CodeRabbit review gates

Layer / File(s) Summary
Freshness enforcement
scripts/lib/cr-review-freshness.sh, scripts/lib/cr-merge-gate.sh, scripts/check-ci.sh, .claude/commands/*, docs/internals/enforcement.md
CodeRabbit checks validate bot review anchors against the current HEAD. Stale and indeterminate results block. Query failures use fail-open handling.
Freshness validation
scripts/lib/test-cr-merge-gate.sh, scripts/hooks/test-block-unresolved-cr-merge.sh, scripts/test-check-ci.sh
Tests cover fresh, stale, absent, paginated, malformed, custom-login, and failed review responses.

Windows path guardrails

Layer / File(s) Summary
Cross-drive classification
scripts/guardrails/graphify-fence.sh, scripts/guardrails/lesson-write-fence.sh
Drive-relative paths are rejected when their drive differs from, or cannot be proven to match, the working drive.
Regression coverage
scripts/guardrails/test-graphify-fence.sh, scripts/guardrails/test-lesson-write-fence.sh
Tests preserve drive-rooted and same-drive behavior and verify fail-closed cross-drive handling.

Lane readiness routing

Layer / File(s) Summary
Readiness probe and policy
scripts/lanes/lane-readiness.mjs, scripts/lanes/lanes.json, scripts/lanes/tests/lane-readiness.test.mjs
Readiness uses trailing consecutive verify-return PASS records. glm requires 10 passes. claudex requires 5.
Dispatch integration
scripts/hooks/guard-implementor-dispatch.sh, scripts/hooks/test-guard-implementor-dispatch.sh
External lane selection checks runnability, readiness, and funding. Invalid or unavailable readiness evidence fails open.

Session observability and alerting

Layer / File(s) Summary
Session ledger and hook
scripts/observability/session-run-ledger.ts, scripts/observability/session-run-hook.ts, scripts/observability/session-run-ledger.test.ts
Session and subagent events are normalized, serialized to JSONL, correlated, rotated, and written by a fail-open hook.
Exporter and session endpoint
scripts/observability/flow-exporter.ts, scripts/observability/flow-exporter.test.ts, scripts/observability/README.md
The exporter classifies session liveness, aggregates metrics, exposes /sessions.json, and reports ledger health.
Alert rules and provisioning
scripts/observability/alerts.rules.yml, scripts/observability/alerts.rules.test.yml, scripts/observability/prometheus.yml, scripts/observability/provisioning/*
Nine Prometheus and Grafana alerts cover flow, task, process, exporter, and inbox conditions. Telegram delivery and datasource provisioning are added.
Installation and dashboard
scripts/observability/install-stack.ps1, scripts/observability/dashboards/war-room-system.json
The installer copies provisioning files and seeds Telegram credentials. The dashboard adds session and subagent panels.

GLM startup watchdog

Layer / File(s) Summary
Startup-hang detection
scripts/telegram/spawn-glm.ts, scripts/telegram/spawn-glm.test.ts
executeRun terminates banner-only workers without transcript growth during the startup window and records failure_class: "startup-hang".

CLIProxyAPI version

Layer / File(s) Summary
Version synchronization
scripts/setup/cli-proxy-lane.ps1, scripts/upstreams.json
The pinned CLIProxyAPI version changes from 7.2.115 to 7.2.122.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

  • yotamleo/Himmel#389: Directly precedes the check-ci.sh merge-gate changes extended here.
  • yotamleo/Himmel#401: Established the implementor-dispatch guard extended with lane-readiness checks.
  • yotamleo/Himmel#433: Introduced the observability exporter and dashboard extended by this change.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the batch and names its main changes, although it covers several related features.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/leg3-dispatch-public-ship

Comment @coderabbitai help to get the list of available commands.

@yotamleo

yotamleo commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (1)
scripts/observability/flow-exporter.test.ts (1)

1192-1219: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a route-level test for GET /sessions.json.

The tests call renderSessionsJson directly. The new branch in startFlowExporter's fetch handler (flow-exporter.ts lines 1417-1428) stays untested. That branch also changed the 404 condition and sets the application/json content type. A regression there would ship undetected.

Add one test that starts the exporter, fetches /sessions.json, and asserts the status, the content type, and a parsed body. Assert that an unknown path still returns 404.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/observability/flow-exporter.test.ts` around lines 1192 - 1219, Add a
route-level test that starts the exporter and requests /sessions.json through
its fetch handler, asserting a successful status, application/json content type,
and parsed session response body. Also request an unknown path and assert it
returns 404, covering the routing changes in startFlowExporter.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/check-ci.sh`:
- Around line 49-55: Update the comment above the freshness requirement to point
to the local review_freshness_gate function below, and identify
cr_review_freshness from scripts/lib/cr-review-freshness.sh as the library
reader.

In `@scripts/lanes/lane-readiness.mjs`:
- Around line 77-81: Update the validation in the readiness mapping around
passesRequired to require a positive integer, treating fractional values as
ungated and returning ready before trailingPasses is evaluated; preserve the
existing handling for non-numeric, non-finite, and non-positive values. Add a
lane-readiness test covering a fractional passesRequired value.

In `@scripts/observability/alerts.rules.yml`:
- Around line 45-55: The HimmelFlowRunStalled alert currently fires on
cumulative stalled outcomes and can remain active after the stalled run is no
longer current. Update the alert expression or the metric emitted by
foldFlowLedger so it represents only currently stalled runs, ensuring the alert
clears when no run remains stalled while preserving detection of active stalled
runs.

In `@scripts/observability/prometheus.yml`:
- Around line 10-11: Update the installation flow in install-stack.ps1 to copy
alerts.rules.yml alongside prometheus.yml into $stateRoot, preserving the
configured rule_files reference so the installed Prometheus process can load the
rules.

In `@scripts/observability/provisioning/alerting/rules.yaml`:
- Line 33: Replace the rolling flow_run_outcome_total increase() expressions for
truncated and error alerts in
scripts/observability/provisioning/alerting/rules.yaml at lines 33 and 61 with
an event-time metric or truly monotonic persisted counter, and apply the
identical corrected expression in scripts/observability/alerts.rules.yml. In
scripts/observability/alerts.rules.test.yml lines 16-50, add an aging-out
sequence such as 2 to 1 and assert it does not trigger a new alert.

In `@scripts/observability/session-run-ledger.ts`:
- Around line 117-124: Update jsonStr to escape every C0 control character below
U+0020, including the existing newline, carriage-return, and tab cases, using
valid JSON escape sequences or Unicode escapes. Preserve the current escaping of
backslashes and quotes so parseSessionLedgerRows can parse strings containing
any control byte.

In `@scripts/setup/cli-proxy-lane.ps1`:
- Around line 65-66: Update the synchronized CLIProxyAPI version and release URL
in scripts/setup/cli-proxy-lane.ps1 lines 65-66 to reference an artifact-backed
release, and update the matching pin in scripts/upstreams.json line 153. Ensure
both locations use the same version and that the Windows amd64 ZIP exists at the
generated release URL.

In `@scripts/telegram/spawn-glm.ts`:
- Around line 1019-1034: The watchdog logic around watchTimer and baseline must
not treat the first observed transcript size as the baseline. Detect assistant
activity already present on the first observation and disarm via the existing
healthy-response path, or initialize reliable size tracking before runSession
can write; add a regression test covering transcript creation and growth before
the first poll followed by inactivity past the fail-fast window.

In `@scripts/upstreams.json`:
- Around line 153-156: Update the note associated with the CLIProxyAPI upstream
row so its version-normalization example matches the current synced_base value
7.2.122, or rewrite the example to avoid hardcoded versions while preserving the
described leading-“v” comparison behavior.

---

Nitpick comments:
In `@scripts/observability/flow-exporter.test.ts`:
- Around line 1192-1219: Add a route-level test that starts the exporter and
requests /sessions.json through its fetch handler, asserting a successful
status, application/json content type, and parsed session response body. Also
request an unknown path and assert it returns 404, covering the routing changes
in startFlowExporter.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e150dd6-ca11-4cfe-afbe-c5d15de84b09

📥 Commits

Reviewing files that changed from the base of the PR and between c009e4e and ea28cf0.

📒 Files selected for processing (37)
  • .claude/commands/check-ci.md
  • .claude/commands/pr-check.md
  • docs/internals/enforcement.md
  • scripts/check-ci.sh
  • scripts/guardrails/graphify-fence.sh
  • scripts/guardrails/lesson-write-fence.sh
  • scripts/guardrails/test-graphify-fence.sh
  • scripts/guardrails/test-lesson-write-fence.sh
  • scripts/hooks/guard-implementor-dispatch.sh
  • scripts/hooks/test-block-unresolved-cr-merge.sh
  • scripts/hooks/test-guard-implementor-dispatch.sh
  • scripts/lanes/lane-readiness.mjs
  • scripts/lanes/lanes.json
  • scripts/lanes/tests/lane-readiness.test.mjs
  • scripts/lib/cr-merge-gate.sh
  • scripts/lib/cr-review-freshness.sh
  • scripts/lib/test-cr-merge-gate.sh
  • scripts/observability/README.md
  • scripts/observability/alerts.rules.test.yml
  • scripts/observability/alerts.rules.yml
  • scripts/observability/dashboards/war-room-system.json
  • scripts/observability/flow-exporter.test.ts
  • scripts/observability/flow-exporter.ts
  • scripts/observability/install-stack.ps1
  • scripts/observability/prometheus.yml
  • scripts/observability/provisioning/alerting/contact-points.yaml
  • scripts/observability/provisioning/alerting/policies.yaml
  • scripts/observability/provisioning/alerting/rules.yaml
  • scripts/observability/provisioning/datasources/prometheus.yaml
  • scripts/observability/session-run-hook.ts
  • scripts/observability/session-run-ledger.test.ts
  • scripts/observability/session-run-ledger.ts
  • scripts/setup/cli-proxy-lane.ps1
  • scripts/telegram/spawn-glm.test.ts
  • scripts/telegram/spawn-glm.ts
  • scripts/test-check-ci.sh
  • scripts/upstreams.json

Comment thread scripts/check-ci.sh
Comment thread scripts/lanes/lane-readiness.mjs
Comment thread scripts/observability/alerts.rules.yml
Comment thread scripts/observability/prometheus.yml
Comment thread scripts/observability/provisioning/alerting/rules.yaml
Comment thread scripts/observability/session-run-ledger.ts
Comment thread scripts/setup/cli-proxy-lane.ps1
Comment thread scripts/telegram/spawn-glm.ts
Comment thread scripts/upstreams.json
…ometheus.yml

Addresses the CodeRabbit finding on this PR: prometheus.yml's
rule_files entry is relative to the config location, so the rule file
must travel with the config copy — without it the installed Prometheus
refuses its config and the HIMMEL-924 native rules are inert after
install. Same idempotent -Force Copy-Item pattern as the config copy.

Private: PR #1621, merged (d0a428b2).
@yotamleo

yotamleo commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/observability/install-stack.ps1 (1)

766-775: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Remove obsolete provisioning files on reinstall.

Copy-Item -Recurse -Force merges into $grafanaProvisioning. It does not remove files deleted or renamed in scripts/observability/provisioning. Grafana can continue loading obsolete alert rules or contact points after a rerun.

If this directory is installer-owned, replace it from a clean staging directory or remove stale files before copying.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/observability/install-stack.ps1` around lines 766 - 775, Update the
provisioning installation block using $grafanaProvisioning so each reinstall
starts from a clean directory, removing existing installer-owned contents before
recursively copying the current provisioning contents from $scriptDir. Preserve
the existing directory creation and content-copy behavior while ensuring deleted
or renamed source files are not retained.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@scripts/observability/install-stack.ps1`:
- Around line 766-775: Update the provisioning installation block using
$grafanaProvisioning so each reinstall starts from a clean directory, removing
existing installer-owned contents before recursively copying the current
provisioning contents from $scriptDir. Preserve the existing directory creation
and content-copy behavior while ensuring deleted or renamed source files are not
retained.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 8e96c33b-3471-4223-8d91-cd0ceac316d3

📥 Commits

Reviewing files that changed from the base of the PR and between ea28cf0 and ca4a6d7.

📒 Files selected for processing (1)
  • scripts/observability/install-stack.ps1

@yotamleo
yotamleo merged commit b7410ce into main Aug 7, 2026
15 checks passed
@yotamleo
yotamleo deleted the feat/leg3-dispatch-public-ship branch August 7, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant