Skip to content

Feat/gource acpx context#5

Merged
tjb-tech merged 6 commits intomainfrom
feat/gource-acpx-context
Mar 20, 2026
Merged

Feat/gource acpx context#5
tjb-tech merged 6 commits intomainfrom
feat/gource-acpx-context

Conversation

@tjb-tech
Copy link
Copy Markdown
Collaborator

No description provided.

tjb-tech and others added 2 commits March 18, 2026 06:09
Includes Gource visualization, ACPX spawn backend/transport,
and git context layer (conflicts, context).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Keep original README content including Korean docs link.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed718c9f68

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread clawteam/spawn/acpx_backend.py Outdated
Comment on lines +112 to +116
shell_cmd = f"{cmd_str}; {exit_hook}"

process = subprocess.Popen(
shell_cmd,
shell=True,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not wrap async ACPX spawns with the normal on-exit hook

When acpx is launched in --no-wait mode, the CLI can return as soon as the turn is queued. Because this wrapper always falls through to clawteam lifecycle on-exit, ClawTeam will treat that still-running ACPX session as exited, and the stored PID will already be dead. That breaks the liveness checks used by TaskStore._acquire_lock()/release_stale_locks() and TeamWaiter._check_dead_agents(), so active ACPX agents can have locks released or in_progress tasks reset while they are still working.

Useful? React with 👍 / 👎.

Comment thread clawteam/transport/acpx.py Outdated
Comment on lines +49 to +53
session_name = f"clawteam-{self.team_name}-{recipient}"

# Try to deliver via ACPX session
try:
# Parse the message to extract content for the ACPX prompt
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize inbox names before deriving ACPX session IDs

Here recipient is the mailbox inbox name, not always the spawned agent name. TeamManager.inbox_name_for() and get_leader_inbox() prefix members as user_agent when member.user is set, but AcpxBackend.spawn() creates sessions as clawteam-{team}-{agent_name}. On multi-user teams, direct sends to the leader or any member will target a non-existent ACPX session and silently fall back to file delivery, so the live ACPX push path never works for those members.

Useful? React with 👍 / 👎.

Comment on lines +80 to +84
try:
from clawteam.team.mailbox import MailboxManager
from clawteam.workspace.conflicts import auto_notify
mailbox = MailboxManager(team_name)
auto_notify(team_name, mailbox)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Deduplicate overlap warnings before auto-notifying again

While clawteam board watch is open, this branch calls auto_notify() every 5 refresh cycles, and auto_notify() always enqueues a fresh message for every current overlap. At the default 2-second refresh interval that means agents receive the same warning about every 10 seconds until someone closes the board, which quickly floods inboxes and buries real coordination messages.

Useful? React with 👍 / 👎.

Comment on lines +72 to +76
count = int(count)
else:
start = int(hunk)
count = 1
lines.update(range(start, start + count))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat zero-length diff hunks as real line changes

Deletion hunks from git diff -U0 are reported as +N,0. In that case range(start, start + count) is empty, so _changed_lines() records no lines for pure deletions. Two agents deleting the same region, or one deleting lines that another edits, will therefore be downgraded to medium/Different lines modified even though Git will produce a real merge conflict.

Useful? React with 👍 / 👎.

@tjb-tech tjb-tech merged commit 4d61784 into main Mar 20, 2026
7 checks passed
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 20, 2026
…it/exemption/symlink/concurrent

RED gate for Plan 02-05. 10 test functions covering:
- freeze/unfreeze persistence to freeze.json (SPRINT-02, QUALITY-06)
- is_frozen exact + path-prefix match
- Pitfall HKUDS#5 exemption: paths under get_data_dir() never vetoed
- T-02-02 mitigation: symlinks + .. segments canonicalized
- FrozenPathError message shape (D-12)
- freeze_audit.jsonl append-only (SAFETY-04, mirrors exit_journal.py)
- Pause/resume rehydration via get_freeze_registry singleton
- 8-thread concurrent writer (file_locked serialization)

All 10 tests fail with ModuleNotFoundError — Task 2 ships the implementation.
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 20, 2026
…pend-only audit

GREEN gate for Plan 02-05. Ships the sprint-scoped path write-lock registry
that Plan 02-10's BeforeFileWrite / BeforeToolCall subscribers will consult
to veto agent writes.

Implementation:
- FreezeRegistry singleton mirrors PhaseRegistry shape (§02-CONTEXT lesson HKUDS#3).
- freeze/unfreeze persist to freeze.json via file_locked + atomic_write_text
  (QUALITY-06); concurrent writers serialize with no torn state (8-thread test).
- Path canonicalization via Path.resolve(strict=False) on both store and
  compare (T-02-02 mitigation): symlinks resolve to real paths, .. segments
  collapse, relative-path bypass defeated.
- Pitfall HKUDS#5 exemption: is_frozen returns (False, "") for any path under
  get_data_dir() so sprint pause/resume never deadlocks writing its own
  state.json / freeze.json / answers/ after a user types /freeze /.
- freeze_audit.jsonl is append-only (SAFETY-04), mirroring exit_journal.py:
  one json.dumps(entry) + newline per freeze / unfreeze / freeze_glob.
- FrozenPathError subclasses ValueError so mcp.helpers.translate_error
  auto-wraps it into an MCPToolError (D-12). Message shape:
    "<path> is /freeze-locked by <who>; unfreeze via /unfreeze <path>"

Tests: 10/10 passing (test_freeze_registry.py). Regression matrix 12/12
green. Phase 1 peer tests (sprint_state, interaction_gate, phase_registry)
all green.

Plan 02-10 subscribes a handler that raises FrozenPathError when is_frozen
matches; this plan ships only the registry state-holder.

Requirements: SAFETY-02, SAFETY-04, QUALITY-06.
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 20, 2026
SUMMARY.md documents:
- Class + method line ranges (per plan <output> requirement)
- Pitfall HKUDS#5 exemption confirmation via test_is_frozen_returns_false_for_paths_under_data_dir
- T-02-02 symlink mitigation confirmation via test_is_frozen_canonicalizes_relative_paths_and_symlinks
- JSONL append-only invariant proof (5 lines after 5 actions)
- Forward contracts for Plan 02-10 / 02-11 / 02-12 / Phase 3
- 1 deviation: Rule 3 (blocking) test-fixture split for work_root vs data_root
  so Pitfall HKUDS#5 exemption and T-02-02 symlink check don't mask each other

RED commit: e0c01e6
GREEN commit: 268e423

Requirements completed: SAFETY-02, SAFETY-04, QUALITY-06
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 20, 2026
- 8 tests for Task 1: EventBus subscribers + /careful regex blacklist
- 6 tests for Task 3: clawteam guard CLI sub-app (freeze/unfreeze/guard/unguard)
- All fail with ImportError on CAREFUL_BLACKLIST + register_safety_subscribers (RED)
- Pitfall HKUDS#5 exemption re-verified at subscriber level (test 8)
- CLI tests use typer.testing.CliRunner + --json envelope assertions
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 20, 2026
Task 1 GREEN. Extends FreezeRegistry module with opt-in EventBus subscribers
that consult the registry on BeforeFileWrite + BeforeToolCall events.

- CAREFUL_BLACKLIST regex matches 5 destructive command patterns (D-13):
  rm -rf, git reset --hard, git push --force, DROP TABLE, DELETE FROM ... WHERE
- _on_before_file_write: veto writes to frozen paths (delegates to is_frozen
  which already honors the Pitfall HKUDS#5 data-dir exemption)
- _on_before_tool_call: shallow arg-scan for frozen path values
- _on_careful: warn-only by default; veto-mode via set_careful_veto_mode
  (flipped by clawteam guard guard composite)
- register_safety_subscribers(bus): idempotent opt-in registration called by
  SprintConductor.__init__ in Plan 02-11; Phase 0 templates never call this
  so their EventBus stays unsubscribed (Pitfall HKUDS#8 BC hinge)
- reset_safety_subscribers(): test helper
- 9 tests in tests/test_safety_rails.py now GREEN (Task 1 tests 1-8 plus one
  pass-through sanity check)
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 20, 2026
- 4 tests covering sprint lifecycle across Phase 2 primitives (UX-02/03/04/05/09,
  CORE-05/07, SPRINT-01/02, SKILL-09, SAFETY-02, QUALITY-01/08/11)
- Exercises CLI start/status/show/list/pause/resume via typer.CliRunner + JSON
  envelope shape
- Verifies FreezeRegistry data-dir exemption (Pitfall HKUDS#5)
- Confirms advance_phase gate chain does not crash on empty artifacts/turn-counters
- Validates AMBIGUOUS_SPRINT prefix error envelope (D-25)
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 27, 2026
…nswer/stop)

The 28-command CLI surface is overwhelming for a solo founder. This adds
4 task-oriented top-level commands that wrap the full happy path:

  clawteam go "<goal>"    — create team + start sprint + launch agents
  clawteam status          — dashboard: team/sprint/questions/cost, no tmux
  clawteam answer          — interactive question picker + $EDITOR launch
  clawteam stop            — kill tmux + cleanup team data

All four read/write an "active team" pointer at ~/.clawteam/active_team
so the user rarely passes --team explicitly. The full 28-command surface
(team, sprint, launch, attend, inbox, ...) is unchanged for power users.

Rationale:
- v1.0 UAT surfaced that the documented flow is `team spawn` + `sprint
  start` + `launch` (3 commands, easy to forget order) + `attend` +
  `attend pick <qid>` (requires knowing qid) + `team cleanup X --force`
  + `tmux kill-session -t clawteam-X` (two ways to stop).
- A solo founder shouldn't need to learn the full harness vocabulary.
- User explicitly asked for "不要做的太command heavy / 交互流程的简单
  易用 / 状态观察的直觉性" (don't make it command-heavy, prioritize easy
  interaction + intuitive state observation).

Design:
- `go`: 24-second one-shot on gstack template. Auto-names team
  `solo-<hash>` unless --name given. Shows 3-step progress (create /
  sprint / launch) + final rich Panel with next-step hints.
- `status`: single-screen view — agent count, sprint ID (truncated),
  goal, phase progress bar [█░░░░░░] think (1/7), top-5 pending
  questions (title not qid), cost panel with honest "$0.00 — 999.001
  unwired" caveat, tmux session liveness indicator (● green / ○ red).
- `answer`: numbered list of pending questions, prompt for choice,
  open question.md in $EDITOR to read, then offer to open answer.md
  for writing. Closes the loop for the HUMAN-UAT HKUDS#5 scenario.
- `stop`: interactive confirm (--force to skip), kill tmux, run team
  cleanup, clear active pointer. --keep-data variant preserves team
  data for post-mortem.

Tests: 9 unit tests covering active-team pointer roundtrip, empty-state
messaging for all 3 read commands, stale-pointer detection, stop
clearing the pointer, --team flag override, dashboard field rendering.

E2E verified on CachyOS/fish:
  clawteam go "improve README"    → 24.5s, 11 tmux windows, rich Panel
  clawteam status                  → dashboard renders correctly
  clawteam stop --force            → tmux killed, data removed, pointer cleared

Addresses v1.0 UAT finding: the primary user flow requires 10+ command
invocations spanning team/sprint/launch/attend/tmux. After this change,
90% of the flow is 4 commands.

Note: no version bump — folded into v1.0 UAT validation scope per user
decision 2026-04-22.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
juntaochi added a commit to novix-science/ClawTeam-gstack that referenced this pull request Apr 27, 2026
User request: "用tmux hook 把prompt注入进每一轮对话 包括身份和需要用的
skill 或者用tmux hook去做一些别的事情 总之tmux hook会是一个很好的技术".

Concept: agents drift over long sessions. CEO forgets to delegate (user
just hit this bug), engineer forgets which `clawteam` subcommands are
available, shipper forgets that `/ship` lives in the framework. A
periodic re-injection of "you are X; here's what you should use"
keeps them anchored.

Implementation:

1. `clawteam nudge <pane_id>` CLI command (new clawteam/nudge.py):
   - Looks up pane_id → session → team → agent via the persisted
     tmux_pane_map.json
   - Debounces (60s cooldown per pane) so repeated silence-hook firings
     don't spam the claude TUI
   - Reads the latest sprint state (current_phase + goal) for context
   - Builds a role-specific reminder text from _ROLE_NUDGES table
     (each role gets 2-3 lines: what you ARE + what commands you CAN
     run now). Appends "Goal: X · Phase: Y" when available.
   - Injects via `tmux send-keys -l <text>` + `send-keys Enter` so
     claude processes it as a user turn.
   - Silent-fail on any error (a noisy hook drowns the user's tmux).

2. tmux hook wiring (tmux_backend.py::_configure_nudge_hook):
   - `monitor-silence = 45s` on each window
   - `alert-silence` hook fires `clawteam nudge #{pane_id}` in the
     background (`run-shell -b`)
   - Opt-out via `CLAWTEAM_NUDGE_SECONDS=0` env var
   - Called from both `TmuxBackend.tile_panes()` (happy path) and
     `TmuxBackend.enable_mouse()` (the --windows non-tiled path) so
     every team gets nudge wiring regardless of layout choice.

3. pane_map normalization (tmux_backend.py::tile_panes):
   - Post-layout readback of pane_title returned claude's dynamic
     status strings like "⠐ CEO" / "✢ ENG-MGR" (spinner glyphs prefix).
   - Normalize by matching uppercase title content against the
     pre-merge window roster (roster_upper dict). Any title containing
     a known role (e.g. "⠐ CEO" contains "CEO") maps to the canonical
     lowercase role name.
   - pane_map.json now reliably stores {"0": "ceo", "1": "pm", ...}
     regardless of what claude's currently showing.

Real-env verified:
  clawteam go --no-attach --no-window "test"
  cat ~/.clawteam/teams/<team>/tmux_pane_map.json  → clean lowercase roster
  clawteam status                                    → Panes: 0=ceo 1=pm ...
  # wait for claude to boot
  clawteam nudge --force <pane_id>                   → injects role reminder
  tmux capture-pane                                  → sees "[nudge] Reminder:
                                                      you DELEGATE, never
                                                      implement. Decompose..."

Future uses of this hook infrastructure (brainstormed but not impl):
  - HKUDS#3 pane-died → log death reason, optional respawn
  - HKUDS#5 alert-activity → append pane output to activity.jsonl timeline
  - HKUDS#6 session-created → broadcast phase+goal to all panes
  - HKUDS#7 send-keys filter → intercept dangerous commands (rm -rf, force push)
  - HKUDS#10 pipe-pane → validate agent envelope JSON against schema

Tests: 30 solo/spawn_cli still green (nudge unit tests not added yet
— next commit candidate).

Co-Authored-By: Claude Opus 4.7 (1M context) <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