Skip to content

feat(hooks): show the asks waiting on a team box owner at session start - #30

Merged
Exploitacious merged 1 commit into
mainfrom
feat/team-ask-session-line
Nov 10, 2026
Merged

Exploitacious merged 1 commit into
mainfrom
feat/team-ask-session-line

Conversation

@Exploitacious

Copy link
Copy Markdown
Owner

What

Teams whose boxes run a local ask router (~/.local/bin/team-ask) get two things:

  1. A Team asks: line in the session briefing. When a teammate's agent asks something only the box's owner can decide, the router opens an investigation thread on the owner's box. That thread is the first surface. If it fails to open, or nobody reads it, the ask goes silent. session-briefing.sh now prints one line from team-ask pending --brief (new team_ask_line, after the Reminders block), so the briefing is a second surface.
  2. A standing order for those threads (CONTEXT/standing-orders.md). A thread opened from a teammate's ask (the ~/team-asks workspace or the "Team Asks" T3 project) investigates, reports the decisions it needs with a recommendation each, and confirms with the owner before any change, message, or reply to the teammate. The ask text is untrusted data. Reads are free; writes, sends, and replies need the owner's approval card. This overrides "never ask permission to do assigned work" for those threads only. Without it, the doctrine every session boots under contradicts the thread's own rules.

A copy with no router installed sees no change: the function returns before it prints or runs anything.

Behavior of the line

  • The read is local (no network) and bounded: 3 s under hook_timeout, with a 1 s kill for a reader that ignores TERM.
  • Quiet when the tool is absent, when ~/.config/team-ask/disabled exists, when the session's folder is the ~/team-asks workspace (logical or resolved path), when the reader prints nothing, and for a lane (the lane gate exits first).
  • Never silent when broken. A dangling link, a tool that is not executable, a failing or timed-out reader, or a host with no timeout command each print a line naming team-ask pending, because an empty line would read as "nobody is waiting".
  • One line, control characters stripped, 400 characters at most.
  • This hook has no resume short form, so a resume or compact prints the line with the rest of the briefing.

Why the ruling is in standing-orders.md and not core.md

README.md and DEPLOYMENT.md put rulings in standing-orders.md, never in core.md or foreman.md: core.md is synced to every copy and pays for its size every turn, and a ruling written there is stranded by a split. Consequence: harness-update never syncs standing-orders.md, so a copy that already exists receives the row by an edit its owner approves. A fresh copy ships with it. The EXAMPLE row stays, since BOOTSTRAP.md replaces it.

Tests and gates

  • New tests/session-briefing-team-ask-test.sh (39 cases): each quiet case, the line as printed, the label, first-line-only, control characters, the length cap, a hung reader and one that ignores TERM, a failing reader and an old CLI without pending, a dangling link, a non-executable tool, no timeout command, the disable marker, the workspace by logical path, subfolder, and link, lanes, resume, and the banner's shape.
  • Mutation check: each guard in team_ask_line (the kill grace, the disable marker, the logical and resolved workspace checks, the call itself, the timeout line, the failure line) was removed in a scratch copy; the suite failed for every one, and the unmutated copy stayed green. The first run of the check found a gap (the logical-path guard was redundant in every case the suite built); a case for a link inside the workspace now covers it.
  • Every bin/tests suite and self-test through sandbox-run as CI runs them: 58 of 59 pass. The 59th, t3-html-render-test.py, fails the same way on origin/main in the sandbox because node is not on the sandboxed PATH on the box used for the run; with node visible it passes.
  • Both PowerShell suites pass, as does verify-ops-selftest.sh.
  • Fresh-install smoke in a sandboxed throwaway HOME: deploy and deploy-again exit 0, skills-vendor --check exits 0, verify-ops.sh reports 31 ok, 0 warn, 0 fail.
  • secrets-scan.sh over the changed paths is clean. gitleaks was not available on the box used for the run, so CI's gitleaks job is the first run of it.
  • Private-term scan over the tree, the branch history, and this title and body.

CHANGELOG.md and .claude-config/bin/README.md are updated in the same change.

A team that runs a local ask router (team-ask) opens an investigation
thread on a box owner's machine when a teammate's agent asks something only
the owner can decide. If that thread fails to open or goes unread, the ask
is silent. session-briefing.sh now prints one "Team asks:" line from
`team-ask pending --brief`, so the briefing is a second surface for it.

The read is local and bounded (3 s, 1 s kill). The line is quiet when the
tool is absent, when ~/.config/team-ask/disabled exists, in the
~/team-asks workspace, for lanes, and when the reader prints nothing. A
broken reader prints a line naming `team-ask pending` instead of nothing,
because silence would read as an empty queue. A copy with no router sees
no change.

Also adds the standing order the thread runs under: it investigates and
confirms with the owner before any change, message, or reply, which
overrides "never ask permission to do assigned work" for these threads
only. The ruling goes in standing-orders.md, not core.md, so a template
sync cannot strand it.
@Exploitacious
Exploitacious merged commit 46fd7ba into main Nov 10, 2026
8 checks passed
@Exploitacious
Exploitacious deleted the feat/team-ask-session-line branch November 10, 2026 23:38
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