Refuse to start with the state store or .env inside the clone
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 1m14s

Answering "is the workspace where the agent runs, or what it works
on?" — it is what it works on, and conflating the two is dangerous
rather than merely untidy.

The agent commits its workspace with git add -A and pushes it, so
anything inside the clone reaches the project repository. A .env
placed there would publish the LiteLLM, Matrix and Gitea tokens as a
side effect of the agent working correctly: silently, once, and
probably unnoticed. Startup now refuses both that and a state store
inside the clone, and .env.example documents the intended layout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
dongarandClaude Opus 5 committed 2026-09-08 22:31:39 +00:00
1 parent 2fb25b8195
commit dfa574aeec
3 files changed
+79 -1

No files matched your search

+41
View File
@@ -89,3 +89,44 @@ def test_state_db_and_workspace_are_separate(tmp_path: Path) -> None:
# A2: build artefacts must not share a volume with agent state.
config = AgentConfig.from_env(COMPLETE)
assert config.state_db.parent != config.workspace
def test_state_db_inside_the_clone_is_refused(tmp_path: Path) -> None:
# git add -A would commit it, and the push would publish the agent's
# own state alongside the project.
work = tmp_path / "project"
with pytest.raises(ConfigError, match="inside the workspace"):
AgentConfig.from_env(
{
**COMPLETE,
"NISSE_WORKSPACE": str(work),
"NISSE_STATE_DB": str(work / "state.db"),
}
)
def test_env_file_inside_the_clone_is_refused(tmp_path: Path) -> None:
# The severe case: the agent would commit and push its own credentials
# as a side effect of working correctly.
work = tmp_path / "project"
with pytest.raises(ConfigError, match="NISSE_ENV"):
AgentConfig.from_env(
{
**COMPLETE,
"NISSE_WORKSPACE": str(work),
"NISSE_STATE_DB": str(tmp_path / "state.db"),
"NISSE_ENV": str(work / ".env"),
}
)
def test_sibling_paths_are_fine(tmp_path: Path) -> None:
config = AgentConfig.from_env(
{
**COMPLETE,
"NISSE_WORKSPACE": str(tmp_path / "project"),
"NISSE_STATE_DB": str(tmp_path / "state.db"),
"NISSE_ENV": str(tmp_path / ".env"),
}
)
assert config.workspace.name == "project"