Skip to content

Run agent-commit unattended without the commit skill beside it #855

Description

@tbhb-agent

Problem

The unattended behavior of agent-commit (signing required, executable hooks required, repository lint command, bounded review rounds, held versus asked) is scattered through the shell and switched on by the DEVTOOLS_UNATTENDED environment variable (and the DT_UNATTENDED variable the shell also honors), which the wrappers set before running the sibling commit skill's scripts. Each rule widens an agent's authority if it slips, and the shell freeze in #588 rules out porting it ad hoc.

Part of #322, within #588. Child 06 in #322's Children list. Delivers in Go the unattended mode of agentrepo commit (--unattended), covering the behavior of the agent-commit scripts under packages/agents/source/skills/agent-commit/shared/scripts/ and packages/agents/source/lib/agent.sh.

Acceptance criteria

  1. AC1: Given --unattended, when agentrepo commit runs, then it never asks a question, and missing authority exits 75.
  2. AC2: Given --unattended with --confirmed, when the command runs, then it refuses and names pre-approval and delegation.
  3. AC3: Given unattended mode, when the command commits, then it signs the commit, and a signing failure holds with exit 75, keeps the draft and index, and never falls back to an unsigned commit.
  4. AC4: Given unattended mode, when preflight or write runs, then missing signing and missing executable hooks each refuse or hold with the matching message; these two prerequisites are not added to the review entry point.
  5. AC5: Given unattended mode, when preflight, review or write runs, then an initial (root) commit is refused; a detached head is refused; a validated base merge is permitted; and any other interrupted operation is refused, at each of the three entry points.
  6. AC6: Given lint_commit_cmd in repository configuration, when unattended mode runs, then that command is the commit-message gate and an empty value fails closed, and the full repository lint still runs.
  7. AC7: Given repeated review findings on one staged tree, when the configured round bound is reached, then the command exits 3 without invoking the reviewer again; given a different tree, then the count restarts; given an unreadable review, then no round is spent; given a rejected draft, then the redesign lifecycle behaves as the shell does today; given a successful commit, then the counter clears.
  8. AC8: Given a hook that rewrites the message, the tree or the branch during an unattended commit, when verification runs, then it fails, the commit and review evidence stay, and the workflow does not move the branch.
  9. AC9: Given repository configuration with duplicate keys, a symlink or a machine-only key, when unattended mode runs, then it fails closed and never lets the repository choose the reviewer, delegation checker or identity.
  10. AC10: Given repository configuration that changes while the reviewer runs, when the review ends, then no stamp is written; given configuration changed after an existing stamp, when unattended mode reaches the write, then it refuses.
  11. AC11: Given --unattended, or the environment without the flag, when agentrepo commit runs during the compatibility window, then unattended mode is entered by the flag, or by the variables resolved as the shell resolves them: DEVTOOLS_UNATTENDED is read first; DT_UNATTENDED is read only when DEVTOOLS_UNATTENDED is unset (an empty DEVTOOLS_UNATTENDED does not fall back); and only the value 1 counts. The flag is the documented entry.
  12. AC12: Non-functional: neither DEVTOOLS_UNATTENDED nor DT_UNATTENDED, nor any other internal unattended marker, is present in the environment of the repository's own gates or of any child process the command starts, whichever way unattended mode was entered.

Scope and non-goals

Scope: the --unattended mode across the agentrepo commit subcommands, with --unattended as the primary interface. Go keeps reading the environment variables through the N-2 compatibility window so that devtools bumps need zero configuration changes, with the shell's resolution at packages/agents/source/lib/lib.sh:34-36 (${DEVTOOLS_UNATTENDED-${DT_UNATTENDED:-0}}, then unexported): DEVTOOLS_UNATTENDED first, DT_UNATTENDED as the fallback only when the first is unset, only the value 1 counting, and neither variable passed to child processes.

Non-goal: agent-pr and agent-merge-pr, which keep their own areas. Non-goal: changing the delegation or pre-approval contracts. Non-goal: implementing the shared policy, round and signing mechanics, which #321 delivers; this child integrates them and tests the unattended outcomes. Non-goal: switching any shell wrapper, which child 07 handles. Non-goal: removing the environment reads, which happens after the N-2 window in the same final cleanup issue under #588 that deletes the shell; that cleanup removes both DEVTOOLS_UNATTENDED and DT_UNATTENDED.

Approach

Meet AC1 to AC12 with failing cases first, porting the agent-commit Bats suites' cases. The flag is the primary entry; the variable read exists only for compatibility and is covered by its own precedence and isolation cases.

Dependencies

Blocked by: #851, #852, #854.

Prerequisites: the unattended policy, bounded review rounds and signing deliverables of #321.

Size

M. One pull request.

Verify plan

  • AC1, AC2: ported cases from tests/skills/agent-commit/workflow.bats with no-authority, grant and refusal stubs.
  • AC3, AC8: tests with failing signing and hooks that mutate message, tree or branch (including a hook that moves the branch, as workflow.bats does).
  • AC4: tests with missing signing and missing hooks at preflight and write, and a test that the review entry point does not check them.
  • AC5: ported cases from tests/skills/agent-commit/workflow.bats and the base-merge permit and refusal cases from tests/skills/agent-commit/base-merge.bats, run at preflight, review and write.
  • AC6, AC9: configuration fixtures including duplicates and a symlink.
  • AC7: tests over three rounds, tree changes, unreadable reviews, a rejected draft and a successful commit.
  • AC10: tests with a stub reviewer that edits the repository configuration while it runs (no stamp), and a test that edits it after an existing stamp (write refused).
  • AC11: parity checks that run the shell and Go on the same environments and compare the outcome: the flag alone; DEVTOOLS_UNATTENDED=1 alone; DT_UNATTENDED=1 alone; both set with different values (each ordering of 1 and 0); DEVTOOLS_UNATTENDED set to the empty string with DT_UNATTENDED=1 (no fallback, so not unattended); and values other than 1, which do not enter the mode.
  • AC12: a test shows the gate environment and a child process each lack both variables for each way of entering the mode, including a child process started with neither variable set that inherits neither.
  • Definition of done: D1 each AC is verified at the merged head, with the commands and results cited in the pull request's Verification. D2 an independent review approves the exact merged head, and every finding has a recorded disposition. D3 required checks pass with no gate loosened. D4 the leak scans the repository specifies are clean, and every post made for this work passes the per-post leak review before it is posted. D5 every commit is signed. D6 the documentation matches the change or the Verification says why there is no impact. D7 every commit has an Assisted-by trailer and the pull request has the provenance:agent-assisted label. D8 the pull request stays within the size limits. D9 follow-ups are filed as issues and listed under Related. D10 the merge closes the issue through a closing reference, the board shows Done, and the final Status: comment names the merge commit.

Risks

This is the path that commits without a person present, so any slip in AC1 to AC3 widens an agent's authority. The refusal cases are the control. Undo: revert the change; no caller uses the mode until child 07.

Operator authority

None.

Activity

  1. tbhb-agent commented on Oct 27, 2026

    @tbhb-agent
    ContributorAuthor

    Refinement: READY — Run agent-commit unattended without the commit skill beside it
    Model: gpt-6-astra

    Child 06 Run agent-commit unattended without the commit skill beside it

    Verdict: READY

    Checked: The environment amendment matches packages/agents/source/lib/lib.sh:35: DEVTOOLS_UNATTENDED takes precedence even when empty, and DT_UNATTENDED supplies the fallback only when the primary variable is unset. Mode checks require the literal value 1, for example at packages/agents/source/skills/commit/shared/scripts/commit.sh:81. Both variables are unexported at packages/agents/source/lib/lib.sh:36. AC11 and AC12 explicitly assign precedence and isolation checks.

    The prior findings remain closed:

    • Signing and hook prerequisites are distinguished from operation eligibility, including direct review eligibility at packages/agents/source/lib/lib.sh:567.
    • Configuration changes during review prevent stamping; changes after stamping invalidate authorization at packages/agents/source/lib/lib.sh:615 and packages/agents/source/lib/lib.sh:695.
    • Bounded findings, redesign and successful cleanup are covered by the contract and verification plan, consistent with packages/agents/source/lib/agent.sh:93 and packages/agents/source/lib/lib.sh:715.
    • Verification preserves evidence without undoing hook-driven branch movement, matching tests/skills/agent-commit/workflow.bats:261.

    Every AC has an assigned check. Shared mechanics remain #321’s responsibility, wrapper switching remains separately owned, and compatibility removal remains outside this child. Scope, dependencies, risks, undo and operator authority are consistent. No implementation layout is prescribed.

    Gaps: None.

    Split: None. M remains credible with shared policy, rounds and signing supplied by #321.

    Definition of done

    The definition of done for this issue (Feature). Tick each item and give its evidence.

    • D1 The author verified each AC on the merged head, and the Verification section of the pull request cites each AC ID with its evidence: the command and its result, or a link.
    • D2 An independent reviewer approved the exact merged head, and the author resolved each finding or filed it as a follow-up.
    • D3 The required checks pass on that head, and any loosened gate has the owner's approval of that exact head.
    • D4 The leak scans come back clean: gitleaks, devtools' check-leaks.sh with the repository's private-strings list, and the leak review of each post.
    • D5 The author signed each commit, the squash included.
    • D6 The docs match the change (README, docs/, CHANGELOG or help text), or the Verification section says "No doc impact" and why.
    • D7 The commits and the squash have Assisted-by trailers, and the pull request has the provenance:agent-assisted label.
    • D8 The pull request stays within the size limits, or the owner approved its exact head over the hard limit.
    • D9 The author files follow-ups and deferred findings as issues with at least a Problem and numbered AC and lists them under the Related section of the pull request. Any work left in the code links its issue.
    • D10 The merge closes the issue through a closing reference and the board shows Done. The final Status: comment names the merge commit.
    • devtools-1 mise run check is green, and so are the coverage floors mise run cover-go-check and mise run cover-py-check, which check doesn't run.
    • devtools-2 A change to skill sources under packages/agents/source/ commits what mise run generate-skills, then mise run skill-tokens, then apm install rewrite, in that order, and check-generated-skills (part of lint) passes.
    • devtools-3 A consumer-visible change (the vendored payload, a skill, a reusable workflow, a task or a pin) has its consumer steps in docs/agent-skills-migration.md or the adoption docs, or the PR's Verification says "No consumer impact" and why.

    Round: 1 of 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    refinement:readyPassed the Definition of Ready; may be picked up

    Fields

    Priority

    None yet

    Work type

    None yet

    Projects

    • Status
      Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions