Skip to content

team: snapshot worktree on submit + refuse no-op submissions #177

Merged
Koukyosyumei merged 8 commits into
mainfrom
update-readme
Jun 22, 2026
Merged

team: snapshot worktree on submit + refuse no-op submissions #177
Koukyosyumei merged 8 commits into
mainfrom
update-readme

Conversation

@Koukyosyumei

Copy link
Copy Markdown
Collaborator

No description provided.

team agent submit froze the env branch tip, but nothing committed the
agent's worktree edits first — so an agent that edited files and submitted
without committing froze the base tree, and reviewers saw nothing to review.

- env::snapshot_for_submit: locked mediated-commit of the env worktree
  (mirrors propose); no-op when there is no local worktree (pulled clone).
- team::submit auto-snapshots on the no-explicit-commit path, then refuses
  a submission whose tree is identical to the team base (nothing to review).
- tests: submit_refuses_no_op_submission, submit_auto_snapshots_dirty_worktree;
  updated two existing tests to advance the env branch off base.
…--as

- --role was never a CLI flag; replace with --persona <file> (the real
  working-style mechanism; see examples/personas/).
- omit --as from all example commands (the agent id auto-generates); surface
  the generated ids via h5i team status and reference them in downstream
  --agent flags. Keep --as in the flag reference, marked optional.
- document team submit's new auto-snapshot + no-op refusal; add the missing
  team persona row. Regenerate docs/manual from MANUAL.md.
@Koukyosyumei Koukyosyumei changed the title Update readme team: snapshot worktree on submit + refuse no-op submissions Jun 22, 2026
Regression from 236c004: snapshot_for_submit acquired the env run lock,
but team submits are ingested *while the agent's box is still alive* (the
team Stop hook keeps boxes running; team sync drains mid-round), so the box
always holds run.lock. The non-blocking acquire (LOCK_EX|LOCK_NB) returned
'busy', team::submit errored, and ingest_team_outbound silently deleted the
staged spool — so every mid-round submit was dropped (submits: 0, no events),
even for agents that had already committed their work.

- snapshot_for_submit is now best-effort: on lock contention it falls back to
  the branch tip (Ok(None)) instead of failing. A committed worktree records
  immediately; an uncommitted one is snapshotted by the at-exit ingest once
  the lock frees.
- ingest_team_outbound keeps the spool file on submit failure (retryable at
  box exit) and records the failure as a durable env event instead of a
  stderr warning a script-polled sync swallows.
- test: snapshot_for_submit_is_best_effort_under_run_lock.
The host can't snapshot a *live* box: the team Stop hook keeps a box alive
for the whole round, so it holds the env run lock the entire session, and the
at-exit ingest never runs mid-round. An agent that writes files but never
commits (codex left quick_sort.py/pyproject.toml as untracked `??` files)
therefore staged a no-op the host refused as 'identical to the team base' —
freeze blocked, the round wedged.

Fix: the in-box `team agent submit` now commits the worktree onto the env
branch itself (commit_box_worktree), where the box has a functional checkout
(rw on its own branch + objects). The host ingest then freezes the advanced
tip — exactly the path a well-behaved agent already takes by committing
in-box. Best-effort: any git error degrades to a no-op so submit is never
blocked; an explicit --commit skips it.

- env::commit_box_worktree / commit_worktree_at (testable, path-based).
- main: call it on the in-box no-explicit-commit submit path.
- test: commit_box_worktree_snapshots_untracked_edits.
commit_box_worktree returned Option and used .ok()? throughout, so ANY git
error inside the box (e.g. a too-narrow box_git_plumbing grant) degraded to a
silent no-op — indistinguishable from a clean worktree, and exactly what makes
an agent's work vanish into a 'no changes to review' submission.

Return Result<Option<Oid>> and have the in-box `team agent submit` print a
clear warning on Err (while still staging — a failed snapshot must never block
the submit; the host then freezes the branch tip). Next run self-diagnoses:
either '▢ snapshotted worktree in-box at <oid>' or a concrete error to act on.
Follow-up to the in-box submit snapshot. Two parts:

1. commit_box_worktree no longer calls git2 index.write() before committing —
   the proven-working `h5i capture commit` path never persists the index from
   git2 (the agent's `git add` does), and writing worktrees/<wt>/index via a
   lock+rename is the step most likely to EACCES in a tight box layout while the
   object + ref writes succeed. Land the commit from the in-memory index
   (write_tree + commit), then refresh the index best-effort. Also return Result
   so a real failure is surfaced (warning) instead of silently becoming a no-op.

2. h5i init guidance (AGENTS.md / .claude/h5i.md templates + this repo's copies):
   'In an agent team, always h5i capture commit before h5i team agent submit.'
   This is the reliable mitigation — a committed worktree submits correctly
   regardless of whether the auto-snapshot can run (it's what well-behaved
   agents already do).
@Koukyosyumei

Copy link
Copy Markdown
Collaborator Author

🪙 86% AI-authored · 7 files · prompt 51/100

6 AI commits · 🚩 1 flagged

6 / 771.3 : 11 / 3
AI commitsfiles touchedREAD : EDITTHINKs / ops

💬 The ask

"It seems it's sometimes hard for each agent in each sandbox to find other's change in h5i env's review phase. Example log is "● Ran 2 stop hooks (ctrl+o to expand) ⎿  Stop hook error: h5i: 2 inbound messages for cleo — untrusted colla…"

📍 What shipped

  • ✓ bump to v0.2.2
  • ✓ team: don't lose in-box submits while the box is alive
  • ✓ team: commit the worktree in-box on team agent submit
  • ✓ team: surface in-box submit-snapshot failures instead of swallowing them
  • ✓ team: make in-box snapshot robust + tell agents to commit before submit

Note

🌿 Prompt maturity: 51/100 · proficient · 5 prompts scored (83% of AI commits)
🔧 Recurring weak spots: weak context, no acceptance criteria, too short.
Heuristic signal of prompt craft — not a developer rating.

📊 heuristic breakdown
Dimension Signal
Specificity █████████░ 0.91
Control / acceptance ████░░░░░░ 0.43
Context grounding ████░░░░░░ 0.43
Structure █████░░░░░ 0.52
Lexical diversity ████████░░ 0.80
Clarity (readability band) █████████░ 0.93
Length adequacy █████████░ 0.88

Readability (display-only): Flesch 51 · FK grade 11.8 · Gunning Fog 14.2

Offline classical-NLP score — no LLM. Higher = more specific, bounded, and grounded prompting.

Tip

✅ Security scan clean

No credentials leaked in this branch's diff. h5i scanned every added line against the secret rule pack and found nothing to rotate.

Note

Duplicate-code scan clean — no copy-paste blocks introduced.

🧠 Reasoning by file — 9203 nodes across 6 lanes, latest 24 only
%%{init: {"flowchart": {"nodeSpacing": 42, "rankSpacing": 48, "diagramPadding": 14}, "themeVariables": {"fontSize": "18px"}} }%%
flowchart TB
  subgraph lane_0["💭 Reasoning · 8 steps"]
    direction LR
    n_lane_0_0["THINK · Let me retry on the `process` tier (which runs for real on this host):"]:::t
    n_lane_0_1["THINK · Let me retry the supervised box with `env run` (non-interactive) instead…"]:::t
    n_lane_0_2["THINK · Let me refactor `commit_box_worktree` to return a `Result` so the caller…"]:::t
    n_lane_0_3["THINK · claude (felix) committed fine in-box, so let me compare how *it* commits…"]:::t
    n_lane_0_4["THINK · write()`. Rather than keep reasoning, let me reproduce at the `process` …"]:::t
    n_lane_0_5["THINK · md (”always commit before submit”) — I'll do that after this repro confi…"]:::t
    n_lane_0_6["NOTE · DEFERRAL (~/Dev/h5i/src/main.rs): m-submit-*.json` is kept by the no-dro…"]:::n
    n_lane_0_7["NOTE · PLACEHOLDER (~/Dev/h5i/src/env.rs): My repro profile was incomplete — th…"]:::n
    n_lane_0_0 --> n_lane_0_1
    n_lane_0_1 --> n_lane_0_2
    n_lane_0_2 --> n_lane_0_3
    n_lane_0_3 --> n_lane_0_4
    n_lane_0_4 --> n_lane_0_5
    n_lane_0_5 --> n_lane_0_6
    n_lane_0_6 --> n_lane_0_7
  end
  subgraph lane_1["📄 src/main.rs · 6 ops"]
    direction LR
    n_lane_1_0["EDIT"]:::a
    n_lane_1_1["READ × 2"]:::o
    n_lane_1_2["EDIT"]:::a
    n_lane_1_3["READ"]:::o
    n_lane_1_4["EDIT"]:::a
    n_lane_1_0 --> n_lane_1_1
    n_lane_1_1 --> n_lane_1_2
    n_lane_1_2 --> n_lane_1_3
    n_lane_1_3 --> n_lane_1_4
  end
  subgraph lane_2["📄 src/env.rs · 3 ops"]
    direction LR
    n_lane_2_0["EDIT"]:::a
    n_lane_2_1["READ"]:::o
    n_lane_2_2["EDIT"]:::a
    n_lane_2_0 --> n_lane_2_1
    n_lane_2_1 --> n_lane_2_2
  end
  subgraph lane_3["📄 AGENTS.md · 2 ops"]
    direction LR
    n_lane_3_0["READ"]:::o
    n_lane_3_1["EDIT"]:::a
    n_lane_3_0 --> n_lane_3_1
  end
  subgraph lane_4["📄 .claude/h5i.md · 2 ops"]
    direction LR
    n_lane_4_0["READ"]:::o
    n_lane_4_1["EDIT"]:::a
    n_lane_4_0 --> n_lane_4_1
  end
  subgraph lane_5["🗂 Other · 3 nodes"]
    direction LR
    n_lane_5_0["READ · read src/repository.rs"]:::o
    n_lane_5_1["READ · read src/sandbox_policy.rs"]:::o
    n_lane_5_2["READ · read src/sandbox.rs"]:::o
    n_lane_5_0 --> n_lane_5_1
    n_lane_5_1 --> n_lane_5_2
  end
  classDef o fill:#dbeafe,stroke:#1e3a8a,color:#0b1c4a;
  classDef t fill:#fef3c7,stroke:#92400e,color:#3f2d05;
  classDef a fill:#dcfce7,stroke:#166534,color:#0a2e16;
  classDef n fill:#ede9fe,stroke:#5b21b6,color:#221251;
  classDef m fill:#e5e7eb,stroke:#374151,color:#0b0f17;
Loading
📜 Per-commit provenance — 6 AI-authored commits

c735fbf2 team: make in-box snapshot robust + tell agents to commit before submit

  • promptI reproduce the same error in ./Examples/T11's Codex env
    • 🌱 prompt maturity 18/100 nascent — too short, weak context
  • model claude-opus-4-8 · agent claude-code

835f3ca5 team: surface in-box submit-snapshot failures instead of swallowing them

  • promptI made a new envs (./Examples/TOO), but it still shows "• Ran h5i capture run -- h5i hook codex finish │ --summary "Implemented Quick Sort in Python with │ pytest coverage" && h5i capture run -- h5i team │ … +1 lines └ ✔ Synced Codex session rollout-2026-06-22T09-48-…
    • 🌿 prompt maturity 61/100 proficient — weak context
  • model claude-opus-4-8 · agent claude-code

b3b7303d team: commit the worktree in-box on team agent submit

  • promptIn codex (./Examples/TOL), it still logs as " The generated cache is gone. I’m doing one final status check and then submitting the candidate. • Ran h5i capture run -- h5i team agent submit └ ▢ team submit staged for host ingest (team-submit-131361-1782135051793552293) …
    • 🪴 prompt maturity 49/100 developing — weak context, no acceptance criteria
  • model claude-opus-4-8 · agent claude-code

46661a04 team: don't lose in-box submits while the box is alive

  • promptwhile both terminals says "● Bash(h5i capture run -- h5i team agent submit) ⎿  ▢ team submit staged for host ingest (t eam-submit-120412-1782133158846743574) ● Submitted. Summary: - quicksort.py — pure-functional quicksort() (returns new list) plus in-place quickso…
    • 🌿 prompt maturity 51/100 proficient — weak context
  • model claude-opus-4-8 · agent claude-code

a0db7a42 docs: fix h5i team examples — drop nonexistent --role, omit optional --as

  • prompt — __
  • model claude-opus-4-8 · agent claude-code
  • 🚩 review signals — score 0.35: AI_NO_PROMPT, PERMISSION_CHANGE
    • shape signals (informational): LARGE_DIFF, WIDE_IMPACT, UNTESTED_CHANGE

236c0046 team: snapshot worktree on submit + refuse no-op submissions

  • promptIt seems it's sometimes hard for each agent in each sandbox to find other's change in h5i env's review phase. Example log is "● Ran 2 stop hooks (ctrl+o to expand) ⎿  Stop hook error: h5i: 2 inbound messages for cleo — untrusted collaborator input, decide whether to act: …
    • 🪴 prompt maturity 47/100 developing
  • model claude-opus-4-8 · agent claude-code

Generated by h5i · re-run h5i share pr post to refresh.

@Koukyosyumei Koukyosyumei merged commit 01e225a into main Jun 22, 2026
5 checks passed
@Koukyosyumei Koukyosyumei deleted the update-readme branch June 22, 2026 14:45
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