Skip to content
Merged
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
22 changes: 22 additions & 0 deletions agent/prompt_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,28 @@ def _strip_yaml_frontmatter(content: str) -> str:
"every assignee in a real profile (`hermes profile list`, or ask the user), "
"and express dependencies via `parents=[...]` on `kanban_create`, not prose.\n"
"\n"
"## Shared-checkout git discipline (non-negotiable)\n"
"\n"
"When a task requires working in a LIVE repository (not your kanban "
"workspace), other agents and humans may be in the same checkout AT THE "
"SAME TIME. Collisions here have caused real incidents (a worker's staged "
"file swept into another agent's commit; a branch cut from a moved HEAD):\n"
"- `git branch --show-current` and `git status` FIRST — never branch from "
"an unverified HEAD; another agent may have moved it or left the tree dirty.\n"
"- Isolate immediately: your own branch before any edit (`git checkout -b "
"<task-slug>`), or `git worktree add` for full isolation. One agent = one "
"branch = one working state.\n"
"- Stage explicit paths and commit immediately: `git add <paths> && git "
"commit`. NEVER leave work staged-but-uncommitted — a concurrent "
"committer's bare `git commit` sweeps the whole index and steals your "
"staged files into THEIR commit.\n"
"- Never `git commit -a`, never force-push a branch you don't own, never "
"resolve merge conflicts via the GitHub web UI — a conflict resolution is "
"a code change: do it locally and run the tests before pushing.\n"
"- When done, leave the shared checkout as you found it: original branch "
"restored, `git status --porcelain` empty. A dirty/non-main checkout can "
"silently break nightly automation that requires main.\n"
"\n"
"## Do NOT\n"
"\n"
"- Do not shell out to `hermes kanban <verb>` for board operations. Use "
Expand Down
8 changes: 5 additions & 3 deletions tests/tools/test_kanban_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -1505,8 +1505,10 @@ def test_kanban_guidance_prompt_size_bounded(monkeypatch, tmp_path):
The block absorbed the load-bearing worker/orchestrator reference
details (workspace kinds, deliverable artifacts, created-card claims,
profile discovery) when the standalone kanban-worker / kanban-orchestrator
skills were removed and folded into this always-injected guidance, so the
ceiling is sized to fit that content with a little headroom.
skills were removed and folded into this always-injected guidance, plus
the shared-checkout git discipline section added with the subagent fleet
doctrine, so the ceiling is sized to fit that content with a little
headroom.
"""
monkeypatch.setenv("HERMES_KANBAN_TASK", "t_fake")
home = tmp_path / ".hermes"
Expand All @@ -1516,7 +1518,7 @@ def test_kanban_guidance_prompt_size_bounded(monkeypatch, tmp_path):
monkeypatch.setattr(_P, "home", lambda: tmp_path)

from agent.prompt_builder import KANBAN_GUIDANCE
assert 1_500 < len(KANBAN_GUIDANCE) < 5_500, (
assert 1_500 < len(KANBAN_GUIDANCE) < 8_000, (
f"KANBAN_GUIDANCE is {len(KANBAN_GUIDANCE)} chars — too short (missing?) or too long"
)

Expand Down
27 changes: 27 additions & 0 deletions tools/delegate_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,33 @@ def _build_child_system_prompt(
"- What you found or accomplished\n"
"- Any files you created or modified\n"
"- Any issues encountered\n\n"
"## Honesty and evidence (non-negotiable)\n"
"Your summary is a SELF-REPORT the parent will independently verify before\n"
"trusting it. Make verification cheap and lying impossible:\n"
"- Every claim of completion must cite observable evidence: the command you\n"
" ran and what it actually printed, the artifact path, URL, PR/issue number,\n"
" or exit code. 'Tests pass' without the summary line is not evidence.\n"
"- Never report success you did not observe. Never invent output, counts,\n"
" paths, or timestamps to fill a gap. 'I could not verify X because Y' is a\n"
" valid, valued answer — fabricated certainty is not.\n"
"- If a step failed, quote the real error verbatim and stop there — the\n"
" parent decides the next move, not your optimism.\n"
"- Operations with external side effects (pushes, PRs, deploys, writes to\n"
" shared paths) require a verifiable handle in the summary (URL, id, sha).\n\n"
"## Git discipline in shared checkouts (non-negotiable)\n"
"Other agents and humans may be working in the same repository AT THE SAME\n"
"TIME. Before any git work in a repo you did not create for this task:\n"
"- Run `git branch --show-current` and `git status` FIRST — never branch from\n"
" an unverified HEAD (another agent may have moved it).\n"
"- If you will write code, isolate yourself: `git worktree add <path> -b <branch>`\n"
" or your own branch immediately. One agent = one branch = one working state.\n"
"- Stage only explicit paths and commit immediately: `git add <paths> && git commit`.\n"
" NEVER leave files staged-but-uncommitted (a concurrent committer's `git commit`\n"
" sweeps the whole index and steals your staged work into their commit).\n"
"- Never `git commit -a`, never resolve merge conflicts via the GitHub web UI\n"
" (a resolution is a code change — do it locally and run the tests).\n"
"- When finished in a shared checkout, leave it as you found it: original\n"
" branch restored, working tree clean (`git status --porcelain` empty).\n\n"
"Important workspace rule: Never assume a repository lives at /workspace/... or any other container-style path unless the task/context explicitly gives that path. "
"If no exact local path is provided, discover it first before issuing git/workdir-specific commands.\n\n"
"Keep your final summary tight: lead with outcomes, prefer bullet "
Expand Down
Loading