admin: explain detection cooldowns and skipped scans (#12185)

* plugin: describe detection cooldowns and report skipped scans

* admin: expose cooldown eligibility and preserve skipped detection outcomes

* admin: show cooldown eligibility alongside maintenance lock waits

* plugin: retain cooldown activity for older admin servers

* admin: keep manual detection skips out of scheduler run state

* plugin: refresh descriptors on reconnect without downgrading saved schemas

* plugin: allow valid schema refreshes to repair corrupt descriptors

* admin: store eligible_after activity detail as RFC3339

* worker: report admin_script interval skips as skipped detection

* worker: report admin_script interval skips after the last completed job

* admin: show the selected job's cooldown while scheduling is disabled

* admin: report an unsigned interval skip instead of a completed scan

* worker: populate new DetectionComplete fields in Rust senders

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

---------

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Chris LuandDevin authored and GitHub committed 2026-10-28 22:55:36 -07:00
1 parent cb993ab83b
commit 4ed9595a58
24 files changed
+529 -112

No files matched your search

+18 -5
View File
@@ -361,7 +361,10 @@ func (r *Plugin) RequestConfigSchema(ctx context.Context, jobType string, forceR
if err != nil {
return nil, err
}
return r.requestConfigSchema(ctx, jobType, forceRefresh, provider.WorkerID)
}
func (r *Plugin) requestConfigSchema(ctx context.Context, jobType string, forceRefresh bool, workerID string) (*plugin_pb.JobTypeDescriptor, error) {
requestID, err := newRequestID("schema")
if err != nil {
return nil, err
@@ -388,7 +391,7 @@ func (r *Plugin) RequestConfigSchema(ctx context.Context, jobType string, forceR
},
}
if err := r.sendToWorker(provider.WorkerID, requestMessage); err != nil {
if err := r.sendToWorker(workerID, requestMessage); err != nil {
return nil, err
}
@@ -1230,6 +1233,19 @@ func (r *Plugin) handleDetectionComplete(workerID string, message *plugin_pb.Det
if messageText == "" {
messageText = "detection failed"
}
} else if message.SkippedReason != "" {
stage = "skipped"
messageText = message.SkippedReason
}
details := map[string]interface{}{
"success": message.Success,
"total_proposals": message.TotalProposals,
}
if message.SkippedReason != "" {
details["skipped_reason"] = message.SkippedReason
}
if message.EligibleAfter != nil {
details["eligible_after"] = message.EligibleAfter.AsTime().UTC().Format(time.RFC3339)
}
r.appendActivity(JobActivity{
JobType: resolvedJobType,
@@ -1239,10 +1255,7 @@ func (r *Plugin) handleDetectionComplete(workerID string, message *plugin_pb.Det
Stage: stage,
Message: messageText,
OccurredAt: timeToPtr(time.Now().UTC()),
Details: map[string]interface{}{
"success": message.Success,
"total_proposals": message.TotalProposals,
},
Details: details,
})
r.safeSendDetectionComplete(message.RequestId, message)