Skip to content

fix(agents): decouple the delegation duty from hard rule 1's write exception - #25

Merged
prajwal-395 merged 1 commit into
mainfrom
fm/fm-delegation-rule
Aug 19, 2026
Merged

prajwal-395 merged 1 commit into
mainfrom
fm/fm-delegation-rule

Conversation

@prajwal-395

Copy link
Copy Markdown
Owner

Why

On 2026-08-19 the primary firstmate personally executed a branch prune across ten repositories instead of delegating it. The investigation traced the cause to upstream commit a24eac1 (2026-07-29, PR kunchenguid#1272), which rewrote AGENTS.md section 1's delegation sentence from an absolute rule into one gated on hard rule 1's captain-approved project-operation exception.

That commit's own message is entirely about write permission and never mentions delegation. The effect was that a rule about whether firstmate may write became the only boundary on whether firstmate must delegate, with no bound on magnitude. This is inherited from upstream rather than fork-local, and is fixed here in the fork.

Two factors compounded it. No rule anywhere in AGENTS.md stated what delegating is for, and a rule with no stated cost loses to a rule that has one. Section 7's "simplest direct end-to-end path" instruction has one, and although it means "do not build machinery" it reads as "do not add indirection" - and delegation is indirection.

Change 1 - decouple the delegation duty from the write exception

Section 1, before:

You are the captain's only point of contact for all software work across all of their projects.
Outside hard rule 1's concrete captain-approved project operation exception, you do not do project-specific work yourself.
For all other project-specific work, delegate coding, investigation, planning, bug reproduction, and audits to a crewmate you spawn and supervise, or to a secondmate whose registered scope fits.

After:

You are the captain's only point of contact for all software work across all of their projects.
Delegating is what keeps you reachable: work you do yourself blocks that only point of contact for as long as it runs, while work a crewmate does leaves you free to keep talking.
You do not do project-specific work yourself.
Delegate coding, investigation, planning, bug reproduction, and audits to a crewmate you spawn and supervise, or to a secondmate whose registered scope fits.
Hard rule 1's concrete captain-approved project operation exception lets you write to a project directly; it does not relieve you of delegating.
When an approved operation is large enough that running it yourself would keep you from answering the captain, brief and spawn a worker for it and tell the captain that is what you are doing.

The duty to delegate is now unconditional. The exception licenses writing, not not-delegating.

The one-project bound was omitted at the captain's instruction

The investigation's proposed wording also included the clause "and it never covers work spanning more than one project or more than a few minutes". The captain reviewed both variants and explicitly chose "decouple delegation from the exception, but do not add the one-project bound".

That clause is therefore deliberately absent from this change, at the captain's instruction. The change carries no project-count and no duration bound. The escalation trigger is grounded in the availability rationale instead: an approved operation gets briefed and spawned when running it would keep firstmate from answering the captain.

Change 2 - state why the rule exists

The rationale is now the second line of section 1, immediately after the "only point of contact" line:

Delegating is what keeps you reachable: work you do yourself blocks that only point of contact for as long as it runs, while work a crewmate does leaves you free to keep talking.

The substance of the proposal, drawn from firstmate's own Grok Bot doctrine, is preserved: availability is the reason, and self-executed work is what costs it. The two halves are joined so the sentence carries the cost in the same breath as the rule.

Change 3 - disambiguate the direct-path sentence

Section 7, before:

For one-off or infrequent operational work, start with the simplest direct end-to-end path.
Do not build wrappers, control planes, policy layers, custom verifiers, or automation unless the direct path exposes a concrete blocker or repeated need that justifies the added machinery.

After:

For one-off or infrequent operational work, start with the simplest direct end-to-end path, meaning do not build machinery around it.
Do not build wrappers, control planes, policy layers, custom verifiers, or automation unless the direct path exposes a concrete blocker or repeated need that justifies the added machinery.
Delegating that work to a crewmate is not machinery and is still the default.

Sites changed: 1. A repo-wide search for the sentence and its close variants (simplest direct, control planes, policy layers, added machinery) across AGENTS.md, .agents/skills/, public skills/, bin/, and docs/ returns this one location only. The near-identical line in the captain's personal global instructions lives outside this repository and is out of scope here.

Out of scope, verified unchanged

  • Hard rule 1's own text, including its exception sentence. Byte-identical to the base, proven below.
  • The other four hard rules.
  • Section 9, the escalation and etiquette contract.
  • The captain's personal global instructions file, which is not in this repository.

Only AGENTS.md is touched, 7 insertions and 3 deletions, so the change is close to net-neutral as the file's size discipline requires.

Verification

Hard rule 1 hashed at the merge base and at HEAD, plus the acceptance greps:

--- hard rule 1 must be byte-identical to the base ---
c282a98a5bde78e94dddfbf711ecd8e56247f718  -
c282a98a5bde78e94dddfbf711ecd8e56247f718  -
--- the exception no longer gates the delegation duty ---
0
--- the one-project bound must NOT be present ---
0
--- rationale present ---
1
--- direct-path sentence disambiguated everywhere ---
       1
       1

git diff --stat fork/main HEAD is a single file:

 AGENTS.md | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

Test suite

Full local suite run on the change:

FM_TEST_SUMMARY total=157 failed=4 skipped_gate=24 duration_ms=4025944

No test needed modification. This change edits prose only and alters no structure or documentation-audience mapping that the suite asserts on. Four scripts failed, and each was individually investigated and attributed to a cause other than this change:

1 and 2 - tests/fm-lint-workflows.test.sh and tests/fm-lint.test.sh: missing local actionlint. Both fail with exit 127, fm-lint-workflows.sh: actionlint not found; install actionlint 1.7.12 for CI parity. The pinned actionlint is not installed on this machine; ShellCheck 0.11.0 is present and passed. Nothing was installed system-wide to chase them. These pass in CI, which installs actionlint. This change touches no shell script and no workflow file, so it cannot affect either.

3 - tests/fm-backend-herdr-presentation-e2e.test.sh: load-induced, not merge-introduced. The failing assertion is "concurrent secondmate recovery failed ... error: herdr presentation recovery could not acquire its session lock; refusing a concurrent resume". Re-run standalone on this branch it passes: FM_TEST_SUMMARY total=1 failed=0 duration_ms=285069. The cause is a timing bound rather than a defect in the change under test: spawn_herdr_presentation_order_lock_acquire in bin/fm-spawn.sh retries 50 times at 0.1s, so it gives up after 5 seconds, while the concurrent peer holds the lock across a full recovery. Under whole-suite load that bound is exceeded.

It is also not a regression introduced by the upstream sync. The only change to bin/fm-spawn.sh between the pre-merge base 6a90309 and this branch is PR #23's relaunch-placement block, which is gated on RELAUNCH_ENDPOINT_MISSING and does not touch the presentation lock or the concurrent-recovery path that failed. The failing code path is identical on both sides of the merge. The herdr identity scrub is not implicated either: the test sets its own HERDR_SESSION from the lab helper and calls herdr_forget_inherited_pane first, so it is self-isolating.

4 - tests/fm-wake-queue.test.sh: pre-existing, reproduces without this commit. It fails on "the oversized unread status line was truncated or omitted", preceded by grep: out of memory. This one is not a load artifact - it reproduces standalone at low load. It was then run on fork/main with this commit absent and failed identically, same assertion and same grep: out of memory. It is therefore pre-existing on main and unrelated to this change, and is left for separate triage rather than widened into this PR.

Base

Rebased onto current fork/main (699b14a), which carries the upstream sync from PR #21 and PR #22, so the diff against main is this one commit.

…ception

Upstream commit a24eac1 (PR kunchenguid#1272) rewrote section 1's delegation sentence
from an absolute rule into one gated on hard rule 1's captain-approved project
operation exception. That commit's message is entirely about write permission
and never mentions delegation, so a rule about whether firstmate may write
became the only boundary on whether firstmate must delegate, with no bound on
magnitude.

Restore the unconditional delegation duty and let the exception license writing
only. State the reason the rule exists - delegating is what keeps firstmate
reachable - so the rule carries a cost the way the direct-path rule does.
Disambiguate the direct-path sentence, which means "do not build machinery" but
reads as "do not add indirection", by naming delegation as not machinery.

Per the captain's explicit ruling, the proposed one-project and few-minutes
bound is deliberately omitted; the escalation trigger is grounded in the
availability rationale instead of a project count or a clock.

Hard rule 1's own text is unchanged and byte-identical to the base.
@prajwal-395
prajwal-395 merged commit 3afdd55 into main Aug 19, 2026
12 checks passed
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