Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,32 @@ def _looks_like_credential(name: str) -> bool:
return any(name.endswith(suf) for suf in _CREDENTIAL_SUFFIXES)


# Kanban env pins are legitimate production/operator controls: the CLI uses
# them for board selection, the dispatcher injects them into worker processes,
# and the gateway honours the dispatcher toggle. They still must be scrubbed
# from pytest's ambient process env because tests that need Kanban context set
# it explicitly and default-board tests rely on no ambient board/path pin.
#
# Scope this set to HERMES_KANBAN_* variables. The dispatcher also injects
# HERMES_PROFILE for worker author attribution, but that is a broader profile
# selector rather than a Kanban-specific pin and is intentionally out of this
# narrow regression fix.
_HERMES_KANBAN_BEHAVIORAL_VARS = frozenset({
# Board and path resolution pins.
"HERMES_KANBAN_BOARD",
"HERMES_KANBAN_DB",
"HERMES_KANBAN_HOME",
"HERMES_KANBAN_WORKSPACES_ROOT",
# Dispatcher-spawned worker runtime pins.
"HERMES_KANBAN_TASK",
"HERMES_KANBAN_WORKSPACE",
"HERMES_KANBAN_RUN_ID",
"HERMES_KANBAN_CLAIM_LOCK",
# Gateway dispatcher escape hatch.
"HERMES_KANBAN_DISPATCH_IN_GATEWAY",
})


# HERMES_* vars that change test behavior by being set. Unset all of these
# unconditionally — individual tests that need them set do so explicitly.
_HERMES_BEHAVIORAL_VARS = frozenset({
Expand Down Expand Up @@ -188,6 +214,7 @@ def _looks_like_credential(name: str) -> bool:
"HERMES_BACKGROUND_NOTIFICATIONS",
"HERMES_EXEC_ASK",
"HERMES_HOME_MODE",
*_HERMES_KANBAN_BEHAVIORAL_VARS,
"TERMINAL_CWD",
"TERMINAL_ENV",
"TERMINAL_VERCEL_RUNTIME",
Expand Down
33 changes: 33 additions & 0 deletions tests/test_hermetic_environment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Regression coverage for process-level pytest environment isolation."""

from __future__ import annotations

import os

import tests.conftest as hermes_conftest


def test_kanban_env_pins_do_not_leak_from_pytest_process_env():
"""Ambient Kanban pins must not be visible inside test bodies.

Hermes sessions and dispatcher workers legitimately export these variables,
so local developer shells can carry them into `pytest`. The global hermetic
fixture owns clearing them; individual Kanban tests opt back in with
`monkeypatch.setenv(...)` when a variable is part of the behavior under test.
"""

leaked = {
name: os.environ[name]
for name in sorted(hermes_conftest._HERMES_KANBAN_BEHAVIORAL_VARS)
if name in os.environ
}

assert leaked == {}


def test_tests_can_still_set_kanban_env_pins_explicitly(monkeypatch):
"""The hermetic fixture clears ambient state, not test-local setup."""

monkeypatch.setenv("HERMES_KANBAN_BOARD", "explicit-test-board")

assert os.environ["HERMES_KANBAN_BOARD"] == "explicit-test-board"
Loading