Skip to content

feat(agents): adopt the Operator Communication Standard for captain-facing messages - #1390

Open
sbracewell64 wants to merge 4 commits into
kunchenguid:mainfrom
sbracewell64:fm/operator-comms-fleet-doctrine
Open

feat(agents): adopt the Operator Communication Standard for captain-facing messages#1390
sbracewell64 wants to merge 4 commits into
kunchenguid:mainfrom
sbracewell64:fm/operator-comms-fleet-doctrine

Conversation

@sbracewell64

Copy link
Copy Markdown

Intent

Implement the captain-ruled Operator Communication Standard across all captain-facing FirstMate communication, per rulings D1=B and D3=A. Rewrite AGENTS.md section 9 at net non-positive LF-normalized bytes to add action-or-outcome-first hierarchy, atomic decision questions with labeled recommendation/exact reply cue/stable IDs, boundary-only state restoration, visible Complete: outcomes, durable tangent suppression with urgent safety interruption, and response-count-first honest operator-effort estimates, while preserving every safety boundary, hard-rule reference, escalation trigger, and the internal-term translation rule. Fund the doctrine by compressing only lexical translation enumeration and adjacent duplicate escalation prose. Have ask-user-authority and decision-hold-lifecycle reference section 9 rather than restate it; add section-9 operator-effort/reply cues only to Captain's Call-class items in Bearings and Ahoy without changing their existing structures. Do not create a communication skill, always-loaded surface, runtime enforcement, machine prose-quality enforcement, or platform FIRSTMATE growth. The PR body must state section 9 before/after byte counts, checklist all preserved safety boundaries and escalation triggers, and include sample decision, completion, and failure transcripts in the new grammar.

What Changed

  • Rewrote AGENTS.md section 9 to lead with the captain's action or the verified outcome, require atomic decision questions carrying a labeled recommendation, consequences, an exact reply cue and a short captain-facing ID (D1/Q7, never an internal key), restore state only at resumptions/question rounds/blockers/completions, prefix triggered completions with Complete:, state operator effort as a response count first, and hold tangents to the next natural boundary except for urgent safety, destructive, irreversible, or security consequences.
  • Funded the new doctrine by compressing the eleven-item lexical translation list into five translation families and folding the duplicate escalation/objection prose into one sentence: section 9 goes from 4142 to 4140 LF-normalized bytes (net −2), with no new always-loaded surface, communication skill, or runtime enforcement.
  • Pointed the skills at section 9 instead of restating it — ask-user-authority and decision-hold-lifecycle now defer to it for grammar and keep only their decision content; bearings and ahoy scope the decision grammar to Captain's Call-class items only; fmx-respond explicitly excludes the captain-facing grammar from public replies — and updated the README Quick Start transcript to the new grammar (the Document step flagged this as a judgment call: the public README now demonstrates the Complete: prefix, reply cue, and response-count effort).

Section 9 budget

Bytes (LF-normalized)
Before (f7d0d0a) 4142
After (32c0c63) 4140
Net −2

Preserved safety boundaries

  • Talk-in-outcomes rule and the internal-term translation requirement
  • Forbidden internal surfaces, including compressed safety labels (fail-closed / fail-open variants)
  • Never relay worker reports, status lines, tool output, validation labels, or decision records verbatim
  • Private evidence reports may keep exact identifiers and paths; their captain-facing summaries still translate
  • Evidence-first form for escalations, objections, and clarifying challenges rather than unsupported deference
  • Exact Captain, shipshape. reply for no-action routine operational updates
  • No automatic fixes, retries, routine progress, or supervision mechanics surfaced; non-urgent updates batched
  • Full https://... PR URL before any shorthand reference
  • Plain chat for a yes-or-no decision, lavish-axi only for multi-option or structured surfaces
  • Cost mentioned as a courtesy, never as a blocker
  • decision-hold-lifecycle still bans the word "hold" in captain chat

Preserved escalation triggers

  • Work ready for review, with the full PR URL
  • Finished investigation findings, relayed as findings rather than a bare completion notice
  • Gate findings requiring the captain's decision under the configured authority
  • A real blocker or failure after the relevant playbook is exhausted
  • Anything destructive, irreversible, or security-sensitive
  • A needed credential or login

Sample transcripts in the new grammar

Decision

Captain, D1: ship the login fix behind the existing flag now, or hold it for the auth review?
Recommendation: ship behind the flag - the review is three days out and the flake is blocking two PRs.
Holding means CI keeps failing on that test until the review lands.
Reply "D1 = ship" or "D1 = hold" - 1 reply.

Completion

Complete: the flaky login test is fixed, captain - CI green, risk low.
Ready for your review: https://github.com/you/xyz/pull/42
Reply "merge it" to ship, or name the changes you want - 1 reply.

Failure

Captain, the release check cannot finish: the publishing credential expired this morning.
Nothing shipped and the branch is untouched; every retry the playbook allows is spent.
Send a fresh credential and I will rerun - 1 reply.

Risk Assessment

✅ Low: The change is documentation-only and well-bounded, every prior-round finding is resolved with all three captain rulings applied exactly as specified, section 9 stays within its net non-positive byte budget at -2, and re-funding came solely from the sanctioned lexical-enumeration and duplicate-escalation-prose sources.

Testing

Ran the four existing tests that own the touched skills and documentation surfaces (ask-user-authority, decision-hold-lifecycle, bearings-snapshot's 25 Captain's Call cases, documentation-audiences) - all pass. Because no existing test asserts section 9's content, I added focused verification in the evidence directory: 79 acceptance checks confirming the -2 byte section 9 budget, every required D1=B/D3=A doctrine element as newly added, all 18 preserved rules, all six escalation triggers, all 11 translation term families, the compression funding scope, skill pointers that reference rather than restate, unchanged Bearings/Ahoy structures, and the absence of every forbidden surface. For end-user evidence I wrote decision, completion, and failure transcripts in the new grammar and scored them with a checker whose rules are asserted to exist verbatim in section 9 at 959913c - new grammar 28/28, pre-change grammar 10/28, proving the checker discriminates rather than passing everything. No PNG screenshot was possible: this environment has no Chrome binary (chrome-devtools-axi fails with "Target closed"), no PIL, cairosvg, or SVG rasterizer, and installing them is outside the worktree boundary, so the reviewer-visible surface is delivered as a rendered HTML artifact plus a self-contained SVG rendering. Worktree left clean and the temporary local HTTP server used during the browser attempt was stopped.

  • Evidence: Captain's reading surface - before/after transcripts with per-rule scoring (SVG rendering) (local file: /tmp/no-mistakes-evidence/01KYW2035D65G22499EC60TYNC/captain-surface.svg)
Evidence: Captain's reading surface - rendered HTML artifact (byte tiles, transcripts, preserved-boundary cards)
<!doctype html><html><head><meta charset="utf-8"><title>Operator Communication Standard — captain-facing evidence</title>
<style>
*{box-sizing:border-box;min-width:0}
body{margin:0;background:#0b1220;color:#dbe4f0;font:15px/1.55 ui-sans-serif,-apple-system,"Segoe UI",sans-serif}
.wrap{max-width:1180px;margin:0 auto;padding:34px 26px 60px}
h1{font-size:26px;margin:0 0 6px;letter-spacing:-.01em}
.sub{color:#8ea3bf;margin:0 0 24px;font-size:14px}
.bytes{display:flex;gap:14px;flex-wrap:wrap;margin:0 0 30px}
.tile{background:#111c2f;border:1px solid #1e2f4a;border-radius:10px;padding:13px 17px;min-width:170px}
.tile .k{font-size:11px;text-transform:uppercase;letter-spacing:.09em;color:#7f95b3}
.tile .v{font:600 21px/1.2 ui-monospace,SFMono-Regular,Menlo,monospace;margin-top:5px}
.tile.good .v{color:#5fd39b}
h2{font-size:16px;margin:0 0 12px;color:#a9c0e0;font-weight:600}
.case{margin:0 0 30px}
.pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:16px}
.col{border:1px solid #1e2f4a;border-radius:12px;overflow:hidden;background:#0f1829;display:flex;flex-direction:column}
.col.after{border-color:#2c5c46}
.colhead{display:flex;justify-content:space-between;align-items:center;gap:8px;padding:9px 14px;background:#152139;font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:#8ea3bf}
.col.after .colhead{background:#12281f;color:#8fd9b4}
.badge{font:600 11px ui-monospace,monospace;background:#3a2230;color:#f0a0a8;padding:2px 8px;border-radius:20px;white-space:nowrap}
.col.after .badge{background:#143a29;color:#6ee7a8}
.chat{padding:14px}
.who{font-size:11px;color:#61789a;margin-bottom:7px;letter-spacing:.05em}
pre{margin:0;padding:13px 15px;background:#0a1526;border:1px solid #1c2b45;border-left:3px solid #4b74b8;border-radius:8px;
 font:13px/1.62 ui-monospace,SFMono-Regular,Menlo,monospace;white-space:pre-wrap;word-break:break-word;color:#e6edf7}
.col.after pre{border-left-color:#3fae7a}
.checks{list-style:none;margin:0;padding:4px 14px 14px;font-size:12.5px}
.checks li{display:flex;gap:8px;padding:2.5px 0;align-items:flex-start}
.checks .mark{width:13px;flex:none;font-weight:700}
.checks .p{color:#9db6d4} .checks .p .mark{color:#4ec98a}
.checks .f{color:#c9899a} .checks .f .mark{color:#e5657f}
.grid3{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr) minmax(0,1fr);gap:16px;margin-top:8px}
.card{background:#0f1829;border:1px solid #1e2f4a;border-radius:12px;padding:15px 17px}
.card h3{margin:0 0 10px;font-size:13px;color:#a9c0e0;letter-spacing:.03em}
.card ul{list-style:none;margin:0;padding:0;font-size:12.5px}
.card li{padding:4px 0 4px 19px;position:relative;color:#c2d2e6;border-top:1px solid #16233a}
.card li:first-child{border-top:0}
.card li:before{content:"✓";position:absolute;left:0;color:#4ec98a;font-weight:700}
.card li b{display:block;color:#e6edf7;font-weight:600}
.card li span{display:block;color:#7f95b3;font-size:11.5px;margin-top:1px}
.foot{margin-top:26px;font-size:12px;color:#61789a;border-top:1px solid #1a2740;padding-top:14px}
</style></head><body><div class="wrap">
<h1>Operator Communication Standard — what the captain now reads</h1>
<p class="sub">AGENTS.md section 9 rewrite · base <code>f7d0d0a</code> → <code>959913c</code> · transcripts checked against section 9's own rules</p>
<div class="bytes">
  <div class="tile"><div class="k">Section 9 before</div><div class="v">4142 B</div></div>
  <div class="tile"><div class="k">Section 9 after</div><div class="v">4140 B</div></div>
  <div class="tile good"><div class="k">Net change</div><div class="v">-2 B</div></div>
  <div class="tile good"><div class="k">Acceptance checks</div><div class="v">79 / 79</div></div>
</div>
<section class="case"><h2>Decision — a Captain's Call that needs the captain's own action</h2><div class="pair"><div class="col before">
      <div class="colhead"><span class="era">BEFORE — pre-change grammar</span><span class="badge">3/11 rules</span></div>
      <div class="chat"><div class="who">firstmate → captain</div><pre>Captain, the scout finished looking at the auth rate limiter. It read the
credential-stuffing report, checked how the current limiter behaves under load,
and compared that against what the API team asked for. The API team wants a cap
of 20 requests per minute. The security review suggests something lower would be
safer, though there is a trade-off with the integrations. Let me know what you
think about the cap and I will get it moving.</pre></div>
      <ul class="checks"><li class="p"><span class="mark">✓</span>addresses the captain</li><li class="p"><span class="mark">✓</span>no internal terms leak</li><li class="p"><span class="mark">✓</span>full PR URL when a PR is named</li><li class="f"><span class="mark">✗</span>operator effort states the response count first</li><li class="f"><span class="mark">✗</span>leads with the captain&#x27;s action, not context</li><li class="f"><span class="mark">✗</span>exactly one atomic decision question</li><li class="f"><span class="mark">✗</span>labeled recommendation</li><li class="f"><span class="mark">✗</span>states the consequence of the other choice</li><li class="f"><span class="mark">✗</span>exact reply cue</li><li class="f"><span class="mark">✗</span>stable captain-facing decision ID</li><li class="f"><span class="mark">✗</span>reply cue uses the same stable ID</li></ul>
    </div><div class="col after">
      <div class="colhead"><span class="era">AFTER — new grammar</span><span class="badge">11/11 rules</span></div>
      <div class="chat"><div class="who">firstmate → captain</div><pre>Captain, one call is yours.

D1 - Ship the auth rate-limit fix at 5 requests per minute, or the 20 the API team asked for?
Recommendation: 5 per minute. The security review found the credential-stuffing gap only closes below 10; at 20 it stays open.
Consequence: choosing 20 lands the fix but leaves that gap open as accepted risk.
Reply &quot;D1: 5&quot; or &quot;D1: 20&quot;.
That is 1 reply from you, and nothing else until the fix is ready for your review.</pre></div>
      <ul class="checks"><li class="p"><span class="mark">✓</span>addresses the captain</li><li class="p"><span class="mark">✓</span>no internal terms leak</li><li class="p"><span class="mark">✓</span>full PR URL when a PR is named</li><li class="p"><span class="mark">✓</span>operator effort states the response count first</li><li class="p"><span class="mark">✓</span>leads with the captain&#x27;s action, not context</li><li class="p"><span class="mark">✓</span>exactly one atomic decision question</li><li class="p"><span class="mark">✓</span>labeled recommendation</li><li class="p"><span class="mark">✓</span>states the consequence of the other choice</li><li class="p"><span class="mark">✓</span>exact reply cue</li><li class="p"><span class="mark">✓</span>stable captain-facing decision ID</li><li class="p"><span class="mark">✓</span>reply cue uses the same stable ID</li></ul>
    </div></div></section><section class="case"><h2>Completion — work finished and reaching the captain</h2><div class="pair"><div class="col before">
      <div class="colhead"><span class="era">BEFORE — pre-change grammar</span><span class="badge">3/6 rules</span></div>
      <div class="chat"><div class="who">firstmate → captain</div><pre>Captain, the auth rate-limit work is finished. The fix went in at 5 requests per
minute, the review came back clean, and the checks are green. The PR is
https://github.com/kunchenguid/firstmate/pull/1390 whenever you get a chance.</pre></div>
      <ul class="checks"><li class="p"><span class="mark">✓</span>addresses the captain</li><li class="p"><span class="mark">✓</span>no internal terms leak</li><li class="p"><span class="mark">✓</span>full PR URL when a PR is named</li><li class="f"><span class="mark">✗</span>operator effort states the response count first</li><li class="f"><span class="mark">✗</span>leads with `Complete:` and a concrete result</li><li class="f"><span class="mark">✗</span>restores enough state to act at this boundary</li></ul>
    </div><div class="col after">
      <div class="colhead"><span class="era">AFTER — new grammar</span><span class="badge">6/6 rules</span></div>
      <div class="chat"><div class="who">firstmate → captain</div><pre>Complete: the auth rate-limit fix is ready for your review at 5 requests per minute, captain.

https://github.com/kunchenguid/firstmate/pull/1390 - checks passing, the credential-stuffing gap closed and covered by a new test.
Where things stand: this was the only work under way, and nothing else is waiting on you.
That is 1 reply from you to approve the merge.</pre></div>
      <ul class="checks"><li class="p"><span class="mark">✓</span>addresses the captain</li><li class="p"><span class="mark">✓</span>no internal terms leak</li><li class="p"><span class="mark">✓</span>full PR URL when a PR is named</li><li class="p"><span class="mark">✓</span>operator effort states the response count first</li><li class="p"><span class="mark">✓</span>leads with `Complete:` and a concrete result</li><li class="p"><span class="mark">✓</span>restores enough state to act at this boundary</li></ul>
    </div></div></section><section class="case"><h2>Failure — a real blocker after the playbook is exhausted</h2><div class="pair"><div class="col before">
      <div class="colhead"><span class="era">BEFORE — pre-change grammar</span><span class="badge">4/11 rules</span></div>
      <div class="chat"><div class="who">firstmate → captain</div><pre>Captain, some background on the auth rate limiter. While validating the fix we
noticed the payments integration retries aggressively - about 12 requests per
minute from a single account - and the new cap rejects those, so payment retries
started failing. We tried a couple of things and none of them worked. There is
an option to narrow the limit per account, and an option to wait for the API
team. Thoughts?</pre></div>
      <ul class="checks"><li class="p"><span class="mark">✓</span>addresses the captain</li><li class="p"><span class="mark">✓</span>no internal terms leak</li><li class="p"><span class="mark">✓</span>full PR URL when a PR is named</li><li class="f"><span class="mark">✗</span>operator effort states the response count first</li><li class="f"><span class="mark">✗</span>leads with the captain&#x27;s action, not context</li><li class="p"><span class="mark">✓</span>exactly one atomic decision question</li><li class="f"><span class="mark">✗</span>labeled recommendation</li><li class="f"><span class="mark">✗</span>states the consequence of the other choice</li><li class="f"><span class="mark">✗</span>exact reply cue</li><li class="f"><span class="mark">✗</span>stable captain-facing decision ID</li><li class="f"><span class="mark">✗</span>reply cue uses the same stable ID</li></ul>
    </div><div class="col after">
      <div class="colhead"><span class="era">AFTER — new grammar</span><span class="badge">11/11 rules</span></div>
      <div class="chat"><div class="who">firstmate → captain</div><pre>Captain, the auth rate-limit fix cannot land as written, and the next move is yours.

D2 - Narrow the limit to per-account, or pause this fix until the API team changes the shared client?
Evidence: the payments integration retries 12 requests per minute from one account, the new cap rejects them, and payment retries fail.
Recommendation: narrow it to per-account. That closes the credential-stuffing gap and keeps payments working; the shared-client change needs its own PR.
Consequence: pausing leaves the gap open until that separate change lands.
Reply &quot;D2: narrow&quot; or &quot;D2: pause&quot;.
That is 1 reply from you. I have exhausted the retry playbook, so nothing moves until you choose.</pre></div>
      <ul class="checks"><li class="p"><span class="mark">✓</span>addresses the captain</li><li class="p"><span class="mark">✓</span>no internal terms leak</li><li class="p"><span class="mark">✓</span>full PR URL when a PR is named</li><li class="p"><span class="mark">✓</span>operator effort states the response count first</li><li class="p"><span class="mark">✓</span>leads with the captain&#x27;s action, not context</li><li class="p"><span class="mark">✓</span>exactly one atomic decision question</li><li class="p"><span class="mark">✓</span>labeled recommendation</li><li class="p"><span class="mark">✓</span>states the consequence of the other choice</li><li class="p"><span class="mark">✓</span>exact reply cue</li><li class="p"><span class="mark">✓</span>stable captain-facing decision ID</li><li class="p"><span class="mark">✓</span>reply cue uses the same stable ID</li></ul>
    </div></div></section>
<section class="case"><h2>Doctrine added, and everything that had to survive it</h2>
<div class="grid3">
  <div class="card"><h3>New doctrine (D1=B, D3=A)</h3><ul><li><b>Action-or-outcome-first hierarchy</b><span>Lead with the captain&#x27;s action or the outcome.</span></li><li><b>Atomic decision question</b><span>Make each decision one unmistakable question…</span></li><li><b>Labeled recommendation + exact reply cue</b><span>…with a labeled recommendation, consequences, and an exact reply cue.</span></li><li><b>Stable captain-facing IDs</b><span>a short captain-facing label like D1 or Q7, never an internal key</span></li><li><b>Boundary-only state restoration</b><span>At a resumption, question round, blocker, or completion… do not recap every turn.</span></li><li><b>Visible Complete: outcomes</b><span>Start a completion… with Complete: and name the concrete result.</span></li><li><b>Response-count-first operator effort</b><span>State operator effort as the response count first…</span></li><li><b>Durable tangent suppression + urgent interrupt</b><span>…but interrupt immediately for urgent safety, destructive, irreversible, or security consequences.</span></li></ul></div>
  <div class="card"><h3>Safety boundaries preserved</h3><ul><li>Outcome-translation mandate</li><li>Captain&#x27;s-noun vocabulary</li><li>Internal-term exposure ban</li><li>Scout / second mate carve-out</li><li>Internal-term translation rule (all 11 families)</li><li>Never relay reports verbatim</li><li>Private-evidence-report exception</li><li>Evidence-first escalation &amp; objections</li><li>No routine-mechanics surfacing</li><li>Exact “Captain, shipshape.” reply</li><li>Batch non-urgent updates</li><li>Plain chat vs lavish-axi surface rule</li><li>Full PR URL before shorthand</li><li>Cost courtesy never blocks</li></ul></div>
  <div class="card"><h3>Escalation triggers preserved</h3><ul><li>Work ready for review, with the full PR URL</li><li>Finished investigation findings, relayed as findings</li><li>Gate findings requiring a decision under configured authority</li><li>A real blocker or failure after the playbook is exhausted</li><li>Anything destructive, irreversible, or security-sensitive</li><li>A needed credential or login</li></ul></div>
</div></section>
<p class="foot">Transcripts are written by applying section 9 as landed; the pass/fail marks come from a checker whose rules are asserted to exist verbatim in section 9 at 959913c. Old-grammar columns are shown to prove the checker discriminates rather than passing everything.</p>
</div></body></html>
Evidence: Sample decision transcript in the new grammar (11/11 section 9 rules)
Captain, one call is yours.

D1 - Ship the auth rate-limit fix at 5 requests per minute, or the 20 the API team asked for?
Recommendation: 5 per minute. The security review found the credential-stuffing gap only closes below 10; at 20 it stays open.
Consequence: choosing 20 lands the fix but leaves that gap open as accepted risk.
Reply "D1: 5" or "D1: 20".
That is 1 reply from you, and nothing else until the fix is ready for your review.

[PASS] addresses the captain
[PASS] no internal terms leak
[PASS] full PR URL when a PR is named
[PASS] operator effort states the response count first
[PASS] leads with the captain's action, not context
[PASS] exactly one atomic decision question
[PASS] labeled recommendation
[PASS] states the consequence of the other choice
[PASS] exact reply cue
[PASS] stable captain-facing decision ID
[PASS] reply cue uses the same stable ID
Evidence: Sample completion transcript in the new grammar (6/6 section 9 rules)
Complete: the auth rate-limit fix is ready for your review at 5 requests per minute, captain.

https://github.com/kunchenguid/firstmate/pull/1390 - checks passing, the credential-stuffing gap closed and covered by a new test.
Where things stand: this was the only work under way, and nothing else is waiting on you.
That is 1 reply from you to approve the merge.

[PASS] leads with `Complete:` and a concrete result
[PASS] restores enough state to act at this boundary
[PASS] operator effort states the response count first
Evidence: Acceptance verification transcript - 79/79 checks (byte budget, doctrine, preserved boundaries, triggers, forbidden surfaces)
==============================================================================
OPERATOR COMMUNICATION STANDARD - acceptance verification
base f7d0d0a -> head 959913c
==============================================================================

--- 1. Byte budget (LF-normalized) ------------------------------------
  AGENTS.md section 9 before : 4142 bytes
  AGENTS.md section 9 after  : 4140 bytes
  net delta                  : -2 bytes
  whole AGENTS.md delta      : -2 bytes

--- 2. Required doctrine added (rulings D1=B, D3=A) --------------------
  [PASS] action-or-outcome-first hierarchy
  [PASS] atomic decision question
  [PASS] labeled recommendation
  [PASS] exact reply cue
  [PASS] stable captain-facing decision IDs
  [PASS] boundary-only state restoration
  [PASS] visible `Complete:` outcomes
  [PASS] durable tangent suppression
  [PASS] urgent safety interruption overrides suppression
  [PASS] response-count-first honest operator effort

--- 3. Preserved safety boundaries and rules ---------------------------
  [PASS] outcome-translation mandate
  [PASS] captain's-noun vocabulary rule
  [PASS] internal-term exposure ban
  [PASS] scout / second mate house-vocabulary carve-out
  [PASS] translate-before-sending rule
  [PASS] never-relay-verbatim rule
  [PASS] read-as-evidence rule
  [PASS] private-evidence-report exception
  [PASS] captain-facing summary still follows the rule
  [PASS] evidence-first escalation, standalone and concise
  [PASS] objection/challenge uses the same evidence-first form
  [PASS] recommendation over unsupported deference
  [PASS] no routine-mechanics surfacing
  [PASS] exact `Captain, shipshape.` reply
  [PASS] batch non-urgent updates
  [PASS] plain chat vs lavish-axi surface rule
  [PASS] full PR URL before shorthand
  [PASS] cost courtesy never blocks

--- 4. Escalation triggers preserved (all six) -------------------------
  trigger bullet count: before=6 after=6
  [PASS] work ready for review, with the full PR URL
  [PASS] finished investigation findings relayed as findings
  [PASS] gate findings needing a decision under configured authority
  [PASS] real blocker or failure after the playbook is exhausted
  [PASS] anything destructive, irreversible, or security-sensitive
  [PASS] a needed credential or login

--- 5. Internal-term translation rule: every base term family survives --
  [PASS] worktree/checkout/local copy
  [PASS] teardown -> cleanup
  [PASS] wake / liveness
  [PASS] hold / gate / ask-user
  [PASS] status & validation labels
  [PASS] brief -> instructions
  [PASS] crewmate -> worker
  [PASS] harness/backend/runtime/adapter -> tool
  [PASS] status file / metadata / state / task ID / raw path -> durable record
  [PASS] fail-closed variants
  [PASS] fail-open variants
  note: 14 individual lexemes folded into their family lines (the funded compression): local-main, watcher, heartbeat, stale, signal, needs-decision, blocked, paused, fix-review, checks-passed, cancelled, fails closed, fail loudly, degraded-open

--- 6. Funding scope: what shrank -------------------------------------
  translation enumeration : 1353 -> 784 bytes (-569)
  duplicate escalation prose: 270 -> 196 bytes (-74)
  new doctrine block added  : +1048 bytes

--- 7. Skills reference section 9 rather than restate it ----------------
  [PASS] ask-user-authority
  [PASS] decision-hold-lifecycle
  [PASS] bearings
  [PASS] ahoy
  [PASS] fmx-respond

  restatement guard - doctrine sentences must live only in AGENTS.md:
    [PASS] ask-user-authority
    [PASS] decision-hold-lifecycle
    [PASS] bearings
    [PASS] ahoy
    [PASS] fmx-respond

--- 8. Bearings / Ahoy host structures unchanged -----------------------
  [PASS] bearings headings: 6 -> 6 (identical)
  [PASS] ahoy numbered steps: 7 -> 7 (identical)
  [PASS] Bearings four-section digest contract intact (Captain's Call, Underway, Charted Next, Recently Landed)

--- 9. Forbidden surfaces absent ---------------------------------------
  changed files:
    M  .agents/skills/ahoy/SKILL.md
    M  .agents/skills/ask-user-authority/SKILL.md
    M  .agents/skills/bearings/SKILL.md
    M  .agents/skills/decision-hold-lifecycle/SKILL.md
    M  .agents/skills/fmx-respond/SKILL.md
    M  AGENTS.md
  [PASS] no files added, deleted, or renamed (no new communication skill)
  [PASS] no runtime enforcement added (bin/ untouched)
  [PASS] no machine prose-quality enforcement added (tests/ and CI untouched)
  [PASS] no platform FIRSTMATE growth (platform adapter surfaces untouched)
  [PASS] no always-loaded surface growth (AGENTS.md/CLAUDE.md net non-positive)

==============================================================================
checks run: 79   passed: 79   failed: 0
RESULT: ALL ACCEPTANCE CRITERIA MET
==============================================================================
Evidence: Full transcript conformance run - old grammar 10/28 vs new grammar 28/28
==============================================================================
CAPTAIN-FACING TRANSCRIPTS - conformance to AGENTS.md section 9
checker rules derived from section 9 at 959913c (asserted above)
==============================================================================

------------------------------------------------------------------------------
DECISION  |  BEFORE (pre-change grammar)
------------------------------------------------------------------------------
  | Captain, the scout finished looking at the auth rate limiter. It read the
  | credential-stuffing report, checked how the current limiter behaves under load,
  | and compared that against what the API team asked for. The API team wants a cap
  | of 20 requests per minute. The security review suggests something lower would be
  | safer, though there is a trade-off with the integrations. Let me know what you
  | think about the cap and I will get it moving.

    [PASS] addresses the captain
    [PASS] no internal terms leak
    [PASS] full PR URL when a PR is named
    [FAIL] operator effort states the response count first
    [FAIL] leads with the captain's action, not context
    [FAIL] exactly one atomic decision question
    [FAIL] labeled recommendation
    [FAIL] states the consequence of the other choice
    [FAIL] exact reply cue
    [FAIL] stable captain-facing decision ID
    [FAIL] reply cue uses the same stable ID
    -> 3/11 section 9 rules satisfied

------------------------------------------------------------------------------
DECISION  |  AFTER  (new grammar)
------------------------------------------------------------------------------
  | Captain, one call is yours.
  | 
  | D1 - Ship the auth rate-limit fix at 5 requests per minute, or the 20 the API team asked for?
  | Recommendation: 5 per minute. The security review found the credential-stuffing gap only closes below 10; at 20 it stays open.
  | Consequence: choosing 20 lands the fix but leaves that gap open as accepted risk.
  | Reply "D1: 5" or "D1: 20".
  | That is 1 reply from you, and nothing else until the fix is ready for your review.

    [PASS] addresses the captain
    [PASS] no internal terms leak
    [PASS] full PR URL when a PR is named
    [PASS] operator effort states the response count first
    [PASS] leads with the captain's action, not context
    [PASS] exactly one atomic decision question
    [PASS] labeled recommendation
    [PASS] states the consequence of the other choice
    [PASS] exact reply cue
    [PASS] stable captain-facing decision ID
    [PASS] reply cue uses the same stable ID
    -> 11/11 section 9 rules satisfied

------------------------------------------------------------------------------
COMPLETION  |  BEFORE (pre-change grammar)
------------------------------------------------------------------------------
  | Captain, the auth rate-limit work is finished. The fix went in at 5 requests per
  | minute, the review came back clean, and the checks are green. The PR is
  | https://github.com/kunchenguid/firstmate/pull/1390 whenever you get a chance.

    [PASS] addresses the captain
    [PASS] no internal terms leak
    [PASS] full PR URL when a PR is named
    [FAIL] operator effort states the response count first
    [FAIL] leads with `Complete:` and a concrete result
    [FAIL] restores enough state to act at this boundary
    -> 3/6 section 9 rules satisfied

------------------------------------------------------------------------------
COMPLETION  |  AFTER  (new grammar)
------------------------------------------------------------------------------
  | Complete: the auth rate-limit fix is ready for your review at 5 requests per minute, captain.
  | 
  | https://github.com/kunchenguid/firstmate/pull/1390 - checks passing, the credential-stuffing gap closed and covered by a new test.
  | Where things stand: this was the only work under way, and nothing else is waiting on you.
  | That is 1 reply from you to approve the merge.

    [PASS] addresses the captain
    [PASS] no internal terms leak
    [PASS] full PR URL when a PR is named
    [PASS] operator effort states the response count first
    [PASS] leads with `Complete:` and a concrete result
    [PASS] restores enough state to act at this boundary
    -> 6/6 section 9 rules satisfied

------------------------------------------------------------------------------
FAILURE  |  BEFORE (pre-change grammar)
------------------------------------------------------------------------------
  | Captain, some background on the auth rate limiter. While validating the fix we
  | noticed the payments integration retries aggressively - about 12 requests per
  | minute from a single account - and the new cap rejects those, so payment retries
  | started failing. We tried a couple of things and none of them worked. There is
  | an option to narrow the limit per account, and an option to wait for the API
  | team. Thoughts?

    [PASS] addresses the captain
    [PASS] no internal terms leak
    [PASS] full PR URL when a PR is named
    [FAIL] operator effort states the response count first
    [FAIL] leads with the captain's action, not context
    [PASS] exactly one atomic decision question
    [FAIL] labeled recommendation
    [FAIL] states the consequence of the other choice
    [FAIL] exact reply cue
    [FAIL] stable captain-facing decision ID
    [FAIL] reply cue uses the same stable ID
    -> 4/11 section 9 rules satisfied

------------------------------------------------------------------------------
FAILURE  |  AFTER  (new grammar)
------------------------------------------------------------------------------
  | Captain, the auth rate-limit fix cannot land as written, and the next move is yours.
  | 
  | D2 - Narrow the limit to per-account, or pause this fix until the API team changes the shared client?
  | Evidence: the payments integration retries 12 requests per minute from one account, the new cap rejects them, and payment retries fail.
  | Recommendation: narrow it to per-account. That closes the credential-stuffing gap and keeps payments working; the shared-client change needs its own PR.
  | Consequence: pausing leaves the gap open until that separate change lands.
  | Reply "D2: narrow" or "D2: pause".
  | That is 1 reply from you. I have exhausted the retry playbook, so nothing moves until you choose.

    [PASS] addresses the captain
    [PASS] no internal terms leak
    [PASS] full PR URL when a PR is named
    [PASS] operator effort states the response count first
    [PASS] leads with the captain's action, not context
    [PASS] exactly one atomic decision question
    [PASS] labeled recommendation
    [PASS] states the consequence of the other choice
    [PASS] exact reply cue
    [PASS] stable captain-facing decision ID
    [PASS] reply cue uses the same stable ID
    -> 11/11 section 9 rules satisfied

==============================================================================
pre-change grammar : 10/28 rules satisfied
new grammar        : 28/28 rules satisfied
RESULT: NEW GRAMMAR FULLY CONFORMS; OLD GRAMMAR DOES NOT
==============================================================================
Evidence: PR-body-ready section: byte counts, preserved-boundary and trigger checklists, three transcripts
## Section 9 byte budget

| | LF-normalized bytes |
|---|---|
| `AGENTS.md` section 9 before (`f7d0d0a`) | 4142 |
| `AGENTS.md` section 9 after (`959913c`) | 4140 |
| **Net** | **-2** |

Funded by compressing the lexical translation enumeration (1353 -> 784 B, -569) and the
adjacent duplicate escalation prose (270 -> 196 B, -74); the new doctrine block costs +1048 B.
Whole-file `AGENTS.md` delta is also -2 B, so the always-loaded surface did not grow.

## Preserved safety boundaries

- [x] Outcome-translation mandate (internal state -> outcome, consequence, next decision)
- [x] Captain's-noun vocabulary rule
- [x] Internal-term exposure ban
- [x] Scout / second mate house-vocabulary carve-out
- [x] Internal-term translation rule - all 11 term families retained
- [x] Never relay worker reports, status lines, tool output, or decision records verbatim
- [x] Read evidence, send the plain-English outcome and consequence
- [x] Private evidence reports may keep exact identifiers; their captain-facing summaries still translate
- [x] Escalations, objections, and challenges stand alone, stay concise, lead with evidence
- [x] Recommendation rather than unsupported deference
- [x] No surfacing of automatic fixes, retries, routine progress, or supervision mechanics
- [x] Exact `Captain, shipshape.` reply for no-action routine updates
- [x] Batch non-urgent updates into the next natural reply
- [x] Plain chat for yes/no; `lavish-axi` only for several options or a structured report
- [x] Full `https://...` PR URL before any shorthand reference
- [x] Cost mentioned as a courtesy, never blocking

## Preserved escalation triggers (all six)

- [x] Work ready for review, with the full PR URL
- [x] Finished investigation findings, relayed as findings rather than only a completion notice
- [x] Gate findings that require the captain's decision under the configured authority
- [x] A real blocker or failure after the relevant playbook is exhausted
- [x] Anything destructive, irreversible, or security-sensitive
- [x] A needed credential or login

## Sample transcripts in the new grammar

**Decision**

`` `text
Captain, one call is yours.

D1 - Ship the auth rate-limit fix at 5 requests per minute, or the 20 the API team asked for?
Recommendation: 5 per minute. The security review found the credential-stuffing gap only closes below 10; at 20 it stays open.
Consequence: choosing 20 lands the fix but leaves that gap open as accepted risk.
Reply "D1: 5" or "D1: 20".
That is 1 reply from you, and nothing else until the fix is ready for your review.
`` `

**Completion**

`` `text
Complete: the auth rate-limit fix is ready for your review at 5 requests per minute, captain.

https://github.com/kunchenguid/firstmate/pull/1390 - checks passing, the credential-stuffing gap closed and covered by a new test.
Where things stand: this was the only work under way, and nothing else is waiting on you.
That is 1 reply from you to approve the merge.
`` `

**Failure**

`` `text
Captain, the auth rate-limit fix cannot land as written, and the next move is yours.

D2 - Narrow the limit to per-account, or pause this fix until the API team changes the shared client?
Evidence: the payments integration retries 12 requests per minute from one account, the new cap rejects them, and payment retries fail.
Recommendation: narrow it to per-account. That closes the credential-stuffing gap and keeps payments working; the shared-client change needs its own PR.
Consequence: pausing leaves the gap open until that separate change lands.
Reply "D2: narrow" or "D2: pause".
That is 1 reply from you. I have exhausted the retry playbook, so nothing moves until you choose.
`` `
- Evidence: Verification sources (re-runnable) (local file: /tmp/no-mistakes-evidence/01KYW2035D65G22499EC60TYNC/verify-operator-comms-standard.py)

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

🔧 **Review** - 6 issues found → auto-fixed (2) ✅
  • ⚠️ AGENTS.md:398 - AGENTS.md:398 mandates that a completion start with Complete:, while AGENTS.md:432 mandates the reply be exactly Captain, shipshape. when a routine operational update's event requires no action. A finished task whose completion needs nothing from the captain satisfies both descriptions, and the two rules are literally unsatisfiable together ("start with Complete:" vs "reply exactly ..."). No precedence is stated. Add a scoping clause — e.g. the Complete: prefix applies to completions surfaced under the reach-immediately triggers, and the shipshape reply governs no-action routine updates.
  • ⚠️ AGENTS.md:405 - The compression at AGENTS.md:405 replaced an explicit do-not-expose list with category labels, and four live internal terms lost coverage: promotion (a real concept at AGENTS.md:331), delivery-mode names (AGENTS.md:206, 251, 459 — i.e. yolo/no-mistakes/ship), autonomy flags, and context budgets. None map cleanly to "startup or supervision machinery / task identifiers or records / worker instructions, copies, cleanup, tools, or settings / pipeline states / compressed safety labels", and unlike crewmate, hold, brief, and status, they are not recovered by the translation bullets at 407-411. The intent authorized funding the doctrine by compressing "only lexical translation enumeration"; this hunk compressed the prohibition list as well and dropped enforceable vocabulary from it.
  • ⚠️ AGENTS.md:399 - The new grammar rules at AGENTS.md:395-399 are unscoped, but .agents/skills/fmx-respond/SKILL.md:79 instructs "It supplements AGENTS.md section 9; apply both, and this public-channel rule wins wherever it is stricter." The public-channel rule is stricter only about omission, so Complete: prefixes, exact reply cues, stable decision IDs, and response-count operator-effort estimates now propagate into public X replies posted under a shared bot identity. The intent scopes the standard to "all captain-facing FirstMate communication"; Bearings and Ahoy each received an explicit scoping line but fmx-respond did not.
  • ⚠️ AGENTS.md:434 - AGENTS.md:434 changed "Use plain chat for a yes-or-no decision" to "for one yes-or-no decision". Combined with the new atomic-decision rule at line 395, this reads as restricting plain chat to a single decision per message, which conflicts with the Bearings contract (.agents/skills/bearings/SKILL.md:72, 92) where a plain-chat Captain's Call section routinely carries several decisions and lavish-axi is only optionally offered. If the intent was to constrain options-within-one-decision rather than decision count, the original wording already said that.
  • ℹ️ .agents/skills/bearings/SKILL.md:93 - .agents/skills/bearings/SKILL.md:92 keeps "The chat follows AGENTS.md section 9 and carries one scannable line per item", and the new line 93 scopes only operator-effort and reply cues to Captain's Call. The rest of the new decision grammar (unmistakable question + labeled recommendation + consequences + stable ID, AGENTS.md:395-396) is therefore inherited by the whole digest via line 92, which is hard to reconcile with one scannable line per item and with line 94's "plain chat stays concise". Consider extending line 93 to cover the full decision grammar, not just the cues.
  • ℹ️ AGENTS.md:396 - AGENTS.md:396 requires stable decision IDs in captain chat while AGENTS.md:405 forbids exposing "task identifiers or records", and .agents/skills/decision-hold-lifecycle/SKILL.md:19 independently mints "a stable privacy-safe key" per decision. Nothing states whether the captain-facing ID may be that internal key or must be a separate captain-friendly label, leaving the two identity schemes to be conflated (and risking a key whose text includes the word "hold", which line 34 of that skill bans from captain chat).

🔧 Fix: Scope captain-facing comms grammar and restore forbidden terms
3 issues (1 warning, 2 infos) still open:

  • ⚠️ AGENTS.md:396 - AGENTS.md:396 now requires a captain-facing decision ID that is "a short captain-facing label like D1 or Q7, never an internal key", and requires it be stable "when several appear or one may cross a turn". Nothing durably stores that label: bin/fm-decision-hold.sh persists only origin-id, decision-key, title, reason, and repo (see its header at lines 13-25), and .agents/skills/decision-hold-lifecycle/SKILL.md:26 explicitly forbids Bearings from "scraping historical reports, visual-review artifacts, terminal output, chat, or other prose". So the D1/Q7 mapping exists only in the chat transcript, and a later Bearings digest built from structured state will renumber labels independently of the earlier one. A captain replying "D1 = B" against a prior digest can therefore be routed to a different hold than the one that carried D1 when it was presented - the exact cross-turn stability the line mandates. Either add a durable captain-label field to the hold record, or state that labels are per-message and must be restated with their subject whenever a decision crosses a turn.
  • ℹ️ .agents/skills/ahoy/SKILL.md:35 - Ruling 5 extended only Bearings. .agents/skills/bearings/SKILL.md:93 now scopes the full decision grammar ("the unmistakable question, labeled recommendation, consequences, stable ID, operator effort, and reply cue") to Captain's Call, but the sibling line at .agents/skills/ahoy/SKILL.md:35 still scopes only "operator-effort and reply cues ... not to recap-only events". By that asymmetry, the unmistakable question, labeled recommendation, consequences, and stable ID are still inherited by Ahoy's recap-only events via section 9 - which is what line 35 was written to prevent. Mirror the Bearings wording in Ahoy.
  • ℹ️ AGENTS.md:406 - The intent authorizes funding only by "compressing only lexical translation enumeration and adjacent duplicate escalation prose", but two of the byte savings in this commit come from neither: AGENTS.md:406 dropped "Firstmate nautical" from the house-vocabulary carve-out (leaving "accepted house vocabulary" with no stated owner), and AGENTS.md:417 dropped the "useful" qualifier, so private evidence reports may now retain identifiers, paths, labels, and internal terms unconditionally rather than only when they are useful. Both are small and neither touches a safety boundary, but they are outside the sanctioned funding sources and the section is now only 3 bytes under budget, so any future edit here has no headroom.

🔧 Fix: Narrow decision labels, mirror Ahoy scoping, restore qualifiers
✅ Re-checked - no issues remain.

✅ **Test** - passed

✅ No issues found.

  • bash tests/fm-ask-user-authority.test.sh - authority rule reaches primaries and secondmates through generated instructions
  • bash tests/fm-decision-hold-lifecycle.test.sh - 9 cases covering the decision relay that now defers to section 9's grammar
  • bash tests/fm-bearings-snapshot.test.sh - 25 cases including Captain's Call actionability and the four-section digest contract
  • bash tests/fm-documentation-audiences.test.sh - documentation inventory, owner pointers, and local links after the prose edits
  • python3 /tmp/no-mistakes-evidence/01KYW2035D65G22499EC60TYNC/verify-operator-comms-standard.py - 79 acceptance checks: byte budget, required doctrine, preserved boundaries, all six escalation triggers, 11 translation families, funding scope, skill pointers vs restatement, host-structure invariance, forbidden surfaces
  • python3 /tmp/no-mistakes-evidence/01KYW2035D65G22499EC60TYNC/transcripts.py - decision/completion/failure transcripts scored against rules asserted to exist verbatim in section 9 at 959913c, run on both pre-change and new grammar
  • Manual render of the captain's reading surface to HTML and SVG (captain-surface.html, captain-surface.svg) after confirming no browser or rasterizer is installed
  • git status --porcelain - worktree left clean, no source or test files modified
⚠️ **Document** - 1 info
  • ℹ️ README.md:123 - Judgment call worth confirming: the public-product Quick Start transcript now demonstrates section 9's captain-facing grammar (Complete: prefix, exact reply cue, response-count effort). This keeps the README honest about what firstmate actually sends, but it does surface the operator-communication grammar in the public product introduction. If you would rather the README stay grammar-agnostic, the alternative is a generic outcome line with no cue or effort token; that would be less faithful to current behavior.
✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

Rewrite the captain-facing doctrine around actionable decisions and outcomes while reducing LF-normalized section 9 from 4,143 to 4,062 bytes. Point decision and recap skills to that single grammar owner without changing their existing content or section contracts.
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