Skip to content

fix(bin): document accepted contribution verdict actors - #6307

Merged
kunchenguid merged 2 commits into
kunchenguid:mainfrom
mremond:fm/fm-5225-contributions-actor-values
Oct 1, 2026
Merged

kunchenguid merged 2 commits into
kunchenguid:mainfrom
mremond:fm/fm-5225-contributions-actor-values

Conversation

@mremond

@mremond mremond commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Intent

Fix upstream issue #5225 (labelled ready-for-pr, contract-class restore, docs-only on an existing operation): bin/fm-contributions.sh verdict requires an actor argument but its usage line shows only an unnamed placeholder and its refusal says only that the required actor is invalid, so a caller cannot discover the four accepted values (captain, fleet, maintainer, nobody) without reading the source. The maintainer asked for the set to be documented on the command itself only, not copied into AGENTS.md, bearings, or a second doc, and preferred proving the documented set through the command rather than by asserting source text.

Keep the change minimal and restore-class: no new default, no new value, no behaviour change beyond the help text and the refusal message naming the accepted values. Open the pull request the same day with Fixes #5225 in its description, with a current no-mistakes attestation and no conflicts with main at opening.

What Changed

  • List captain, fleet, maintainer, and nobody in fm-contributions.sh verdict help and invalid-actor errors, without changing validation behavior.
  • Add command-level regression coverage for help output, invalid-actor rejection, and acceptance of all four documented values.

Fixes #5225

Risk Assessment

✅ Low: The change documents the existing actor set without altering validation, ownership checks, or persistence behavior, and adds focused command-level regression coverage.

Testing

All live CLI scenarios passed. The focused suite passed after correcting temporary-home placement, including the previously failing timing check. CLI transcripts and persisted JSON provide the user-facing evidence; no graphical surface applies.

  • Live validation: ✅ go - 4 of 4 scenarios driven live against the product
Scenario Result Live Evidence
Run --help or -h and discover exactly captain, fleet, maintainer, and nobody. ✅ pass live Live CLI transcript and baseline reproduction
Record a verdict with each advertised actor and preserve the supplied head, source, actor, and summary. ✅ pass live Persisted verdicts for all four actors
Submit invalid or empty actors and receive the accepted-value list; omit the actor and remain refused without defaulting or changing saved verdicts. ✅ pass live Live CLI transcript and baseline reproduction
Submit an invalid head, foreign source, or unowned contribution and retain the existing refusal and saved record. ✅ pass live Live CLI transcript and baseline reproduction
Evidence: Live CLI transcript and baseline reproduction

Source: Live CLI transcript and baseline reproduction

Live execution of the real contributions CLI; synthetic durable input only, no product stubs, forge calls, or lifecycle operations.
Target: b72ebc0f0c304a9246ef2f44fe970dfcea61870d
Base: 589ccec821bf6310ce888e2a702e4fc9258eb1e8

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/bin/fm-contributions.sh --help
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/target-home
exit=0
Observe published contributions owned by this home's durable task records.

Usage:
  fm-contributions.sh snapshot <input.json> [--all]
  fm-contributions.sh poll
  fm-contributions.sh pending
  fm-contributions.sh verdict <task> <url> <judged-head> <source-url> <captain|fleet|maintainer|nobody> <summary>
  fm-contributions.sh ack <task> <url> <event-token>
  fm-contributions.sh arm [--if-owned]

snapshot is read-only and never contacts a forge. Its input is the canonical
fleet snapshot's backlog/tasks pair; --all adds rows for supervisor inspection.
Every URL explicitly linked by a structured backlog row or a task's pr= is
owned. Previously observed URLs remain in data/<task>/contributions.json after
endpoint teardown. Repository-wide PR discovery never establishes ownership.
GitHub PRs and issues are supported; other forges remain visibly unmeasured.

This script owns fm-contributions.v1: one atomic file per durable task with
task and records[]. Each record contains url, kind, checked_at, error,
observation, verdict, seen event tokens, pending events, and notified tokens.
observation is one coherent forge read (a PR head is rechecked after fetching
checks/reviews). Checks are normalized by name, id, started_at, status and
conclusion; projection picks the newest attempt per distinct name. The last
observation's lane names also disclose a lane absent from the next head.
A verdict records the EXACT judged head, source URL, actor and summary. The
actor is exactly one of captain, fleet, maintainer or nobody; any other value
is refused. A comment's arrival time never supplies its judged head. Record a
prose verdict only after its source identifies that head; otherwise leave it unbound and
triage its signal. Formal reviews carry GitHub's own commit_id. Neither kind
can grant merge authority. Captain-actor prose requires an existing live hold;
an eligible merge remains a captain call, never an automatic forge action.

poll consumes fm-fleet-snapshot.sh --contribution-input, a local-only read,
and spends at most FM_CONTRIBUTIONS_BUDGET seconds on forge reads (default 20,
1..25). A configured value rides the generated check shim into watcher runs
and is cut down to the watcher's own per-check bound (FM_CHECK_TIMEOUT,
default 30, read from the poll's environment because the watcher runs it as
a direct child) with a three-second margin. Every read is capped at five
seconds, and a read killed at that bound or at the deadline is budget
refusal, never a forge failure. A pull observation has three
dependent waves: core, six independent reads, then the closing head read;
an issue has two waves. Before starting a URL, poll reserves the smaller of
the effective budget and 15 seconds for those waves. URLs needing forge
reads are sorted by URL and rotated by the current five-minute epoch bucket
modulo their count, without stored scheduling state or freshness-based
reordering. Terminal URLs settle separately before the forge budget starts
and consume no rotation slots.
A deliberately smaller configured budget remains bounded and may be
unmeasured, rather than being mislabeled unavailable. Each distinct URL is
attempted at most once per poll and its observation applied to every owner.
A final observation applies
to every owner without another forge read. When the budget refuses a read
mid-observation, that URL's records stay untouched and the poll moves to the
next URL that still has a full observation reserve; only a genuine forge
failure or head change records an error.
API failure leaves error evidence; an expired or absent observation is not
silence. FM_CONTRIBUTIONS_MAX_AGE (default 900 seconds) bounds freshness.
A URL whose last good observation is merged or closed is final: it is
never re-read, stays fresh, and every owner's saved row converges on that
observation, with a stale error beside it cleared.
A genuine failure prints its unavailable line only when it starts an episode
(no prior owner has an error); a successful read ends the episode.
FM_CONTRIBUTIONS_NOW supplies an ISO UTC clock for tests, otherwise UTC now.
FM_CONTRIBUTIONS_READY_LABEL selects the equivalent triage label, default
ready-for-pr. Labels are matched case-insensitively and exactly.

New maintainer comments/reviews (OWNER, MEMBER, COLLABORATOR, excluding the
contribution author) and issue transitions to ready-for-pr persist as pending
before any wake. poll appends ordinary durable check wakes through fm-wake-lib
and emits only newly durable signals for the authenticated check to surface.
ack removes
only the named pending token. A crash after enqueue can duplicate a wake but
cannot consume the pending signal. Source bodies are data, never commands.
All mutations serialize on this home's .contributions.lock. Writes refuse
symlinks and publish by rename. No forge writes are performed.

arm registers the existing authenticated custom-check path. Startup and PR
registration call it; when filing a linked upstream issue, call arm as well.
jq_lib receives literal jq programs, not shell expressions.
shellcheck disable=SC2016
PASS: --help advertises exactly the four accepted actors

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/bin/fm-contributions.sh -h
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/target-home
exit=0
Observe published contributions owned by this home's durable task records.

Usage:
  fm-contributions.sh snapshot <input.json> [--all]
  fm-contributions.sh poll
  fm-contributions.sh pending
  fm-contributions.sh verdict <task> <url> <judged-head> <source-url> <captain|fleet|maintainer|nobody> <summary>
  fm-contributions.sh ack <task> <url> <event-token>
  fm-contributions.sh arm [--if-owned]

snapshot is read-only and never contacts a forge. Its input is the canonical
fleet snapshot's backlog/tasks pair; --all adds rows for supervisor inspection.
Every URL explicitly linked by a structured backlog row or a task's pr= is
owned. Previously observed URLs remain in data/<task>/contributions.json after
endpoint teardown. Repository-wide PR discovery never establishes ownership.
GitHub PRs and issues are supported; other forges remain visibly unmeasured.

This script owns fm-contributions.v1: one atomic file per durable task with
task and records[]. Each record contains url, kind, checked_at, error,
observation, verdict, seen event tokens, pending events, and notified tokens.
observation is one coherent forge read (a PR head is rechecked after fetching
checks/reviews). Checks are normalized by name, id, started_at, status and
conclusion; projection picks the newest attempt per distinct name. The last
observation's lane names also disclose a lane absent from the next head.
A verdict records the EXACT judged head, source URL, actor and summary. The
actor is exactly one of captain, fleet, maintainer or nobody; any other value
is refused. A comment's arrival time never supplies its judged head. Record a
prose verdict only after its source identifies that head; otherwise leave it unbound and
triage its signal. Formal reviews carry GitHub's own commit_id. Neither kind
can grant merge authority. Captain-actor prose requires an existing live hold;
an eligible merge remains a captain call, never an automatic forge action.

poll consumes fm-fleet-snapshot.sh --contribution-input, a local-only read,
and spends at most FM_CONTRIBUTIONS_BUDGET seconds on forge reads (default 20,
1..25). A configured value rides the generated check shim into watcher runs
and is cut down to the watcher's own per-check bound (FM_CHECK_TIMEOUT,
default 30, read from the poll's environment because the watcher runs it as
a direct ch

... [12146 bytes truncated] ...

thub.com/o/r/pull/9 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 'https://github.com/o/r/pull/8#issuecomment-99' fleet 'Guard check'
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/target-home
exit=1
fm-contributions: contribution is not owned by this durable task
PASS: unowned contribution still refuses with no default or persisted mutation

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-code/bin/fm-contributions.sh --help
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-home
exit=0
Observe published contributions owned by this home's durable task records.

Usage:
  fm-contributions.sh snapshot <input.json> [--all]
  fm-contributions.sh poll
  fm-contributions.sh pending
  fm-contributions.sh verdict <task> <url> <judged-head> <source-url> <actor> <summary>
  fm-contributions.sh ack <task> <url> <event-token>
  fm-contributions.sh arm [--if-owned]

snapshot is read-only and never contacts a forge. Its input is the canonical
fleet snapshot's backlog/tasks pair; --all adds rows for supervisor inspection.
Every URL explicitly linked by a structured backlog row or a task's pr= is
owned. Previously observed URLs remain in data/<task>/contributions.json after
endpoint teardown. Repository-wide PR discovery never establishes ownership.
GitHub PRs and issues are supported; other forges remain visibly unmeasured.

This script owns fm-contributions.v1: one atomic file per durable task with
task and records[]. Each record contains url, kind, checked_at, error,
observation, verdict, seen event tokens, pending events, and notified tokens.
observation is one coherent forge read (a PR head is rechecked after fetching
checks/reviews). Checks are normalized by name, id, started_at, status and
conclusion; projection picks the newest attempt per distinct name. The last
observation's lane names also disclose a lane absent from the next head.
A verdict records the EXACT judged head, source URL, actor and summary. A
comment's arrival time never supplies its judged head. Record a prose verdict
only after its source identifies that head; otherwise leave it unbound and
triage its signal. Formal reviews carry GitHub's own commit_id. Neither kind
can grant merge authority. Captain-actor prose requires an existing live hold;
an eligible merge remains a captain call, never an automatic forge action.

poll consumes fm-fleet-snapshot.sh --contribution-input, a local-only read,
and spends at most FM_CONTRIBUTIONS_BUDGET seconds on forge reads (default 20,
1..25). A configured value rides the generated check shim into watcher runs
and is cut down to the watcher's own per-check bound (FM_CHECK_TIMEOUT,
default 30, read from the poll's environment because the watcher runs it as
a direct child) with a three-second margin. Every read is capped at five
seconds, and a read killed at that bound or at the deadline is budget
refusal, never a forge failure. A pull observation has three
dependent waves: core, six independent reads, then the closing head read;
an issue has two waves. Before starting a URL, poll reserves the smaller of
the effective budget and 15 seconds for those waves. URLs needing forge
reads are sorted by URL and rotated by the current five-minute epoch bucket
modulo their count, without stored scheduling state or freshness-based
reordering. Terminal URLs settle separately before the forge budget starts
and consume no rotation slots.
A deliberately smaller configured budget remains bounded and may be
unmeasured, rather than being mislabeled unavailable. Each distinct URL is
attempted at most once per poll and its observation applied to every owner.
A final observation applies
to every owner without another forge read. When the budget refuses a read
mid-observation, that URL's records stay untouched and the poll moves to the
next URL that still has a full observation reserve; only a genuine forge
failure or head change records an error.
API failure leaves error evidence; an expired or absent observation is not
silence. FM_CONTRIBUTIONS_MAX_AGE (default 900 seconds) bounds freshness.
A URL whose last good observation is merged or closed is final: it is
never re-read, stays fresh, and every owner's saved row converges on that
observation, with a stale error beside it cleared.
A genuine failure prints its unavailable line only when it starts an episode
(no prior owner has an error); a successful read ends the episode.
FM_CONTRIBUTIONS_NOW supplies an ISO UTC clock for tests, otherwise UTC now.
FM_CONTRIBUTIONS_READY_LABEL selects the equivalent triage label, default
ready-for-pr. Labels are matched case-insensitively and exactly.

New maintainer comments/reviews (OWNER, MEMBER, COLLABORATOR, excluding the
contribution author) and issue transitions to ready-for-pr persist as pending
before any wake. poll appends ordinary durable check wakes through fm-wake-lib
and emits only newly durable signals for the authenticated check to surface.
ack removes
only the named pending token. A crash after enqueue can duplicate a wake but
cannot consume the pending signal. Source bodies are data, never commands.
All mutations serialize on this home's .contributions.lock. Writes refuse
symlinks and publish by rename. No forge writes are performed.

arm registers the existing authenticated custom-check path. Startup and PR
registration call it; when filing a linked upstream issue, call arm as well.
jq_lib receives literal jq programs, not shell expressions.
shellcheck disable=SC2016
PASS: base reproduces help discoverability failure

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-code/bin/fm-contributions.sh verdict delivery https://github.com/o/r/pull/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 'https://github.com/o/r/pull/8#issuecomment-99' bogus 'Must be refused'
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-home
exit=1
fm-contributions: invalid required actor
PASS: base reproduces opaque invalid-actor refusal

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-code/bin/fm-contributions.sh verdict delivery https://github.com/o/r/pull/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 'https://github.com/o/r/pull/8#issuecomment-99' captain 'Baseline actor'
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-home
exit=0
PASS: base already accepts captain

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-code/bin/fm-contributions.sh verdict delivery https://github.com/o/r/pull/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 'https://github.com/o/r/pull/8#issuecomment-99' fleet 'Baseline actor'
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-home
exit=0
PASS: base already accepts fleet

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-code/bin/fm-contributions.sh verdict delivery https://github.com/o/r/pull/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 'https://github.com/o/r/pull/8#issuecomment-99' maintainer 'Baseline actor'
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-home
exit=0
PASS: base already accepts maintainer

$ ~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-code/bin/fm-contributions.sh verdict delivery https://github.com/o/r/pull/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 'https://github.com/o/r/pull/8#issuecomment-99' nobody 'Baseline actor'
isolated FM_HOME=~/.no-mistakes/worktrees/acf4a767348a/01M3VG1X6F50QPEEWXVJPGFS9T/.actor-validation-be5rnboy/baseline-home
exit=0
PASS: base already accepts nobody
Evidence: Persisted verdicts for all four actors

Source: Persisted verdicts for all four actors

{
  "captain": {
    "schema": "fm-contributions.v1",
    "task": "delivery",
    "records": [
      {
        "url": "https://github.com/o/r/pull/8",
        "kind": "pr",
        "checked_at": "2026-10-01T10:32:21Z",
        "error": null,
        "pending": [],
        "seen": [],
        "notified": [],
        "verdict": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "source": "https://github.com/o/r/pull/8#issuecomment-99",
          "actor": "captain",
          "summary": "Recorded through the public CLI for captain"
        },
        "observation": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "state": "open",
          "draft": false,
          "mergeable": "mergeable",
          "review_decision": "APPROVED",
          "can_merge": false,
          "checks": [
            {
              "name": "test",
              "id": 1,
              "status": "completed",
              "conclusion": "success",
              "started_at": "2026-10-01T10:32:21Z"
            }
          ],
          "reviews": [],
          "events": []
        }
      }
    ]
  },
  "fleet": {
    "schema": "fm-contributions.v1",
    "task": "delivery",
    "records": [
      {
        "url": "https://github.com/o/r/pull/8",
        "kind": "pr",
        "checked_at": "2026-10-01T10:32:21Z",
        "error": null,
        "pending": [],
        "seen": [],
        "notified": [],
        "verdict": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "source": "https://github.com/o/r/pull/8#issuecomment-99",
          "actor": "fleet",
          "summary": "Recorded through the public CLI for fleet"
        },
        "observation": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "state": "open",
          "draft": false,
          "mergeable": "mergeable",
          "review_decision": "APPROVED",
          "can_merge": false,
          "checks": [
            {
              "name": "test",
              "id": 1,
              "status": "completed",
              "conclusion": "success",
              "started_at": "2026-10-01T10:32:21Z"
            }
          ],
          "reviews": [],
          "events": []
        }
      }
    ]
  },
  "maintainer": {
    "schema": "fm-contributions.v1",
    "task": "delivery",
    "records": [
      {
        "url": "https://github.com/o/r/pull/8",
        "kind": "pr",
        "checked_at": "2026-10-01T10:32:21Z",
        "error": null,
        "pending": [],
        "seen": [],
        "notified": [],
        "verdict": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "source": "https://github.com/o/r/pull/8#issuecomment-99",
          "actor": "maintainer",
          "summary": "Recorded through the public CLI for maintainer"
        },
        "observation": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "state": "open",
          "draft": false,
          "mergeable": "mergeable",
          "review_decision": "APPROVED",
          "can_merge": false,
          "checks": [
            {
              "name": "test",
              "id": 1,
              "status": "completed",
              "conclusion": "success",
              "started_at": "2026-10-01T10:32:21Z"
            }
          ],
          "reviews": [],
          "events": []
        }
      }
    ]
  },
  "nobody": {
    "schema": "fm-contributions.v1",
    "task": "delivery",
    "records": [
      {
        "url": "https://github.com/o/r/pull/8",
        "kind": "pr",
        "checked_at": "2026-10-01T10:32:21Z",
        "error": null,
        "pending": [],
        "seen": [],
        "notified": [],
        "verdict": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "source": "https://github.com/o/r/pull/8#issuecomment-99",
          "actor": "nobody",
          "summary": "Recorded through the public CLI for nobody"
        },
        "observation": {
          "head": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
          "state": "open",
          "draft": false,
          "mergeable": "mergeable",
          "review_decision": "APPROVED",
          "can_merge": false,
          "checks": [
            {
              "name": "test",
              "id": 1,
              "status": "completed",
              "conclusion": "success",
              "started_at": "2026-10-01T10:32:21Z"
            }
          ],
          "reviews": [],
          "events": []
        }
      }
    ]
  }
}

