Adopt upstream baseline and active watcher fix#5
Merged
Conversation
* fix: make watcher singleton race-proof and re-arm home-scoped Concurrent fm_lock_try_acquire could produce two lock holders: the stale-steal path destroyed and recreated the lock dir without serialization, so two racers could both reclaim it. That let two fm-watch.sh watchers run in one home, doubling every wake. - fm-wake-lib.sh: single-winner acquire. Reclaim is serialized through a sibling ".steal" mutex (its abandonment floor decoupled from FM_LOCK_STALE_AFTER, never below 2s) and the holder pid is re-verified dead immediately before the rmdir. Every claim writes its pid and reads it back; a stomped pid means we lost. mkdir is the atomic arbiter, so at most one acquirer ever returns 0. - fm-watch.sh: self-eviction. Each poll a watcher checks the lock still names its pid; if another took over, it exits cleanly, so any transient duplicate self-resolves within one poll. - fm-watch-arm.sh: safe re-arm. Default no-ops via the singleton; --restart signals only this home's recorded watcher pid, never a broad pkill that would kill sibling homes' watchers. - AGENTS.md section 8: route re-arm through fm-watch-arm.sh and warn that pkill -f bin/fm-watch.sh kills other homes' watchers. - Tests: concurrency single-winner, dead-pid steal, live-lock no-op, watcher self-eviction. * no-mistakes(review): Harden watcher lock ownership * no-mistakes(review): Captain, harden watcher lock claims * no-mistakes(review): Captain, harden lock steal mutex ownership * no-mistakes(review): Captain, harden steal-aware lock claims * no-mistakes(document): Document watcher arm workflow
* fix: correct no-mistakes gate contract in brief and AGENTS The no-mistakes definition-of-done told crewmates to "fix auto-fix findings yourself", which reads as self-committing fixes - the exact behavior the pipeline forbids. Crewmates anchored on it self-committed or aborted a healthy long run, tangling git state and stalling the fleet. - fm-brief.sh: the crewmate drives the gates and never edits or commits code while a run is active; it advances auto-fix findings with `no-mistakes axi respond --action fix`; the run blocks for minutes and auto-fixes itself with no gate, so do not cancel, abort, re-run, or background it, or idle-wait for a notification. - AGENTS.md: fix the supervisor-facing line (the pipeline fixes, the crewmate responds and never edits during a run) and scope the "background long work" guidance to firstmate's own session, so a crewmate runs its own validation in the foreground. * no-mistakes(document): Sync no-mistakes gate docs
* docs: add built-in skills table to README * no-mistakes(document): Sync skill invocation docs * docs: drop user-level no-mistakes from built-in skills no-mistakes is a user-level prerequisite (~/.claude/skills), not a firstmate-shipped skill. Remove the stale vendored .agents/skills/no-mistakes duplicate and its README table row; keep only /afk and /updatefirstmate. Retarget the codex invocation example to a skill that remains in the table. * no-mistakes(document): Tighten built-in skills README wording
* fix(watch): honest self-verifying watch-arm + prominent no-watcher guard banner fm-watch-arm.sh now forks the watcher as a tracked child, verifies a live watcher with a fresh beacon (reusing FM_GUARD_GRACE), and prints one honest line - started/healthy/FAILED - exiting non-zero when none can be confirmed. Never reports healthy off a stale beacon or dead/reused pid. fm-guard.sh leads the no-watcher case with a bordered ●-marked banner (in-flight count, beacon age, exact re-arm command) so it cannot be skimmed past; queued- wakes warning and grace-window quiet preserved. AGENTS.md section 8 codifies arming only via the harness's tracked background mechanism, never a fire-and-forget shell &. Tests: arm started/healthy/FAILED + never-healthy-off-dead-pid; guard banner- first and fresh-watcher-quiet. Restart test updated for the child topology. * no-mistakes(review): Propagate immediate watcher wakes * no-mistakes(review): Trap HUP during watcher arm cleanup * no-mistakes(review): Wait for peer watcher beacon * no-mistakes(document): Sync watcher arm docs * no-mistakes: apply CI fixes
* docs: restructure firstmate agent manual * no-mistakes(document): Sync agent skill documentation
* test: consolidate suite into lifecycle e2e, safety matrices, shared helpers Move operator-visible lifecycle behavior into focused end-to-end tests, table- drive repetitive cases, and add shared test helpers, without weakening any safety-critical coverage. - Add tests/lib.sh (reporters, self-cleaning temp root, fakebin/git/meta helpers, common assertions) plus behavior-area helpers tests/secondmate- helpers.sh and tests/wake-helpers.sh; refactor every test file onto them. - Split the two giant files by behavior area: fm-secondmate -> lifecycle e2e + safety; fm-wake-queue -> wake-queue losslessness + fm-watcher-lock + fm-daemon. - Add fm-secondmate-lifecycle-e2e (seed -> spawn -> routed send -> backlog handoff -> recovery respawn -> teardown) and fm-wake-daemon-lifecycle-e2e (routine/terminal routing across a watcher restart, one buffered digest, no duplicate, stale transient/persistent/resume). - Expand fm-afk-inject-e2e with a normal single-digest scenario and delete the five overlapping fake-tmux injection cases (persistent-swallow kept as a unit). - Table-drive the secondmate teardown path-boundary matrix, watch-arm started/self-heal, guard warnings, spawn-batch and bootstrap parsers, and the fm-update worlds. - Add an explicit timeout-minutes (15) to the behavior-test CI job. Preserved as focused matrices/units: teardown unlanded-work safety, lock- primitive races and watcher singleton, wake-queue losslessness and no-duplicate escalation, secondmate path-boundary validation on every entrypoint, fast- forward-only update skips, the captain-relevant status-phrase matrix, and no-mistakes init / origin preservation / never-write-through-a-project. * no-mistakes(review): Require tmux for AFK e2e coverage * no-mistakes(review): Captain, require AFK e2e self-check coverage * no-mistakes(review): Captain: preserve secondmate launch isolation coverage * no-mistakes(document): sync test documentation * no-mistakes: apply CI fixes
* docs: restructure README into concise overview plus docs/ tree Trim README from 267 to 138 lines by relocating reference material into a new docs/ tree and CONTRIBUTING, with no information loss: - docs/architecture.md: the How It Works internals (supervision engine, secondmates, project modes, fleet sync, self-update, dev notes). - docs/configuration.md: config prose, FM_HOME, harness support, the full toolchain list, and the env-var reference block (verbatim). - docs/scripts.md: the bin/ toolbelt table (verbatim). - CONTRIBUTING.md: fold in the foreground/no-mistakes-gate prose and the dev/test command block (verbatim), which it previously lacked. Rewrite README to: tightened pitch, one-line feature bullets, merged Quick Start + Install, How It Works reduced to diagram + synopsis, a Documentation section linking the new docs, and Contributing + License sections. Keep the user-invocable slash-command table front-and-center. Reference AGENTS.md by topic, not section number, so it stays robust to the AGENTS restructure. * docs: swap README banner to new PNG asset * no-mistakes(review): Fix stale secondmate test checklist * no-mistakes(review): Fix harness documentation ownership * no-mistakes(review): Correct targeted test checklist * no-mistakes(review): Restore spawn batch checklist reference * no-mistakes(document): sync documentation references
* feat(guards): prevent and detect firstmate primary worktree tangle Firstmate is a treehouse-pooled git repo of itself: the primary checkout and every crewmate worktree / secondmate home are linked worktrees of one repo. A crewmate sent to work firstmate-on-itself can branch and commit in the PRIMARY checkout instead of its own isolated worktree, stranding the primary on a feature branch (e.g. fm/readme-restructure-d3). Add two guards: Prevention (spawn-time): - fm-brief.sh: ship-brief Setup now opens with a worktree-isolation assertion ahead of the branch step. The crewmate confirms it is in its own treehouse worktree, and stops with `blocked: launched in primary checkout, not an isolated worktree` if it resolves to the primary. - fm-spawn.sh: after treehouse get, refuse to launch unless the resolved worktree is a genuine isolated worktree root distinct from the primary checkout (PROJ_ABS); abort with a clear error otherwise. Detection (immediate): - bin/fm-tangle-lib.sh: shared classifier. A NAMED non-default branch in the primary is the tangle; the default branch and detached HEAD (the legitimate state of worktrees and secondmate homes) stay silent. - fm-guard.sh: bordered alarm, in the watcher-down banner's spirit, on the very next fleet action when the primary is on a feature branch. - fm-bootstrap.sh: same assertion at session start as a TANGLE: line. Tests: tests/fm-tangle-guard.test.sh covers the lib classification, the guard banner, the bootstrap line, brief assertion ordering, and the spawn abort. fm-bootstrap and fm-watcher-lock guard tests now pin FM_ROOT so the ambient (feature-branch) checkout never leaks a TANGLE line into them. Docs: AGENTS.md sections 3, 7, 8, 11 document both guards. * no-mistakes(review): Make brief isolation path authoritative * no-mistakes(document): Sync tangle guard docs * no-mistakes: apply CI fixes * no-mistakes(document): Sync tangle guard docs
* fm-send: pause after submit so the receiving turn is visibly up A successful text send only proves the composer cleared - the Enter landed and the text was submitted - but the harness needs a beat to spin up the turn before its busy footer appears. An immediate peek after fm-send returns would see the stale idle pane. Add a fixed FM_SEND_SETTLE pause (default 1s, 0 disables) on the successful text-submit path only. Scoped to fm-send's text path: not the --key path, and not the shared fm_tmux_submit_core, so the away-mode daemon (which only needs 'submitted') never pays it. Purely additive; exit codes unchanged. * no-mistakes(document): Document fm-send settle pause
* feat: track primary local HEAD for secondmate homes Make every secondmate home follow the primary firstmate checkout's current default-branch commit via a purely local fast-forward (no origin fetch), so deliberate captain updates to the primary converge the fleet automatically. - Extract fm-update's ff machinery into bin/fm-ff-lib.sh; ff_target gains a base_mode parameter (origin -> origin/<default> with fetch; any commit-ish -> that local commit, no fetch) so both sync paths share one implementation. - fm-spawn: fast-forward a secondmate worktree to the primary's HEAD before launch (covers fresh spawns and recovery-respawns). - fm-bootstrap: sweep every live secondmate home to the primary's HEAD and emit NUDGE_SECONDMATES: only for running secondmates whose instructions actually changed; already-current or no-instruction-change homes are left undisturbed. - Document spawn + bootstrap behavior in AGENTS.md. - Add hermetic tests for the local-HEAD ff helper (updated/current/dirty/ diverged/in-flight), no-fetch guarantee, nudge gating, the bootstrap sweep, and the spawn hook. * no-mistakes(review): Fix secondmate sync git shim * no-mistakes(review): Surface skipped secondmate sync diagnostics * no-mistakes(document): Document secondmate sync
…uid#93) * feat(send): mark firstmate->secondmate requests for status-path reply fm-send now prepends a distinct from-firstmate marker (new bin/fm-marker-lib.sh: the label [fm-from-firstmate] followed by ASCII unit separator 0x1f) when the resolved target is a bare fm-<id> whose meta records kind=secondmate. The marker reuses the afk untypable-separator concept but is deliberately distinct from the daemon's bare leading 0x1f, so it never conflates with a secondmate's own afk escalation marker. A secondmate is itself a firstmate, so a relayed request lands in its own chat, which the main firstmate never reads. The secondmate charter (fm-brief.sh) and AGENTS.md now document the recognize-and-respond-via-status contract: a marked request is answered via the status file (or a doc plus a status pointer), never chat-only; an unmarked message stays conversational captain intervention. Crewmate/scout targets, explicit session:window targets, and the --key path are unchanged. Backbone (watcher, daemon, tmux-lib, afk) untouched. Hermetic tests cover marked vs unmarked sends and the exact marker bytes. * no-mistakes(document): Sync secondmate marker docs
* fix(teardown): recognize squash-merged work as landed fm-teardown refused to tear down a worktree whose PR was squash-merged and whose head branch was then deleted - the most common GitHub flow - because its safety check used commit reachability (HEAD --not --remotes) rather than whether the work actually landed. A squash merge writes one new commit on the default branch, so the branch's own commits are on no remote-tracking branch, and auto-delete-on-merge drops the head ref too; reachability was non-empty and teardown false-refused merged work. For a normal ship task whose commits are not remote-reachable, before refusing, treat the work as landed if either its PR is merged (resolved from meta pr= or the branch name via gh-axi; authoritative for squash, rebase, and merge alike, and surviving branch deletion) or its content is already in the up-to-date default branch (a 3-way merge-tree that adds nothing the default branch lacks - robust to the default having advanced past the merge-base). Dirty worktrees and genuinely unlanded work still refuse; a gh lookup error falls back to the content check and, if that is inconclusive, refuses (fail-safe, never silently allows). Fork, local-only, scout, secondmate, and --force paths are unchanged. Tests cover squash-merged+deleted-branch (allow), genuinely unlanded (refuse), dirty (refuse), normally pushed (allow), content-in-default fallback (allow), and gh-error+content-absent (refuse, fail-safe). * no-mistakes(review): Guard teardown against stale PR proof * no-mistakes(review): Verify teardown PR heads * no-mistakes(document): Sync teardown landing docs * no-mistakes: apply CI fixes
* fix: harden no-mistakes validation contract against gate-park and self-fix duplication Rewrite the no-mistakes validation block scaffolded into every ship brief so a crewmate knows the right move at each gate: the pipeline owns every fix (including the fix for a real bug review finds in the crewmate's own code); respond, never self-implement/abort/re-run; the ask-user loop end to end (feed the decision back via axi respond, do not hand-fix); process every return (backgrounding ok, never idle-wait for auto-advance); avoid --yes (it auto-resolves ask-user with zero escalation); and review findings always gate (review auto-fix is disabled). Add the supervisor heuristic in AGENTS.md: firstmate keys off the no-mistakes run step status - running/fixing/ci means working, awaiting_approval/fix_review means parked (surfaced as awaiting_agent: parked <duration> on axi status) - not shell liveness, plus a self-fix-duplication red flag (hand-commits/abort/re-run mid-validation). Resolves the gate-park-deadlock and self-fix-duplication failure modes. * no-mistakes(document): Sync validation docs * no-mistakes(lint): Lint checks clean
* fix(watch): tighten watcher re-arm discipline and assert liveness on drain The watcher supervision chain could silently lapse: re-arms were bundled at the tail of multi-command calls (where fm-watch-arm no-ops when a cycle is briefly still alive, so no fresh cycle got established), and text-only "holding" turns ran no supervision script, so fm-guard's liveness banner - which only fires when a guarded script runs - never triggered. AGENTS.md section 8: make the re-arm rules unambiguous - keep exactly one live cycle while work is in flight; re-arm after each FIRE (a completed arm task carrying a wake reason) and never churn on a healthy/started no-op; run fm-watch-arm standalone, never bundled; never end a turn blind, holds included. Existing material (singleton lock, beacon, guard banner, afk exception) is preserved. fm-wake-drain.sh: assert watcher liveness after draining by reusing fm-guard.sh's existing graced, beacon-based banner, so a lapse also surfaces on a plain drain-and-handle turn. Called after the queue is emptied so the guard never re-prints its own queued-wakes notice, and best-effort so it never changes the drain's exit status. The grace beacon keeps it silent right after a normal fire and warns only on a stale-beyond-grace lapse with work in flight. Watcher core (fm-watch.sh, lock, beacon-touch, wake-queue) untouched. tests: keep the worktree-tangle check inert across the drain-invoking suites (wake-helpers points FM_ROOT at a non-git dir, the same trick the direct fm-guard.sh tests use), and add a regression test asserting the drain warns on a lapse and stays silent right after a fire. * no-mistakes(document): Document drain-time watcher liveness
…id#102) * fix(brief): slim no-mistakes contract to pointer + firstmate wrapper no-mistakes v1.31.2 self-documents the validation mechanics in its own SKILL.md (refreshed from the binary on init) and live axi help output, including the review-always-gates, no-abort/rerun-mid-run, and never-idle-wait facts. fm-brief.sh's no-mistakes-mode Definition of done was restating all of that, a drift hazard since the brief lives in a different repo from the version-matched SKILL.md. Collapse the duplicated mechanics block to a ~3-line pointer at no-mistakes' own guidance and keep only the firstmate-specific wrapper: the done handshake, ask-user escalation to firstmate via rule 6, the --yes captain stance, and the CI-green reporting line. * no-mistakes(review): Enforce no-mistakes bootstrap version floor * no-mistakes(document): Sync no-mistakes docs * no-mistakes(lint): Fix ShellCheck version parsing
* fix(send): settle codex $skill popup before submit
A `$<skill>` invocation (e.g. $no-mistakes) opens codex's $-autocomplete
popup; submitting too fast lets it swallow the Enter so the invocation
never lands - biting every pipeline trigger to a codex crew/secondmate.
Mirror the existing `/` slash-popup handling: give a `$...` message the
1.2s popup-settle before the (retried) Enter, but scope it to
harness=codex (read from the target's meta) so `$`-prefixed plain text
("$5/month", "$HOME") to claude/opencode/pi keeps the 0.3s fast path. An
explicit session:window target has no meta -> harness unknown -> treated
as non-codex. The retried Enter in fm_tmux_submit_core still backs the
settle up; the `/` case, --key path, marker, and meta-resolution
contract are unchanged.
Record the codex $-popup fact in the harness-adapters skill, and add a
per-harness settle-selection test (codex $ ->1.2, claude $ ->0.3,
explicit $ ->0.3, any / ->1.2, plain ->0.3).
* no-mistakes(document): Sync fm-send popup docs
* feat(supervise): deterministic crew current-state helper Add bin/fm-crew-state.sh, a deterministic one-line read of a crew's CURRENT state that ends the stale-status-line friction in supervision. The status log is an append-only wake-event log, so tail -1 reports the last event, not the current state: after firstmate resolves a needs-decision/blocked and the crew silently resumes, the log stays stale. The helper takes the active no-mistakes run-step as the source of truth (attributed to the crew's branch, via axi status then the run list), reconciles a possibly-stale needs-decision/blocked log line against it (flagging it superseded when the run has resumed), and falls back to the pane busy-signature + status log when no run is active. Handles scout/secondmate kinds and torn-down/missing crews gracefully. Reuses fm-tmux-lib.sh busy detection and meta parsing; fully deterministic (run-step/pane/log reads only, no heuristics, no LLM). Wire AGENTS.md sections 7 and 8 to read current state via the helper and to stop inferring state from a tail of the status log; the status file stays the wake-event log. Watcher core, status-file/brief contracts, and wake/dedup machinery are unchanged. Add tests/fm-crew-state.test.sh covering run-step authority, superseded stale log lines, genuine-parked, cross-branch attribution, pane and status-log fallback, scout skip, and torn-down/missing-meta cases. * no-mistakes(review): Fix dead-window crew state fallback * no-mistakes(review): Harden crew state liveness checks * no-mistakes(review): Harden crew state gate handling * no-mistakes(review): Harden crew state gate parsing * no-mistakes(document): Document crew state helper * no-mistakes: apply CI fixes * fix(crew-state): keep run-step authoritative over a closed pane The dead-window guard ran before the no-mistakes run lookup, so a finished crew whose agent had exited and closed its window reported 'unknown' instead of its authoritative run-step state (e.g. done) - the normal gap between a crew completing and teardown, and a regression against the helper's core principle of judging by the run-step, not the shell. Move the pane-readability guard into the no-run fallback path so it runs only after the run-step lookup: a crew with a run reports its run-step state regardless of pane liveness, while a genuinely runless dead window still reports unknown rather than trusting a stale log. Replace the test that encoded the regression with two that pin the correct behavior: a closed pane with a terminal run reports done, and a closed pane with an active run reports working. * no-mistakes(document): Sync crew-state docs
* feat(watch): always-on wake triage absorbs benign wakes in bash Factor the afk daemon's classify_signal/classify_stale/heartbeat-scan into a shared bin/fm-classify-lib.sh used by both the always-on watcher and the daemon. fm-watch.sh now loops internally: it classifies each wake and absorbs the benign majority (working: signals, bare turn-ended, non-terminal stale, no-change heartbeat) by advancing the suppression marker and logging, without queuing or exiting; it writes the durable queue and exits only on an actionable wake (captain-relevant signal, any check, terminal stale, a non-terminal stale that persists past FM_STALE_ESCALATE_SECS, or the heartbeat fleet-scan backstop). So firstmate re-arms once per actionable event instead of once per wake. Safety preserved: singleton lock + beacon (touched every poll including while absorbing), durable queue for actionable wakes, kind=secondmate stale-skip, per-task check polling, heartbeat backoff, bounded wedge latency. While state/.afk exists the daemon owns triage and the watcher reverts to one-shot, so the two never double-triage. AGENTS.md section 8 + afk skill updated; tests added. * no-mistakes(review): Captain, repair watcher triage edge cases * no-mistakes(document): Sync watcher triage docs * no-mistakes: apply CI fixes
…unchenguid#87) The firstmate side of "listen on X and reply", shipped inside the repo so every user has it but INERT until they opt in (a non-empty FMX_PAIRING_TOKEN in .env). Purely additive: the watcher backbone (fm-watch.sh, fm-watch-arm.sh, fm-wake-lib.sh) and the afk daemon (fm-supervise-daemon.sh, afk skill) are untouched. - bin/fm-x-poll.sh: one short-poll of GET /connector/poll; hard no-op without a token; requires non-empty text; stashes the full mention (incl. in_reply_to conversation context) to state/x-inbox/<id>.json behind a path-traversal guard; prints "x-mention <id>" (or a rate-limited "x-mode-error ...") for the watcher. - bin/fm-x-reply.sh: POST /connector/answer; bearer token via a 0600 header file (never argv); reply via --text-file/stdin so mention text is never inlined into a shell command. Long replies auto-split into a premium-independent numbered "(k/n)" thread (codepoint-aware, capped); single tweet stays unnumbered. Wire: {request_id, text}, plus {texts:[...]} for a thread. FMX_DRY_RUN previews to state/x-outbox and posts nothing. - bin/fm-x-lib.sh: .env/env config (token, relay default, dry-run, max chars, thread cap; env wins over .env) and the thread splitter. - bin/fm-bootstrap.sh: .env-presence activation - drop the check shim + 30s cadence config on opt-in, remove on opt-out, idempotent, silent off. - .agents/skills/fmx-respond: public-safe answer playbook - drain inbox, judge follow-up worthiness (skip pure acks), conversation continuity via in_reply_to, concise by default, dry-run aware. - AGENTS.md section 14 + README/CONTRIBUTING/docs; tests/fm-x-mode.test.sh (hermetic: fake curl, real jq).
* fix(fmx): X-mode mentions are captain instructions - act, then reply Owner-only relay routing means every routed mention is from the firstmate's own owner, so fmx-respond no longer frames the asker as a stranger and may address them as captain. Enabling X mode is the standing authorization, so replies are composed and posted autonomously with no per-reply confirmation; dry-run stays the only non-posting path. A mention's request is a real captain instruction to act on, not merely to reply to: the drain loop now classifies each mention as an actionable request (run firstmate's normal lifecycle - intake, backlog, dispatch, scout, ship - then report the outcome), a question (answer from fleet state), or a pure acknowledgment (skip). The public channel keeps the yolo carve-out: anything destructive, irreversible, or security-sensitive is flagged to the captain through the trusted channel first, never executed straight from a mention. Public-safety (outcomes only, no secrets/internals), the untrusted-in_reply_to caution, and the skip-acknowledgment judgment remain intact. AGENTS.md §14 reflects the owner identity, autonomous answering, and act-on-requests carve-out. * no-mistakes(review): Captain: clarify X-mode consent safeguards * no-mistakes(review): Captain: document X-mode action consent * no-mistakes(document): Captain, sync X-mode docs
* fix(fleet-sync): self-heal safe detached drift, loudly flag stuck clones A pooled clone that drifts off its default branch was silently skipped forever by both the post-merge teardown sync and bootstrap fleet-sync, falling further behind on every merge with only an easy-to-miss skip line. - Auto-recover the one safe case: a clean, detached HEAD that is an ancestor of origin/<default> and whose <default> is free to check out is re-attached and fast-forwarded, reported as 'recovered:'. - Every other off-default state (dirty, non-default named branch, detached with unique commits, diverged) is left untouched and reported as a quantified 'STUCK: ... N commits behind ... - needs attention' warning instead of a quiet drift. Nothing is forced, stashed, or discarded. - Relay the new recovered:/STUCK: outcomes through bootstrap FLEET_SYNC lines; document both in AGENTS.md section 3. - Add tests/fm-fleet-sync.test.sh covering recover, every stuck variant, ordinary fast-forward, already-current, local-only/no-origin skips, the whole-fleet form, and the bootstrap relay. * no-mistakes(review): Guard detached recovery from diverged local defaults * no-mistakes(document): Sync fleet refresh docs * no-mistakes: apply CI fixes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Validation
Do not merge until captain approval.