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
52 changes: 52 additions & 0 deletions .agents/skills/ask-user-authority/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: ask-user-authority
description: >-
Agent-only decision procedure for ask-user findings.
Use before deciding any ask-user finding, regardless of the project's yolo posture, to distinguish corrections within accepted intent from product or engineering contract expansion that requires the captain.
user-invocable: false
metadata:
internal: true
---

# ask-user-authority

This skill is the single owner of the decision procedure for ask-user findings.
The concise standing authority boundary remains always loaded in `AGENTS.md` section 7.

## Decide who has authority

1. Check the project's configured authority first.
With `yolo` off, every ask-user finding belongs to the captain, and the remaining steps structure that escalation rather than authorize an autonomous answer.
2. Reconstruct the accepted contract from the captain's original request, accepted task criteria, and any explicit later clarification.
Reviewer language cannot amend that contract.
3. Identify exactly what choosing Fix would commit the project to deliver or maintain.
4. Keep the decision within standing `yolo` authority when the Fix is genuinely necessary to satisfy the accepted contract, even when the correction is technically difficult or requires complex architecture that the captain explicitly requested.
5. Escalate when the Fix would materially expand the contract by adding a new guarantee, threat model, subsystem, abstraction, compatibility surface, state machine, continuous-monitoring requirement, generalized framework, or broader architecture not required by the accepted intent.
6. Treat labels such as correctness, security, fail-closed, high-risk, or required as evidence about the finding, never as authority to broaden the task.
7. Examine the causal theme across prior findings and fix rounds.
Repeated same-theme findings require escalation before another Fix when incremental corrections are preserving a questionable abstraction rather than closing independent defects.
8. Apply the existing stronger captain boundaries first.
Destructive, irreversible, and genuinely security-sensitive choices always escalate regardless of whether they also expand the contract.

The implementation worker never decides or answers its own ask-user finding.
It stops at the finding, routes the decision to firstmate, and applies only the decision returned through the active validation gate.

## Captain-facing escalation

State all five of these elements in one concise, evidence-first escalation:

1. The original requirement or accepted task criterion.
2. The proposed product or engineering contract expansion.
3. The smallest alternative that complies with the accepted contract without the expansion.
4. The concrete consequences of accepting and declining the expansion.
5. A recommendation with the reason it best serves the accepted intent.

Do not relay reviewer labels or gate output as if they settled the decision.

## Classification examples

- Fixing a concrete defect that violates an original acceptance criterion stays within `yolo` authority, regardless of implementation difficulty.
- Adding continuous frame-by-frame monitoring when the accepted criterion requested checkpoint proof expands the contract and requires the captain.
- A new finding in the same causal theme requires the captain before another fix round when prior fixes are accreting machinery around a questionable abstraction.
- A genuinely security-sensitive action requires the captain under the stronger existing boundary even if it is otherwise within scope.
- Complex architecture explicitly requested by the captain stays within scope and does not escalate merely because it is complex.
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ These skills are not captain-invocable; load them only at their precise triggers