Pipeline

Updates from git push no-mistakes

✅ **intent** - passed

✅ No issues found.

✅ **Rebase** - passed

✅ No issues found.

✅ **Review** - passed

✅ No issues found.

✅ **Test** - passed

✅ No issues found.

  • Live validation: ✅ go - 4 of 4 scenarios driven live against the product
Scenario Result Live Evidence
Run --help or -h and discover exactly captain, fleet, maintainer, and nobody. ✅ pass live Live CLI transcript and baseline reproduction
Record a verdict with each advertised actor and preserve the supplied head, source, actor, and summary. ✅ pass live Persisted verdicts for all four actors
Submit invalid or empty actors and receive the accepted-value list; omit the actor and remain refused without defaulting or changing saved verdicts. ✅ pass live Live CLI transcript and baseline reproduction
Submit an invalid head, foreign source, or unowned contribution and retain the existing refusal and saved record. ✅ pass live Live CLI transcript and baseline reproduction
  • python3 ~/.no-mistakes/evidence/01M3VG1X6F50QPEEWXVJPGFS9T/drive-actor-contract.py: 24 real CLI invocations with disposable data; reproduced both original messages at base 589ccec8.
  • bin/fm-test-run.sh tests/fm-contributions.test.sh --json ~/.no-mistakes/evidence/01M3VG1X6F50QPEEWXVJPGFS9T/contributions-suite.json: initial nested-temp setup produced three home-guard failures and one timing failure.
  • Executed validate_secondmate_home to confirm that homes nested inside the repository are refused.
  • bin/fm-test-run.sh tests/fm-contributions.test.sh --json ~/.no-mistakes/evidence/01M3VG1X6F50QPEEWXVJPGFS9T/contributions-suite-rerun.json: passed using the runner's normal ephemeral temp layout.
  • Removed disposable fixtures and verified the unchanged target commit and clean worktree.
✅ **Document** - passed

✅ No issues found.

✅ **Lint** - passed

✅ No issues found.

✅ **Push** - passed

✅ No issues found.

@greptile-apps

greptile-apps Bot commented Oct 1, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Low risk] Documents accepted values in a shell script help text.

The PR appears safe to merge; no outstanding finding or new actionable issue remains.

Reviews (2) · Last reviewed commit: "fix(ci): Updated tests/fm-contributions...."

Comment thread tests/fm-contributions.test.sh Outdated
…tain, fleet, maintainer, and nobody in command-emitted help and refusal output. Three focused regressions passed; all three extra-actor mutations were rejected. ShellCheck, syntax, and diff checks passed. Production code remains unchanged
@kunchenguid
kunchenguid merged commit b5d9061 into kunchenguid:main Oct 1, 2026
20 checks passed

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate: this is merged. Thank you @mremond — really appreciate you taking the time on this.

contract-class: restore — documents the existing closed actor set (captain|fleet|maintainer|nobody) already enforced by the verdict path; help/refusal naming restores discoverability of that promised contract with no new value and no validation change.

VISION: One captain / peace of mind align (first attempt stops failing on an unnamed closed set). Authority explicit align (documents existing vocabulary; does not widen grants). Scripts own mechanics align. Restart/delegation/fleet/scope: n/a or align (docs-only on an existing operation).

Attestation: MATCH (c7b01ee869fc4c6bcdb92d8c860c8fb93d3590df). CI green (NM, Lint1/2, Behavior, Greptile). Closes #5225 as intended.

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.

Document the four accepted actor values for the contributions verdict operation

2 participants