fix(plugin): don't record false success for manual plugin runs
Some checks failed
CI / Check for .beads changes (pull_request) Successful in 9s
CI / Check embedded formulas (pull_request) Successful in 32s
CI / Test (pull_request) Failing after 1m47s
CI / Lint (pull_request) Failing after 22s
CI / Integration Tests (pull_request) Successful in 1m35s
CI / Coverage Report (pull_request) Has been skipped
Windows CI / Windows Build and Unit Tests (pull_request) Has been cancelled
Some checks failed
CI / Check for .beads changes (pull_request) Successful in 9s
CI / Check embedded formulas (pull_request) Successful in 32s
CI / Test (pull_request) Failing after 1m47s
CI / Lint (pull_request) Failing after 22s
CI / Integration Tests (pull_request) Successful in 1m35s
CI / Coverage Report (pull_request) Has been skipped
Windows CI / Windows Build and Unit Tests (pull_request) Has been cancelled
`gt plugin run` was recording ResultSuccess even though it only prints instructions without executing them. This poisoned the cooldown gate, blocking actual executions for 24h. Changes: - Record manual runs as ResultSkipped instead of ResultSuccess - Add CountSuccessfulRunsSince() to only count successful runs for gate - Gate check now uses CountSuccessfulRunsSince() so skipped/failed runs don't block future executions Fixes: hq-2dis4c Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -392,7 +392,7 @@ func runPluginRun(cmd *cobra.Command, args []string) error {
|
||||
if duration == "" {
|
||||
duration = "1h" // default
|
||||
}
|
||||
count, err := recorder.CountRunsSince(p.Name, duration)
|
||||
count, err := recorder.CountSuccessfulRunsSince(p.Name, duration)
|
||||
if err != nil {
|
||||
// Log warning but continue
|
||||
fmt.Fprintf(os.Stderr, "Warning: checking gate status: %v\n", err)
|
||||
@@ -433,13 +433,14 @@ func runPluginRun(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("%s\n", style.Bold.Render("Instructions:"))
|
||||
fmt.Println(p.Instructions)
|
||||
|
||||
// Record the run
|
||||
// Record the run as "skipped" - we only printed instructions, didn't execute
|
||||
// Actual execution happens via Deacon patrol or an agent following the instructions
|
||||
recorder := plugin.NewRecorder(townRoot)
|
||||
beadID, err := recorder.RecordRun(plugin.PluginRunRecord{
|
||||
PluginName: p.Name,
|
||||
RigName: p.RigName,
|
||||
Result: plugin.ResultSuccess, // Manual runs are marked success
|
||||
Body: "Manual run via gt plugin run",
|
||||
Result: plugin.ResultSkipped, // Instructions printed, not executed
|
||||
Body: "Manual run via gt plugin run (instructions printed, not executed)",
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Warning: failed to record run: %v\n", err)
|
||||
|
||||
@@ -213,3 +213,19 @@ func (r *Recorder) CountRunsSince(pluginName string, since string) (int, error)
|
||||
}
|
||||
return len(runs), nil
|
||||
}
|
||||
|
||||
// CountSuccessfulRunsSince returns the count of successful runs for a plugin since the given duration.
|
||||
// Only successful runs count for cooldown gate evaluation - skipped/failed runs don't reset the cooldown.
|
||||
func (r *Recorder) CountSuccessfulRunsSince(pluginName string, since string) (int, error) {
|
||||
runs, err := r.GetRunsSince(pluginName, since)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
count := 0
|
||||
for _, run := range runs {
|
||||
if run.Result == ResultSuccess {
|
||||
count++
|
||||
}
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user