feat: implement Christmas Ornament pattern for mol-witness-patrol (gt-tnow.1, gt-tnow.2)
- Update WitnessPatrolMolecule() with dynamic bonding pattern:
- PREFLIGHT: inbox-check, check-refinery, load-state
- DISCOVERY: survey-workers (bonds mol-polecat-arm per polecat)
- CLEANUP: aggregate (WaitsFor: all-children), save-state, generate-summary,
context-check, burn-or-loop
- Reduced from 11 sequential steps to 9 with parallel arm execution
- Add PolecatArmMolecule() for per-polecat inspection:
- 5 sequential steps: capture, assess, load-history, decide, execute
- Uses {{polecat_name}} and {{rig}} variable substitution
- Bonded dynamically by survey-workers step
- Update tests: 14 builtin molecules, new test cases
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ func BuiltinMolecules() []BuiltinMolecule {
|
|||||||
DeaconPatrolMolecule(),
|
DeaconPatrolMolecule(),
|
||||||
RefineryPatrolMolecule(),
|
RefineryPatrolMolecule(),
|
||||||
WitnessPatrolMolecule(),
|
WitnessPatrolMolecule(),
|
||||||
|
PolecatArmMolecule(),
|
||||||
|
|
||||||
// Session and utility molecules
|
// Session and utility molecules
|
||||||
CrewSessionMolecule(),
|
CrewSessionMolecule(),
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import "testing"
|
|||||||
func TestBuiltinMolecules(t *testing.T) {
|
func TestBuiltinMolecules(t *testing.T) {
|
||||||
molecules := BuiltinMolecules()
|
molecules := BuiltinMolecules()
|
||||||
|
|
||||||
if len(molecules) != 13 {
|
if len(molecules) != 14 {
|
||||||
t.Errorf("expected 13 built-in molecules, got %d", len(molecules))
|
t.Errorf("expected 14 built-in molecules, got %d", len(molecules))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify each molecule can be parsed and validated
|
// Verify each molecule can be parsed and validated
|
||||||
@@ -300,17 +300,17 @@ func TestWitnessPatrolMolecule(t *testing.T) {
|
|||||||
t.Fatalf("failed to parse: %v", err)
|
t.Fatalf("failed to parse: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should have 11 steps: inbox-check, check-refinery, load-state, survey-workers,
|
// Should have 9 steps using Christmas Ornament pattern:
|
||||||
// inspect-workers, decide-actions, execute-actions, save-state, generate-summary,
|
// PREFLIGHT: inbox-check, check-refinery, load-state
|
||||||
// context-check, burn-or-loop
|
// DISCOVERY: survey-workers (bonds mol-polecat-arm dynamically)
|
||||||
if len(steps) != 11 {
|
// CLEANUP: aggregate, save-state, generate-summary, context-check, burn-or-loop
|
||||||
t.Errorf("expected 11 steps, got %d", len(steps))
|
if len(steps) != 9 {
|
||||||
|
t.Errorf("expected 9 steps, got %d", len(steps))
|
||||||
}
|
}
|
||||||
|
|
||||||
expectedRefs := []string{
|
expectedRefs := []string{
|
||||||
"inbox-check", "check-refinery", "load-state", "survey-workers",
|
"inbox-check", "check-refinery", "load-state", "survey-workers",
|
||||||
"inspect-workers", "decide-actions", "execute-actions", "save-state",
|
"aggregate", "save-state", "generate-summary", "context-check", "burn-or-loop",
|
||||||
"generate-summary", "context-check", "burn-or-loop",
|
|
||||||
}
|
}
|
||||||
for i, expected := range expectedRefs {
|
for i, expected := range expectedRefs {
|
||||||
if i >= len(steps) {
|
if i >= len(steps) {
|
||||||
@@ -338,8 +338,72 @@ func TestWitnessPatrolMolecule(t *testing.T) {
|
|||||||
t.Errorf("load-state should need check-refinery, got %v", steps[2].Needs)
|
t.Errorf("load-state should need check-refinery, got %v", steps[2].Needs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aggregate needs survey-workers (fanout gate)
|
||||||
|
if len(steps[4].Needs) != 1 || steps[4].Needs[0] != "survey-workers" {
|
||||||
|
t.Errorf("aggregate should need survey-workers, got %v", steps[4].Needs)
|
||||||
|
}
|
||||||
|
|
||||||
// burn-or-loop needs context-check
|
// burn-or-loop needs context-check
|
||||||
if len(steps[10].Needs) != 1 || steps[10].Needs[0] != "context-check" {
|
if len(steps[8].Needs) != 1 || steps[8].Needs[0] != "context-check" {
|
||||||
t.Errorf("burn-or-loop should need context-check, got %v", steps[10].Needs)
|
t.Errorf("burn-or-loop should need context-check, got %v", steps[8].Needs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestPolecatArmMolecule(t *testing.T) {
|
||||||
|
mol := PolecatArmMolecule()
|
||||||
|
|
||||||
|
if mol.ID != "mol-polecat-arm" {
|
||||||
|
t.Errorf("expected ID 'mol-polecat-arm', got %q", mol.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if mol.Title != "Polecat Arm" {
|
||||||
|
t.Errorf("expected Title 'Polecat Arm', got %q", mol.Title)
|
||||||
|
}
|
||||||
|
|
||||||
|
steps, err := ParseMoleculeSteps(mol.Description)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to parse: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should have 5 steps: capture, assess, load-history, decide, execute
|
||||||
|
if len(steps) != 5 {
|
||||||
|
t.Errorf("expected 5 steps, got %d", len(steps))
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedRefs := []string{"capture", "assess", "load-history", "decide", "execute"}
|
||||||
|
for i, expected := range expectedRefs {
|
||||||
|
if i >= len(steps) {
|
||||||
|
t.Errorf("missing step %d: expected %q", i, expected)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if steps[i].Ref != expected {
|
||||||
|
t.Errorf("step %d: expected ref %q, got %q", i, expected, steps[i].Ref)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify dependencies form a chain
|
||||||
|
// capture has no deps (first step)
|
||||||
|
if len(steps[0].Needs) != 0 {
|
||||||
|
t.Errorf("capture should have no deps, got %v", steps[0].Needs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// assess needs capture
|
||||||
|
if len(steps[1].Needs) != 1 || steps[1].Needs[0] != "capture" {
|
||||||
|
t.Errorf("assess should need capture, got %v", steps[1].Needs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// load-history needs assess
|
||||||
|
if len(steps[2].Needs) != 1 || steps[2].Needs[0] != "assess" {
|
||||||
|
t.Errorf("load-history should need assess, got %v", steps[2].Needs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// decide needs load-history
|
||||||
|
if len(steps[3].Needs) != 1 || steps[3].Needs[0] != "load-history" {
|
||||||
|
t.Errorf("decide should need load-history, got %v", steps[3].Needs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute needs decide
|
||||||
|
if len(steps[4].Needs) != 1 || steps[4].Needs[0] != "decide" {
|
||||||
|
t.Errorf("execute should need decide, got %v", steps[4].Needs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,20 +182,41 @@ Needs: context-check`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WitnessPatrolMolecule returns the witness-patrol molecule definition.
|
// WitnessPatrolMolecule returns the witness-patrol molecule definition.
|
||||||
// This is the per-rig worker monitor's patrol loop with progressive nudging.
|
// This is the per-rig worker monitor's patrol loop using the Christmas Ornament pattern.
|
||||||
func WitnessPatrolMolecule() BuiltinMolecule {
|
func WitnessPatrolMolecule() BuiltinMolecule {
|
||||||
return BuiltinMolecule{
|
return BuiltinMolecule{
|
||||||
ID: "mol-witness-patrol",
|
ID: "mol-witness-patrol",
|
||||||
Title: "Witness Patrol",
|
Title: "Witness Patrol",
|
||||||
Description: `Per-rig worker monitor patrol loop.
|
Description: `Per-rig worker monitor patrol loop using the Christmas Ornament pattern.
|
||||||
|
|
||||||
The Witness is the Pit Boss for your rig. You watch polecats, nudge them toward
|
The Witness is the Pit Boss for your rig. You watch polecats, nudge them toward
|
||||||
completion, verify clean git state before kills, and escalate stuck workers.
|
completion, verify clean git state before kills, and escalate stuck workers.
|
||||||
|
|
||||||
**You do NOT do implementation work.** Your job is oversight, not coding.
|
**You do NOT do implementation work.** Your job is oversight, not coding.
|
||||||
|
|
||||||
This molecule uses wisp storage (.beads-wisp/) for ephemeral patrol state.
|
This molecule uses dynamic bonding to spawn mol-polecat-arm for each worker,
|
||||||
Persistent state (nudge counts, handoffs) is stored in a witness handoff bead.
|
enabling parallel inspection with a fanout gate for aggregation.
|
||||||
|
|
||||||
|
## The Christmas Ornament Shape
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
★ mol-witness-patrol (trunk)
|
||||||
|
/|\
|
||||||
|
┌────────┘ │ └────────┐
|
||||||
|
PREFLIGHT DISCOVERY CLEANUP
|
||||||
|
│ │ │
|
||||||
|
inbox-check survey aggregate (WaitsFor: all-children)
|
||||||
|
check-refnry │ save-state
|
||||||
|
load-state │ generate-summary
|
||||||
|
↓ context-check
|
||||||
|
┌───────┼───────┐ burn-or-loop
|
||||||
|
● ● ● mol-polecat-arm (dynamic)
|
||||||
|
ace nux toast
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
---
|
||||||
|
# PREFLIGHT PHASE
|
||||||
|
---
|
||||||
|
|
||||||
## Step: inbox-check
|
## Step: inbox-check
|
||||||
Process witness mail: lifecycle requests, help requests.
|
Process witness mail: lifecycle requests, help requests.
|
||||||
@@ -254,114 +275,64 @@ If no handoff exists (fresh start), initialize empty state.
|
|||||||
This state persists across wisp burns and session cycles.
|
This state persists across wisp burns and session cycles.
|
||||||
Needs: check-refinery
|
Needs: check-refinery
|
||||||
|
|
||||||
|
---
|
||||||
|
# DISCOVERY PHASE (Dynamic Bonding)
|
||||||
|
---
|
||||||
|
|
||||||
## Step: survey-workers
|
## Step: survey-workers
|
||||||
List polecats and categorize by status.
|
List polecats and bond mol-polecat-arm for each one.
|
||||||
|
|
||||||
` + "```" + `bash
|
` + "```" + `bash
|
||||||
|
# Get list of polecats
|
||||||
gt polecat list <rig>
|
gt polecat list <rig>
|
||||||
` + "```" + `
|
` + "```" + `
|
||||||
|
|
||||||
Categorize each polecat:
|
For each polecat discovered, dynamically bond an inspection arm:
|
||||||
- **working**: Actively processing (needs inspection)
|
|
||||||
- **idle**: At prompt, not active (may need nudge)
|
|
||||||
- **pending_shutdown**: Requested termination (needs pre-kill)
|
|
||||||
- **error**: Showing errors (needs assessment)
|
|
||||||
|
|
||||||
Build action queue for next steps.
|
` + "```" + `bash
|
||||||
|
# Bond mol-polecat-arm for each polecat
|
||||||
|
for polecat in $(gt polecat list <rig> --names); do
|
||||||
|
bd mol bond mol-polecat-arm $PATROL_WISP_ID \
|
||||||
|
--ref arm-$polecat \
|
||||||
|
--var polecat_name=$polecat \
|
||||||
|
--var rig=<rig>
|
||||||
|
done
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
This creates child wisps like:
|
||||||
|
- patrol-x7k.arm-ace (5 steps)
|
||||||
|
- patrol-x7k.arm-nux (5 steps)
|
||||||
|
- patrol-x7k.arm-toast (5 steps)
|
||||||
|
|
||||||
|
Each arm runs in PARALLEL. The aggregate step will wait for all to complete.
|
||||||
|
|
||||||
|
If no polecats are found, this step completes immediately with no children.
|
||||||
Needs: load-state
|
Needs: load-state
|
||||||
|
|
||||||
## Step: inspect-workers
|
---
|
||||||
Capture output for each 'working' polecat.
|
# CLEANUP PHASE (Gate + Fixed Steps)
|
||||||
|
---
|
||||||
|
|
||||||
For each polecat showing "working" status:
|
## Step: aggregate
|
||||||
` + "```" + `bash
|
Collect outcomes from all polecat inspection arms.
|
||||||
tmux capture-pane -t gt-<rig>-<name> -p | tail -40
|
WaitsFor: all-children
|
||||||
` + "```" + `
|
|
||||||
|
|
||||||
Look for:
|
This is a **fanout gate** - it cannot proceed until ALL dynamically-bonded
|
||||||
- Recent tool calls (good - actively working)
|
polecat arms have completed their inspection cycles.
|
||||||
- Prompt waiting for input (may be stuck)
|
|
||||||
- Error messages or stack traces
|
|
||||||
- "Done" or completion indicators
|
|
||||||
- Time since last activity
|
|
||||||
|
|
||||||
Update worker status based on inspection.
|
Once all arms complete, collect their outcomes:
|
||||||
|
- Actions taken per polecat (nudge, kill, escalate, none)
|
||||||
|
- Updated nudge counts
|
||||||
|
- Any errors or issues discovered
|
||||||
|
|
||||||
|
Build the consolidated state for save-state.
|
||||||
Needs: survey-workers
|
Needs: survey-workers
|
||||||
|
|
||||||
## Step: decide-actions
|
|
||||||
Apply nudge matrix and queue actions.
|
|
||||||
|
|
||||||
For each worker, apply decision rules:
|
|
||||||
|
|
||||||
**Progressing normally**: No action needed
|
|
||||||
**Idle <10 min**: Continue monitoring
|
|
||||||
**Idle 10-15 min**: Queue first nudge (gentle)
|
|
||||||
**Idle 15-20 min with no progress since nudge 1**: Queue second nudge (direct)
|
|
||||||
**Idle 20+ min with no progress since nudge 2**: Queue third nudge (final warning)
|
|
||||||
**No response after 3 nudges**: Queue escalation to Mayor
|
|
||||||
**Requesting shutdown**: Queue pre-kill verification
|
|
||||||
**Showing errors**: Assess severity, queue nudge or escalation
|
|
||||||
|
|
||||||
Progressive nudge text:
|
|
||||||
1. "How's progress on <issue>? Need any help?"
|
|
||||||
2. "Please wrap up <issue> soon. What's blocking you?"
|
|
||||||
3. "Final check on <issue>. Will escalate in 5 min if no response."
|
|
||||||
|
|
||||||
Track nudge counts in state - never exceed 3 per issue.
|
|
||||||
Needs: inspect-workers
|
|
||||||
|
|
||||||
## Step: execute-actions
|
|
||||||
Nudge, kill, or escalate as decided.
|
|
||||||
|
|
||||||
Process action queue in order:
|
|
||||||
|
|
||||||
**Nudges:**
|
|
||||||
` + "```" + `bash
|
|
||||||
tmux send-keys -t gt-<rig>-<name> "<nudge text>" Enter
|
|
||||||
` + "```" + `
|
|
||||||
Update nudge count and timestamp in state.
|
|
||||||
|
|
||||||
**Pre-kill verification:**
|
|
||||||
` + "```" + `bash
|
|
||||||
cd polecats/<name> && git status # Must be clean
|
|
||||||
git log origin/main..HEAD # Check for unpushed commits
|
|
||||||
bd show <issue-id> # Verify issue closed
|
|
||||||
` + "```" + `
|
|
||||||
|
|
||||||
If clean:
|
|
||||||
` + "```" + `bash
|
|
||||||
tmux kill-session -t gt-<rig>-<name>
|
|
||||||
git worktree remove polecats/<name> # If transient
|
|
||||||
git branch -d polecat/<name> # If transient
|
|
||||||
` + "```" + `
|
|
||||||
|
|
||||||
If dirty: nudge worker to clean up, wait for retry.
|
|
||||||
If dirty after 3 attempts: escalate to Mayor.
|
|
||||||
|
|
||||||
**Escalations:**
|
|
||||||
` + "```" + `bash
|
|
||||||
gt mail send mayor/ -s "Escalation: <polecat> stuck on <issue>" -m "
|
|
||||||
Worker: <polecat>
|
|
||||||
Issue: <issue-id>
|
|
||||||
Problem: <description>
|
|
||||||
|
|
||||||
Timeline:
|
|
||||||
- Nudge 1: <time> - <response>
|
|
||||||
- Nudge 2: <time> - <response>
|
|
||||||
- Nudge 3: <time> - <response>
|
|
||||||
|
|
||||||
Git state: <clean/dirty>
|
|
||||||
My assessment: <what's happening>
|
|
||||||
Recommendation: <what should happen>
|
|
||||||
"
|
|
||||||
` + "```" + `
|
|
||||||
Needs: decide-actions
|
|
||||||
|
|
||||||
## Step: save-state
|
## Step: save-state
|
||||||
Update handoff bead with new states.
|
Update handoff bead with new states.
|
||||||
|
|
||||||
Persist state to the witness handoff bead:
|
Persist state to the witness handoff bead:
|
||||||
- Updated worker statuses
|
- Updated worker statuses from all arms
|
||||||
- Current nudge counts per worker
|
- Current nudge counts per worker
|
||||||
- Nudge timestamps
|
- Nudge timestamps
|
||||||
- Actions taken this cycle
|
- Actions taken this cycle
|
||||||
@@ -372,7 +343,7 @@ bd update <handoff-bead-id> --description="<serialized state>"
|
|||||||
` + "```" + `
|
` + "```" + `
|
||||||
|
|
||||||
This state survives wisp burns and session cycles.
|
This state survives wisp burns and session cycles.
|
||||||
Needs: execute-actions
|
Needs: aggregate
|
||||||
|
|
||||||
## Step: generate-summary
|
## Step: generate-summary
|
||||||
Summarize this patrol cycle for digest.
|
Summarize this patrol cycle for digest.
|
||||||
@@ -420,6 +391,123 @@ Needs: context-check`,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PolecatArmMolecule returns the polecat-arm molecule definition.
|
||||||
|
// This is dynamically bonded by mol-witness-patrol for each polecat being monitored.
|
||||||
|
func PolecatArmMolecule() BuiltinMolecule {
|
||||||
|
return BuiltinMolecule{
|
||||||
|
ID: "mol-polecat-arm",
|
||||||
|
Title: "Polecat Arm",
|
||||||
|
Description: `Single polecat inspection and action cycle.
|
||||||
|
|
||||||
|
This molecule is bonded dynamically by mol-witness-patrol's survey-workers step.
|
||||||
|
Each polecat being monitored gets one arm that runs in parallel with other arms.
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
| Variable | Required | Description |
|
||||||
|
|----------|----------|-------------|
|
||||||
|
| polecat_name | Yes | Name of the polecat to inspect |
|
||||||
|
| rig | Yes | Rig containing the polecat |
|
||||||
|
|
||||||
|
## Step: capture
|
||||||
|
Capture recent tmux output for {{polecat_name}}.
|
||||||
|
|
||||||
|
` + "```" + `bash
|
||||||
|
tmux capture-pane -t gt-{{rig}}-{{polecat_name}} -p | tail -50
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
Record:
|
||||||
|
- Last activity timestamp (when was last tool call?)
|
||||||
|
- Visible errors or stack traces
|
||||||
|
- Completion indicators ("Done", "Finished", etc.)
|
||||||
|
|
||||||
|
## Step: assess
|
||||||
|
Categorize polecat state based on captured output.
|
||||||
|
|
||||||
|
States:
|
||||||
|
- **working**: Recent tool calls, active processing
|
||||||
|
- **idle**: At prompt, no recent activity
|
||||||
|
- **error**: Showing errors or stack traces
|
||||||
|
- **requesting_shutdown**: Sent LIFECYCLE/Shutdown mail
|
||||||
|
- **done**: Showing completion indicators
|
||||||
|
|
||||||
|
Calculate: minutes since last activity.
|
||||||
|
Needs: capture
|
||||||
|
|
||||||
|
## Step: load-history
|
||||||
|
Read nudge history for {{polecat_name}} from patrol state.
|
||||||
|
|
||||||
|
` + "```" + `
|
||||||
|
nudge_count = state.nudges[{{polecat_name}}].count
|
||||||
|
last_nudge_time = state.nudges[{{polecat_name}}].timestamp
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
This data was loaded by the parent patrol's load-state step and passed
|
||||||
|
to the arm via the bonding context.
|
||||||
|
Needs: assess
|
||||||
|
|
||||||
|
## Step: decide
|
||||||
|
Apply the nudge matrix to determine action for {{polecat_name}}.
|
||||||
|
|
||||||
|
| State | Idle Time | Nudge Count | Action |
|
||||||
|
|-------|-----------|-------------|--------|
|
||||||
|
| working | any | any | none |
|
||||||
|
| idle | <10min | any | none |
|
||||||
|
| idle | 10-15min | 0 | nudge-1 (gentle) |
|
||||||
|
| idle | 15-20min | 1 | nudge-2 (direct) |
|
||||||
|
| idle | 20+min | 2 | nudge-3 (final) |
|
||||||
|
| idle | any | 3 | escalate |
|
||||||
|
| error | any | any | assess-severity |
|
||||||
|
| requesting_shutdown | any | any | pre-kill-verify |
|
||||||
|
| done | any | any | pre-kill-verify |
|
||||||
|
|
||||||
|
Nudge text:
|
||||||
|
1. "How's progress? Need any help?"
|
||||||
|
2. "Please wrap up soon. What's blocking you?"
|
||||||
|
3. "Final check. Will escalate in 5 min if no response."
|
||||||
|
|
||||||
|
Record decision and rationale.
|
||||||
|
Needs: load-history
|
||||||
|
|
||||||
|
## Step: execute
|
||||||
|
Take the decided action for {{polecat_name}}.
|
||||||
|
|
||||||
|
**nudge-N**:
|
||||||
|
` + "```" + `bash
|
||||||
|
tmux send-keys -t gt-{{rig}}-{{polecat_name}} "{{nudge_text}}" Enter
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
**pre-kill-verify**:
|
||||||
|
` + "```" + `bash
|
||||||
|
cd polecats/{{polecat_name}}
|
||||||
|
git status # Must be clean
|
||||||
|
git log origin/main..HEAD # Check for unpushed
|
||||||
|
bd show <assigned-issue> # Verify closed/deferred
|
||||||
|
` + "```" + `
|
||||||
|
If clean: kill session, remove worktree, delete branch
|
||||||
|
If dirty: record failure, retry next cycle
|
||||||
|
|
||||||
|
**escalate**:
|
||||||
|
` + "```" + `bash
|
||||||
|
gt mail send mayor/ -s "Escalation: {{polecat_name}} stuck" -m "..."
|
||||||
|
` + "```" + `
|
||||||
|
|
||||||
|
**none**: No action needed.
|
||||||
|
|
||||||
|
Record: action taken, result, updated nudge count.
|
||||||
|
Needs: decide
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
The arm completes with:
|
||||||
|
- action_taken: none | nudge-1 | nudge-2 | nudge-3 | killed | escalated
|
||||||
|
- result: success | failed | pending
|
||||||
|
- updated_state: New nudge count and timestamp for {{polecat_name}}
|
||||||
|
|
||||||
|
This data feeds back to the parent patrol's aggregate step.`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RefineryPatrolMolecule returns the refinery-patrol molecule definition.
|
// RefineryPatrolMolecule returns the refinery-patrol molecule definition.
|
||||||
// This is the merge queue processor's patrol loop with verification gates.
|
// This is the merge queue processor's patrol loop with verification gates.
|
||||||
func RefineryPatrolMolecule() BuiltinMolecule {
|
func RefineryPatrolMolecule() BuiltinMolecule {
|
||||||
|
|||||||
Reference in New Issue
Block a user