diff --git a/bin/fm-capability-lib.sh b/bin/fm-capability-lib.sh index a80c5ec76b..ad87b329a5 100755 --- a/bin/fm-capability-lib.sh +++ b/bin/fm-capability-lib.sh @@ -6,9 +6,25 @@ # This header owns the wire format and selection contracts: # - Log path: $FM_HOME/data/capability-outcomes.log (override: FM_CAPABILITY_LOG). # - One append-only line per finished ship/scout teardown: -# ||||| +# |||||[|[|]] # Fields never contain '|' or newlines; invalid fields refuse the append. -# - Outcomes: green (normal landed teardown) or discarded (--force). +# The trailing counts are written only when derivable, each as one +# non-negative integer: fix-rounds is the number of earlier recorded +# pipeline attempts for the task's branch before its final attempt, and +# steers is the confirmed supervisor send count from state/.steers. +# An absent fix-rounds count retains an empty field when steers is present; +# otherwise absent trailing counts are omitted, never guessed. Older +# six-field lines without them stay valid forever. +# - Outcomes (green means exactly what it claims): +# green validation passed on the first recorded pipeline attempt +# (fix-rounds 0) +# fixed validation passed only after earlier recorded attempts +# failed validation ran but its newest recorded attempt never +# completed +# unknown no validation result was derivable at teardown (scout +# reports, direct-PR/local-only delivery, or unavailable run +# records) +# discarded work was discarded by an approved --force teardown # - Secondmate teardowns are not recorded (not a worker capability sample). # - task-type is a free-form slug from meta task_type= when present, else kind # (ship|scout). Firstmate should pass a stable slug at spawn for finer bins. @@ -17,9 +33,10 @@ # cost-filtered profile set; this lib never invents a harness outside it and # never bypasses third-party-model / crew-dispatch guards. # - select=capability-recent ranks allowed profiles by green density -# (green / (green+discarded)) in the window; a sampled profile outranks an -# earlier unsampled one only when density > 0; all-zero or absent evidence -# keeps input (configured) order; no samples for a task-type keep the first. +# (first-try greens / all samples) in the window; a sampled profile +# outranks an earlier unsampled one only when density > 0; all-zero or +# absent evidence keeps input (configured) order; no samples for a +# task-type keep the first. # - Scout tax (~10%): advisory CAPABILITY_SCOUT_TAX stderr suggestion of a # different allowed profile; never changes the selected stdout profile. # FM_CAPABILITY_SCOUT_TAX=0 disables; =1 forces; otherwise a roll @@ -68,45 +85,102 @@ fm_capability_field_ok() { } # Append one outcome line. Args: task-type harness model effort outcome +# [fix-rounds] [steers] +# Each count is optional: a non-empty value must be a non-negative integer. +# An empty fix-rounds value retains its positional field when steers is present. # Best-effort: creates data/ as needed; returns non-zero on invalid fields or # write failure but never blocks teardown callers that ignore the status. fm_capability_log_append() { local task_type=$1 harness=$2 model=$3 effort=$4 outcome=$5 - local log_path ts dir + local fix_rounds=${6:-} steers=${7:-} + local log_path ts dir line case "$outcome" in - green|discarded) ;; + green|fixed|failed|unknown|discarded) ;; *) return 1 ;; esac fm_capability_field_ok "$task_type" || return 1 fm_capability_field_ok "$harness" || return 1 fm_capability_field_ok "$model" || return 1 fm_capability_field_ok "$effort" || return 1 + case "$fix_rounds" in + '') ;; + *[!0-9]*) return 1 ;; + esac + case "$steers" in + '') ;; + *[!0-9]*) return 1 ;; + esac log_path=$(fm_capability_log_path) dir=$(dirname "$log_path") mkdir -p "$dir" || return 1 ts=$(fm_capability_now) fm_capability_field_ok "$ts" || return 1 - printf '%s|%s|%s|%s|%s|%s\n' "$ts" "$task_type" "$harness" "$model" "$effort" "$outcome" >> "$log_path" + line="$ts|$task_type|$harness|$model|$effort|$outcome" + case "$fix_rounds:$steers" in :) ;; *) line="$line|$fix_rounds" ;; esac + case "$steers" in '') ;; *) line="$line|$steers" ;; esac + printf '%s\n' "$line" >> "$log_path" +} + +# Derive the teardown capability outcome from captured `no-mistakes runs` text. +# Args: branch runs-output (empty when unavailable). Rows are newest-first, +# whitespace-separated: