Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .agents/skills/ahoy/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: ahoy
description: Recap only the visible session events since the prior real captain message when the captain explicitly invokes /ahoy, with a Bearings fallback when /ahoy is the session's first real captain message.
user-invocable: true
metadata:
internal: true
---

# ahoy

Give the captain a concise session-only recap without gathering fresh state.

1. Inspect only conversation or session history already visible to the current first mate.
2. Find the most recent real captain-authored message before the current `/ahoy` invocation.
Use Firstmate's existing distinction between captain input and internal or synthetic notifications.
System, developer, tool, watcher, guard, away-mode, and other injected operational messages are not captain messages.
3. If no prior real captain message exists, load [`../bearings/SKILL.md`](../bearings/SKILL.md) and follow it exactly.
Bearings alone owns its gathering, artifact, and response contract.
Do not restate that contract or combine a session recap with Bearings output.
4. If a prior real captain message exists, recap only what happened after that message and before the current invocation.
Include concrete outcomes, landed work, failures, decisions made, new decisions needed, and work still running only when those events appear in visible session history.
Use captain-facing outcome language and preserve every full PR URL present in that interval.
5. The normal recap branch is session-history-only.
Do not call Bearings, shell commands, fleet snapshots, status readers, GitHub or browser APIs, tools, or file reads or writes.
Create no report, persist nothing, and do not guess current live state beyond the last visible event.
6. If nothing happened after the previous captain message, say so directly in one sentence.

The current `/ahoy` message is outside the recap interval.
A previous `/ahoy` is a real captain message and may be the next interval boundary.
If context compaction makes the prior boundary unavailable, state that the exact session boundary is unavailable and summarize only visibly supported events.
Do not silently invoke Bearings unless this is genuinely the first real captain message.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ Claude and grok use the slash form shown here; codex uses the same names with `$
| Skill | What it does |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `/afk` | Enter away-mode supervision: the sub-supervisor self-handles routine notifications in bash, escalates captain-relevant events and bounded declared-external-wait rechecks as batched digests, and actively alerts if delivery gets stuck while you step away |
| `/ahoy` | Recap only visible session events since the prior real captain message, falling back to Bearings when invoked as the session's first real captain message |
| `/bearings` | Generate a standalone current-status report from bounded local fleet and registered-secondmate state, with live PR enrichment only when requested, written to a dated file in `data/` and surfaced concisely in chat; read-mostly, mutates no task state |
| `/updatefirstmate` | Self-update the running firstmate and its secondmates to the latest from origin with fast-forward-only pulls, then re-read instructions and nudge secondmates |
| `/stow` | Sweep the session for uncaptured durable knowledge, route each finding to its disk home per AGENTS.md, file undone next steps to the backlog, and report what is now safe to reset |
Expand Down
46 changes: 46 additions & 0 deletions tests/fm-captain-translation-contract.test.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bash
# Static regression tests for the captain-facing plain-English translation
# contract owned by AGENTS.md section 9.
# shellcheck disable=SC2016
set -u

# shellcheck source=tests/lib.sh
Expand All @@ -15,6 +16,8 @@ HARNESS="$ROOT/.agents/skills/harness-adapters/SKILL.md"
CODEXAPP="$ROOT/.agents/skills/firstmate-codexapp/SKILL.md"
FMX="$ROOT/.agents/skills/fmx-respond/SKILL.md"
UPDATE="$ROOT/.agents/skills/updatefirstmate/SKILL.md"
AHOY="$ROOT/.agents/skills/ahoy/SKILL.md"
README="$ROOT/README.md"

section_9() {
awk '
Expand Down Expand Up @@ -138,10 +141,53 @@ test_section_9_owner_is_not_duplicated_into_skills() {
pass "skills cross-reference section 9 instead of duplicating the mapping list"
}

test_ahoy_is_an_internal_user_invocable_skill() {
assert_present "$AHOY" "ahoy skill is missing"
assert_grep 'name: ahoy' "$AHOY" "ahoy skill metadata has the wrong name"
assert_grep 'user-invocable: true' "$AHOY" "ahoy skill is not user-invocable"
assert_grep ' internal: true' "$AHOY" "ahoy skill is not internal"
[ ! -e "$ROOT/skills/ahoy" ] || fail "ahoy must not exist in the public installer-facing skills directory"
pass "ahoy is internal, user-invocable, and absent from public skills"
}

test_ahoy_readme_uses_cross_harness_convention() {
assert_grep 'Claude and grok use the slash form shown here; codex uses the same names with `$`' "$README" \
"README lost the cross-harness slash and dollar convention"
assert_grep '| `/ahoy`' "$README" "README built-in skills table does not list /ahoy"
pass "README lists ahoy under the shared cross-harness invocation convention"
}

test_ahoy_owns_only_the_visible_session_recap() {
assert_grep '[`../bearings/SKILL.md`](../bearings/SKILL.md)' "$AHOY" \
"first-message fallback does not delegate to Bearings by relative pointer"
assert_grep 'If no prior real captain message exists' "$AHOY" \
"ahoy does not limit Bearings fallback to the first real captain message"
assert_grep 'System, developer, tool, watcher, guard, away-mode, and other injected operational messages are not captain messages.' "$AHOY" \
"ahoy incorrectly treats synthetic operational messages as captain messages"
assert_grep 'The normal recap branch is session-history-only.' "$AHOY" \
"later ahoy invocation is not explicitly session-history-only"
assert_grep 'Do not call Bearings, shell commands, fleet snapshots, status readers, GitHub or browser APIs, tools, or file reads or writes.' "$AHOY" \
"normal recap does not prohibit fresh fleet, file, and tool reads"
assert_grep 'do not guess current live state beyond the last visible event' "$AHOY" \
"normal recap may falsely claim a live snapshot"
assert_grep 'If context compaction makes the prior boundary unavailable' "$AHOY" \
"ahoy does not disclose an unavailable compacted boundary"
assert_grep 'summarize only visibly supported events' "$AHOY" \
"compacted fallback may invent unsupported events"
assert_no_grep 'fm-bearings-snapshot.sh' "$AHOY" \
"ahoy copied Bearings gathering mechanics instead of referencing its owner"
assert_no_grep "Captain's Call" "$AHOY" \
"ahoy copied Bearings response contract instead of referencing its owner"
pass "ahoy delegates first-message fallback and keeps later recaps visible-session-only"
}

test_section_9_owns_positive_translation_contract
test_scout_remains_allowed_house_vocabulary
test_compressed_safety_labels_have_plain_renderings
test_mapping_list_covers_high_risk_internal_families
test_verbatim_internal_evidence_is_rejected_from_chat
test_outward_facing_skill_points_reference_section_9_owner
test_section_9_owner_is_not_duplicated_into_skills
test_ahoy_is_an_internal_user_invocable_skill
test_ahoy_readme_uses_cross_harness_convention
test_ahoy_owns_only_the_visible_session_recap
Loading