Skip to content

feat(config): observability block schema (#119 PR-1 of 4) - #2450

Merged
HongmingWang-Rabbit merged 1 commit into
stagingfrom
feat/observability-config-schema
May 1, 2026
Merged

HongmingWang-Rabbit merged 1 commit into
stagingfrom
feat/observability-config-schema

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Summary

  • Add ObservabilityConfig dataclass to workspace/config.py: groups cadence + verbosity knobs into one declarative block (hermes-style).
  • Two fields with live consumers waiting:
    • heartbeat_interval_seconds (default 30, clamped to [5, 300]) — heartbeat.py:134 has hard-coded HEARTBEAT_INTERVAL = 30
    • log_level (default "INFO", uppercased at parse) — main.py:465 has hard-coded log_level="info"
  • Clamp + uppercase coercion happens at parse time so adapters and consumers don't have to re-validate.
  • Schema-only — wiring lands in PR-3 of the fix(security+scheduler): IPv6 SSRF gap + scheduler unit tests [supersedes #111, #112] #119 stack.

Why this shape

Daniel's incident IR-2026-03-11 showed sub-5s heartbeats flood the platform; >5min lets crashed workspaces look healthy long enough to mask failure. Clamp band [5, 300] is the safe operating range — coerce at boundary, not at every read site.

Stack

  • PR-1 (this): schema only
  • PR-2: EventLog module + EventLogConfig nested under observability
  • PR-3: wire consumers (heartbeat.py, main.py logging)
  • PR-4: skill-compat audit + SKILL.md frontmatter docs

Part of task #119 (adopt hermes-style architecture: event-log, declarative skill compat, observability config block).

Test plan

  • pytest workspace/tests/test_config.py — 48 tests pass (45 existing + 7 new for the new block)
  • New tests cover: dataclass default, YAML omits block, explicit YAML, partial override, parametrized clamp (10 cases including garbage strings + None), log_level uppercase normalization
  • CI green

Hermes-style declarative block grouping cadence + verbosity knobs into
one place. Schema-only in this PR — wiring into heartbeat.py and main.py
lands in PR-3 of the #119 stack.

Two fields with live consumers waiting:
- heartbeat_interval_seconds (default 30, clamped to [5, 300])
  → heartbeat.py:134 currently has hard-coded HEARTBEAT_INTERVAL = 30
- log_level (default "INFO", uppercased at parse)
  → main.py:465 currently has hard-coded log_level="info"

Clamp band [5, 300] is intentional: sub-5s flooded the platform during
IR-2026-03-11; >5min lets crashed workspaces look healthy long enough
to mask failure. Coerce at parse so adapters and heartbeat.py can read
the value without re-validating.

Tests pin defaults, explicit YAML override, partial override, and
parametrized clamp behavior (10 cases including garbage strings + None).

Part of: task #119 (adopt hermes-style architecture)
Stack:  PR-1 schema → PR-2 event_log → PR-3 wire consumers → PR-4 skill compat
@HongmingWang-Rabbit
HongmingWang-Rabbit added this pull request to the merge queue May 1, 2026
Merged via the queue into staging with commit c06c4c0 May 1, 2026
20 checks passed
@HongmingWang-Rabbit
HongmingWang-Rabbit deleted the feat/observability-config-schema branch May 1, 2026 05:24
HongmingWang-Rabbit pushed a commit that referenced this pull request Jun 12, 2026
…nflicts (#2450)

Replaces the fixed :8080 bind with an OS-allocated ephemeral port in both
lifecycle-stub and lifecycle-real jobs. This eliminates the "address already
in use" failures caused by stale processes or concurrent jobs on shared
docker-host runners.

Changes:
- Configure platform env: allocate PORT via socket.bind(('', 0)) and set
  BASE=http://localhost:8000.
- Start platform: use PORT=8000 instead of hardcoded 8080.
- Kill stale platform-server: remove the fuser/lsof port-scan for 8080
  (no longer needed) and keep the comm-scan process cleanup.
- Update comments to reflect dynamic-port rationale.

Fixes #2450

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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