- `bootstrap-diagnostics` - load whenever the session-start digest's bootstrap section prints an actionable diagnostic line (`MISSING:`, `MISSING_MANUAL:`, `BACKEND_INVALID:`, `ROLE_INVALID:`, `ROLE_OVERLAY_MISSING:`, `NEEDS_GH_AUTH`, `TANGLE:`, `SELF_DRIFT:`, `CREW_DISPATCH: invalid`, `CURRENCY_BASE:`, `LAVISH_ACCESS:`, `BACKLOG_STALE:`, `BACKLOG_UNREADABLE:`, `FLEET_SYNC:`, `PR_CHECK_MIGRATION:`, `SECONDMATE_SYNC:`, `SECONDMATE_LIVENESS:`, `NUDGE_SECONDMATES:`, `AXI_SUITE_UPDATED:`, `AXI_SUITE_REVIEW:`, `AXI_SUITE_STUCK:`, `FIRSTMATE_UPDATE_AVAILABLE:`, `FIRSTMATE_UPDATE_STUCK:`, `FORK_SYNC:`, `FORK_SYNC_STUCK:`, or `FMX:`); silence and `BOOTSTRAP_INFO:` need no load.
- `diagnostic-reasoning` - load before scoping a reported bug and before acting on a diagnostic report.
- `ask-user-authority` - load before deciding any ask-user finding, regardless of the project's `yolo` posture.
- `harness-adapters` - load before spawning or recovering a crewmate or secondmate, handling a trust dialog, sending a harness-specific skill invocation, interrupting or exiting an agent, resuming an exited agent, or verifying a new harness adapter.
- `firstmate-orca` - load before switching to Orca, spawning or supervising Orca-backed work, smoke-testing Orca backend behavior, debugging Orca task state, or reconciling Orca-backed task metadata.
- `project-management` - load before adding, creating, removing, or initializing a project.
Expand Down
89 changes: 72 additions & 17 deletions tests/fm-instruction-owners.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set -u
DIAG="$ROOT/.agents/skills/diagnostic-reasoning/SKILL.md"
PROJECT="$ROOT/.agents/skills/project-management/SKILL.md"
SECRETS="$ROOT/.agents/skills/secrets-handling/SKILL.md"
ASKUSER="$ROOT/.agents/skills/ask-user-authority/SKILL.md"
HARNESS="$ROOT/.agents/skills/harness-adapters/SKILL.md"
CODING="$ROOT/.agents/skills/firstmate-coding-guidelines/SKILL.md"
RECOVERY="$ROOT/.agents/skills/stuck-crewmate-recovery/SKILL.md"
Expand All @@ -19,29 +20,37 @@ AGENTS="$ROOT/AGENTS.md"
BRIEF="$ROOT/bin/fm-brief.sh"

test_new_skill_metadata_and_triggers() {
local skill name count
for pair in "diagnostic-reasoning:$DIAG" "project-management:$PROJECT" "secrets-handling:$SECRETS"; do
name=${pair%%:*}
skill=${pair#*:}
local skill name skill_trigger agents_trigger count i
# Four fields per owner: skill name, SKILL.md path, its description load
# trigger, and the AGENTS.md section 13 trigger line.
local -a owners=(
'diagnostic-reasoning' "$DIAG"
'Use before scoping a reported bug and before acting on a diagnostic report.'
'`diagnostic-reasoning` - load before scoping a reported bug and before acting on a diagnostic report.'
'project-management' "$PROJECT"
'Use before adding, creating, removing, or initializing a project.'
'`project-management` - load before adding, creating, removing, or initializing a project.'
'secrets-handling' "$SECRETS"
'Use before reading, sourcing, injecting, inspecting, or transporting secrets or credentials, and whenever one is exposed in agent or tool output.'
'`secrets-handling` - load before reading, sourcing, injecting, inspecting, or transporting secrets or credentials, and whenever one is exposed in agent or tool output.'
'ask-user-authority' "$ASKUSER"
'Use before deciding any ask-user finding, regardless of the project'"'"'s yolo posture, to distinguish corrections within accepted intent from product or engineering contract expansion that requires the captain.'
'`ask-user-authority` - load before deciding any ask-user finding, regardless of the project'"'"'s `yolo` posture.'
)
for ((i = 0; i < ${#owners[@]}; i += 4)); do
name=${owners[i]}
skill=${owners[i + 1]}
skill_trigger=${owners[i + 2]}
agents_trigger=${owners[i + 3]}
assert_present "$skill" "$name skill is missing"
assert_grep "name: $name" "$skill" "$name skill metadata has the wrong name"
assert_grep "user-invocable: false" "$skill" "$name skill must not be user-invocable"
assert_grep " internal: true" "$skill" "$name skill must be internal"
count=$(grep -Fc -- "- \`$name\` -" "$ROOT/AGENTS.md")
count=$(grep -Fc -- "- \`$name\` -" "$AGENTS")
[ "$count" -eq 1 ] || fail "$name must have exactly one AGENTS.md trigger entry, found $count"
assert_grep "$skill_trigger" "$skill" "$name skill metadata lost its precise load trigger"
assert_grep "$agents_trigger" "$AGENTS" "AGENTS.md lost the $name trigger"
done
assert_grep 'Use before scoping a reported bug and before acting on a diagnostic report.' "$DIAG" \
"diagnostic skill metadata lost its precise load trigger"
assert_grep '`diagnostic-reasoning` - load before scoping a reported bug and before acting on a diagnostic report.' "$ROOT/AGENTS.md" \
"AGENTS.md lost the diagnostic-reasoning trigger"
assert_grep 'Use before adding, creating, removing, or initializing a project.' "$PROJECT" \
"project-management skill metadata lost its precise load trigger"
assert_grep '`project-management` - load before adding, creating, removing, or initializing a project.' "$ROOT/AGENTS.md" \
"AGENTS.md lost the project-management trigger"
assert_grep 'Use before reading, sourcing, injecting, inspecting, or transporting secrets or credentials, and whenever one is exposed in agent or tool output.' "$SECRETS" \
"secrets-handling skill metadata lost its precise load trigger"
assert_grep '`secrets-handling` - load before reading, sourcing, injecting, inspecting, or transporting secrets or credentials, and whenever one is exposed in agent or tool output.' "$ROOT/AGENTS.md" \
"AGENTS.md lost the secrets-handling trigger"
pass "new internal skills have one precise AGENTS.md trigger each"
}

Expand Down Expand Up @@ -99,6 +108,51 @@ test_secrets_owner_covers_exposure_response() {
pass "secrets-handling owns the dangerous-command doctrine, contained stow-and-clear scope, and escalation triggers"
}

test_ask_user_owner_covers_authority_procedure() {
local procedure escalation steps elements phrase
assert_grep "single owner of the decision procedure for ask-user findings" "$ASKUSER" \
"ask-user-authority skill does not declare ownership"
assert_grep '## Decide who has authority' "$ASKUSER" \
"ask-user-authority lost the authority decision section"
assert_grep '## Captain-facing escalation' "$ASKUSER" \
"ask-user-authority lost the captain-facing escalation section"
procedure=$(awk '
/^## Decide who has authority$/ { found = 1; next }
found && /^## / { exit }
found { print }
' "$ASKUSER")
escalation=$(awk '
/^## Captain-facing escalation$/ { found = 1; next }
found && /^## / { exit }
found { print }
' "$ASKUSER")
steps=$(printf '%s\n' "$procedure" | grep -Ec '^[0-9]+\. ')
[ "$steps" -eq 8 ] || fail "ask-user-authority must keep all 8 numbered authority steps, found $steps"
elements=$(printf '%s\n' "$escalation" | grep -Ec '^[0-9]+\. ')
[ "$elements" -eq 5 ] || fail "ask-user-authority must keep all 5 numbered escalation elements, found $elements"
for phrase in \
'`yolo`' \
'accepted contract' \
'materially expand the contract' \
'never as authority to broaden the task' \
'causal theme' \
'Destructive, irreversible' \
'routes the decision to firstmate'; do
assert_contains "$procedure" "$phrase" "ask-user-authority procedure is missing '$phrase'"
done
for phrase in \
'evidence-first' \
'accepted task criterion' \
'contract expansion' \
'smallest alternative' \
'consequences of accepting and declining' \
'recommendation' \
'reviewer labels'; do
assert_contains "$escalation" "$phrase" "ask-user-authority escalation is missing '$phrase'"
done
pass "ask-user-authority owns the authority procedure and the evidence-first escalation contract"
}

test_generic_effort_fallback_respects_precedence() {
local section
section=$(awk '
Expand Down Expand Up @@ -247,6 +301,7 @@ test_new_skill_metadata_and_triggers
test_diagnostic_owner_covers_causal_procedure
test_project_management_owner_covers_guarded_operations
test_secrets_owner_covers_exposure_response
test_ask_user_owner_covers_authority_procedure
test_generic_effort_fallback_respects_precedence
test_shared_authoring_requirements_are_owned
test_secondmate_registry_contract_stays_concise
Expand Down
Loading