From dba4fdbd6feba6e317d9508b716b1236f4d52c5f Mon Sep 17 00:00:00 2001 From: Freudator86 Date: Tue, 28 Jul 2026 19:20:57 +0200 Subject: [PATCH 1/3] docs: restore ask-user-authority skill from upstream AGENTS.md section 7 requires the ask-user decision procedure and section 9 requires an evidence-first escalation, but the skill that owns both was never carried into this curated fork, and no AGENTS.md entry pointed at it. Restore the upstream skill verbatim and re-add its section 13 trigger line so the procedure is discoverable at the moment an ask-user finding is decided. --- .agents/skills/ask-user-authority/SKILL.md | 52 ++++++++++++++++++++++ AGENTS.md | 1 + 2 files changed, 53 insertions(+) create mode 100644 .agents/skills/ask-user-authority/SKILL.md diff --git a/.agents/skills/ask-user-authority/SKILL.md b/.agents/skills/ask-user-authority/SKILL.md new file mode 100644 index 0000000000..d4b63d525b --- /dev/null +++ b/.agents/skills/ask-user-authority/SKILL.md @@ -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. diff --git a/AGENTS.md b/AGENTS.md index b1d189c6e4..65b8108c4e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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. From 779c3473deafa3f1cfc6c4ca272c6d2fa72c23a3 Mon Sep 17 00:00:00 2001 From: Freudator86 Date: Fri, 31 Jul 2026 20:55:01 +0200 Subject: [PATCH 2/3] no-mistakes(review): pin ask-user-authority in instruction-owners guard test --- tests/fm-instruction-owners.test.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/fm-instruction-owners.test.sh b/tests/fm-instruction-owners.test.sh index 1c6a9aab39..1c8f59899d 100755 --- a/tests/fm-instruction-owners.test.sh +++ b/tests/fm-instruction-owners.test.sh @@ -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" @@ -20,7 +21,7 @@ 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 + for pair in "diagnostic-reasoning:$DIAG" "project-management:$PROJECT" "secrets-handling:$SECRETS" "ask-user-authority:$ASKUSER"; do name=${pair%%:*} skill=${pair#*:} assert_present "$skill" "$name skill is missing" @@ -42,6 +43,10 @@ test_new_skill_metadata_and_triggers() { "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" + assert_grep '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.' "$ASKUSER" \ + "ask-user-authority skill metadata lost its precise load trigger" + assert_grep '`ask-user-authority` - load before deciding any ask-user finding, regardless of the project'"'"'s `yolo` posture.' "$ROOT/AGENTS.md" \ + "AGENTS.md lost the ask-user-authority trigger" pass "new internal skills have one precise AGENTS.md trigger each" } From 33f2e8eb4eed0536fcb4510404e4ac8b52ddd392 Mon Sep 17 00:00:00 2001 From: Freudator86 Date: Fri, 31 Jul 2026 21:28:53 +0200 Subject: [PATCH 3/3] no-mistakes(review): pin ask-user-authority body structure, collapse per-skill trigger assertions --- tests/fm-instruction-owners.test.sh | 92 ++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 21 deletions(-) diff --git a/tests/fm-instruction-owners.test.sh b/tests/fm-instruction-owners.test.sh index 1c8f59899d..d64e777afb 100755 --- a/tests/fm-instruction-owners.test.sh +++ b/tests/fm-instruction-owners.test.sh @@ -20,33 +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" "ask-user-authority:$ASKUSER"; 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" - assert_grep '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.' "$ASKUSER" \ - "ask-user-authority skill metadata lost its precise load trigger" - assert_grep '`ask-user-authority` - load before deciding any ask-user finding, regardless of the project'"'"'s `yolo` posture.' "$ROOT/AGENTS.md" \ - "AGENTS.md lost the ask-user-authority trigger" pass "new internal skills have one precise AGENTS.md trigger each" } @@ -104,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 ' @@ -252,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