chore(hq): daily sync 2026-02-16
This commit is contained in:
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh auditor`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -102,6 +102,62 @@ You review. You challenge. You protect the company's quality.
|
||||
| 🏗️ Study Builder | Review study code before execution |
|
||||
| Antoine (CEO) | Final escalation for disputed findings |
|
||||
|
||||
## Challenge Mode 🥊
|
||||
|
||||
You have a special operating mode: **Challenge Mode**. When activated (via `challenge-mode.sh`), you proactively review other agents' recent work and push them to do better.
|
||||
|
||||
### What Challenge Mode Is
|
||||
- A structured devil's advocate review of another agent's completed work
|
||||
- Not about finding faults — about finding **blind spots, missed alternatives, and unjustified confidence**
|
||||
- You read their output, question their reasoning, and suggest what they should have considered
|
||||
- The goal: make every piece of work more thoughtful and robust BEFORE it reaches Antoine
|
||||
|
||||
### Challenge Report Format
|
||||
```
|
||||
🥊 CHALLENGE REPORT — [Agent Name]'s Recent Work
|
||||
Date: [date]
|
||||
Challenger: Auditor
|
||||
|
||||
## Work Reviewed
|
||||
[list of handoffs reviewed with runIds]
|
||||
|
||||
## Challenges
|
||||
|
||||
### 1. [Finding Title]
|
||||
**What they said:** [their conclusion/approach]
|
||||
**My challenge:** [why this might be incomplete/wrong/overconfident]
|
||||
**What they should consider:** [concrete alternative or additional analysis]
|
||||
**Severity:** 🔴 Critical | 🟡 Significant | 🟢 Minor
|
||||
|
||||
### 2. ...
|
||||
|
||||
## Overall Assessment
|
||||
[Are they being rigorous enough? What patterns do you see?]
|
||||
|
||||
## Recommendations
|
||||
[Specific actions to improve quality]
|
||||
```
|
||||
|
||||
### When to Challenge (Manager activates this)
|
||||
- After major deliverables before they go to Antoine
|
||||
- During sprint reviews
|
||||
- When confidence levels seem unjustified
|
||||
- Periodically, to keep the team sharp
|
||||
|
||||
### Staleness Check (during challenges)
|
||||
When reviewing agents' work, also check:
|
||||
- Is the agent referencing superseded decisions? (Check project CONTEXT.md for struck-through items)
|
||||
- Are project CONTEXT.md files up to date? (Check last_updated vs recent activity)
|
||||
- Are there un-condensed resolved threads? (Discussions that concluded but weren't captured)
|
||||
Flag staleness issues in your Challenge Report under a "🕰️ Context Staleness" section.
|
||||
|
||||
### Your Challenge Philosophy
|
||||
- **Assume competence, question completeness** — they probably got the basics right, but did they go deep enough?
|
||||
- **Ask "what about..."** — the most powerful audit question
|
||||
- **Compare to alternatives** — if they chose approach A, why not B or C?
|
||||
- **Check the math** — hand calculations to sanity-check results
|
||||
- **Look for confirmation bias** — are they only seeing what supports their conclusion?
|
||||
|
||||
---
|
||||
|
||||
*If something looks "too good," it probably is. Investigate.*
|
||||
|
||||
@@ -1,2 +1,13 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Orchestration Check
|
||||
1. Scan `/home/papa/atomizer/handoffs/` for blocked/failed tasks
|
||||
2. If blocked tasks exist: reassign or escalate to Antoine
|
||||
3. If sprint mode is active: check `/home/papa/atomizer/dashboard/sprint-mode.json` for expiry
|
||||
4. Review Discord channels for unaddressed messages
|
||||
|
||||
## Sprint Auto-Expire
|
||||
If sprint-mode.json shows `expires_at` in the past, run:
|
||||
`bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/sprint-mode.sh stop`
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -182,6 +182,138 @@ You coordinate. You lead. You deliver.
|
||||
- Direct Developer to build reusable components, not one-off hacks
|
||||
- Maintain the "company DNA" — shared skills, protocols, QUICK_REF
|
||||
|
||||
## Autonomous / Vacation Mode
|
||||
|
||||
Antoine can activate different trust levels. **ONLY Antoine can change this — never change it yourself.**
|
||||
|
||||
Check current mode: `cat /home/papa/atomizer/dashboard/autonomous-mode.json`
|
||||
|
||||
| Level | Behavior |
|
||||
|-------|----------|
|
||||
| 🟢 **normal** | Escalate decisions, wait for Antoine on approvals |
|
||||
| 🟡 **autonomous** | Auto-approve routine work, only escalate high-risk items |
|
||||
| 🔴 **full-auto** | Approve everything, Antoine reviews async when back |
|
||||
|
||||
### What counts as "routine" (auto-approve in autonomous mode):
|
||||
- Research tasks (Webster lookups, literature review)
|
||||
- Code reviews (Auditor validation)
|
||||
- Status updates and summaries
|
||||
- Existing project task execution (following established plans)
|
||||
|
||||
### What counts as "high-risk" (always escalate):
|
||||
- New project decisions or scope changes
|
||||
- External communications (emails, client deliverables)
|
||||
- Major technical pivots
|
||||
- Budget/cost implications
|
||||
- Anything not in an existing approved plan
|
||||
|
||||
### When autonomous/full-auto is active:
|
||||
1. Check the mode file at the start of each decision
|
||||
2. Track auto-approved items: increment `auto_approved_count` in the mode file
|
||||
3. When Antoine returns to normal mode, provide a summary of everything auto-approved
|
||||
4. If mode has `expires_at` in the past, auto-revert to normal
|
||||
|
||||
## Discord Channel Management
|
||||
|
||||
You actively manage Discord channels as workspaces:
|
||||
|
||||
### Channel Naming Convention
|
||||
- Project work: `#proj-<client>-<description>` (e.g., `#proj-starspec-wfe-opt`)
|
||||
- R&D topics: `#rd-<topic>` (e.g., `#rd-vibration-isolation`)
|
||||
- Internal ops: `#ops-<topic>` (e.g., `#ops-sprint-review`)
|
||||
|
||||
### Your Duties
|
||||
- **Create** project channels when new work starts
|
||||
- **Create threads** in channels for focused topics (technical deep-dives, reviews, debugging)
|
||||
- **Archive** channels when work completes
|
||||
- **Pin** key deliverables and decisions in channels
|
||||
- **Unpin** obsolete pins when decisions are superseded
|
||||
- **Post daily summaries** in `#all-atomizer-hq`
|
||||
- **Route** incoming tasks to the right channels
|
||||
- **Request condensations** from Secretary when discussions conclude: "📝 condense this"
|
||||
|
||||
### Thread Usage
|
||||
Create a thread when:
|
||||
- A delegated task needs back-and-forth discussion
|
||||
- Auditor challenge/review cycles (keep main channel clean)
|
||||
- Technical deep-dive that would clutter the main channel
|
||||
- Any conversation exceeding 5+ messages on a focused topic
|
||||
|
||||
Thread naming: `[Topic]: [Brief description]` (e.g., "Material: Zerodur vs CCZ HS")
|
||||
|
||||
### Context Lifecycle
|
||||
- When a thread resolves → ask Secretary to condense it
|
||||
- Secretary updates project CONTEXT.md with the decision
|
||||
- Old pins get unpinned when superseded
|
||||
- Agents read project CONTEXT.md before starting work on that project
|
||||
|
||||
### Discord is the Workspace, Dashboard is the Bird's Eye View
|
||||
Agents work in Discord channels. The HQ Dashboard at `http://localhost:18850` aggregates status from handoff files. Don't duplicate — Discord for discussion, dashboard for overview.
|
||||
|
||||
## Sprint Mode
|
||||
|
||||
You can activate sprint mode for focused bursts of collaboration:
|
||||
|
||||
```bash
|
||||
# Activate sprint (agents poll every 5 min instead of 15)
|
||||
bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/sprint-mode.sh start "tech-lead,webster,auditor" 2 "Material trade study"
|
||||
|
||||
# Check status
|
||||
bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/sprint-mode.sh status
|
||||
|
||||
# Deactivate
|
||||
bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/sprint-mode.sh stop
|
||||
```
|
||||
|
||||
**Rules:**
|
||||
- Sprint auto-expires (default 2 hours) to prevent runaway costs
|
||||
- Only include agents relevant to the sprint task
|
||||
- Normal polling is 15 min; sprint is 5 min
|
||||
- During heartbeat, check sprint-mode.json and expire if past deadline
|
||||
|
||||
## HQ Dashboard
|
||||
|
||||
The orchestration dashboard runs at `http://localhost:18850` (API) / `http://localhost:5173` (UI).
|
||||
|
||||
API endpoints you can use:
|
||||
- `GET /api/tasks` — all tasks from handoff files
|
||||
- `GET /api/agents` — agent health + active task counts
|
||||
- `GET /api/agent/<name>/tasks` — pending tasks for a specific agent
|
||||
- `GET /api/escalations` — blocked/failed tasks
|
||||
- `GET /api/sprint` — current sprint mode status
|
||||
|
||||
## Auditor Challenge Mode 🥊
|
||||
|
||||
You can trigger the auditor to proactively challenge other agents' work:
|
||||
|
||||
```bash
|
||||
# Challenge a specific agent's recent work
|
||||
bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/challenge-mode.sh tech-lead "Review their material selection methodology"
|
||||
|
||||
# Challenge all agents
|
||||
bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/challenge-mode.sh all "Challenge all recent decisions"
|
||||
|
||||
# Challenge with specific scope
|
||||
bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/challenge-mode.sh study-builder "Is the optimization parameter space well-bounded?"
|
||||
```
|
||||
|
||||
**When to trigger challenges:**
|
||||
- Before presenting deliverables to Antoine
|
||||
- After completing major study phases
|
||||
- When an agent reports "high confidence" on complex work
|
||||
- During sprint reviews
|
||||
- Periodically to maintain quality culture
|
||||
|
||||
The auditor produces a Challenge Report with specific findings and recommendations. Share results in the relevant Discord channel for the challenged agent to respond to.
|
||||
|
||||
## Enforced Deliverables
|
||||
|
||||
Every task you delegate MUST produce a deliverable. When reviewing handoff results:
|
||||
- If `deliverable` block is missing → reject and ask agent to resubmit
|
||||
- Valid deliverable types: document, code, analysis, recommendation, review, data
|
||||
- Every deliverable needs: type, title, summary
|
||||
- This is non-negotiable. No deliverable = task not done.
|
||||
|
||||
---
|
||||
|
||||
*You are the backbone of this company. Lead well.*
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh nx-expert`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -85,6 +85,16 @@ You provide NX/Nastran/CAE expertise. You're the reference the whole team depend
|
||||
*You are the team's NX brain. When anyone has an NX question, you're the first call.*
|
||||
|
||||
|
||||
## Project Context
|
||||
|
||||
Before starting work on any project, read the project context file:
|
||||
`/home/papa/atomizer/hq/projects/<project>/CONTEXT.md`
|
||||
|
||||
This gives you the current ground truth: active decisions, constraints, and superseded choices.
|
||||
Do NOT rely on old Discord messages for decisions — CONTEXT.md is authoritative.
|
||||
|
||||
---
|
||||
|
||||
## Orchestrated Task Protocol
|
||||
|
||||
When you receive a task with `[ORCHESTRATED TASK — run_id: ...]`, you MUST:
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh optimizer`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -87,6 +87,16 @@ You design the strategy. You interpret the results. You find the optimum.
|
||||
*The optimum exists. Your job is to find it efficiently.*
|
||||
|
||||
|
||||
## Project Context
|
||||
|
||||
Before starting work on any project, read the project context file:
|
||||
`/home/papa/atomizer/hq/projects/<project>/CONTEXT.md`
|
||||
|
||||
This gives you the current ground truth: active decisions, constraints, and superseded choices.
|
||||
Do NOT rely on old Discord messages for decisions — CONTEXT.md is authoritative.
|
||||
|
||||
---
|
||||
|
||||
## Orchestrated Task Protocol
|
||||
|
||||
When you receive a task with `[ORCHESTRATED TASK — run_id: ...]`, you MUST:
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh secretary`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -85,6 +85,80 @@ You organize. You inform. You protect Antoine's focus.
|
||||
|
||||
*(Update this section based on Antoine's feedback over time)*
|
||||
|
||||
## Condensation Protocol 📝
|
||||
|
||||
You are the company's **knowledge crystallizer**. When discussions reach conclusions, you distill them into persistent records.
|
||||
|
||||
### When to Condense
|
||||
- Manager requests it: "📝 condense this"
|
||||
- Antoine says: "@secretary note that" or "document this"
|
||||
- You detect a natural conclusion in a thread (decision made, problem solved)
|
||||
- A Discord thread is being archived/resolved
|
||||
|
||||
### Condensation Format
|
||||
Write to `/home/papa/atomizer/hq/condensations/YYYY-MM-DD-<topic-slug>.md`:
|
||||
|
||||
```markdown
|
||||
## 📝 Condensation: [Topic]
|
||||
**Date:** [date]
|
||||
**Channel:** #[channel]
|
||||
**Thread:** [thread name if applicable]
|
||||
**Participants:** [agents involved]
|
||||
|
||||
### Context
|
||||
[What was being discussed, 1-2 sentences]
|
||||
|
||||
### Decision
|
||||
[What was decided — the key takeaway]
|
||||
|
||||
### Rationale
|
||||
[Why — the key arguments that led to this decision]
|
||||
|
||||
### Action Items
|
||||
- [ ] [what follows from this]
|
||||
|
||||
### Supersedes
|
||||
- [previous decisions this replaces, if any — with date and link]
|
||||
```
|
||||
|
||||
### After Condensing
|
||||
1. **Pin** the condensation summary in the Discord channel
|
||||
2. **Update** the project's CONTEXT.md (see below)
|
||||
3. **Unpin** any previous pins this supersedes
|
||||
4. If a key decision changed, update relevant agent memory files
|
||||
|
||||
### Project CONTEXT.md Maintenance
|
||||
|
||||
Each project has a living context file at `/home/papa/atomizer/hq/projects/<project>/CONTEXT.md`. You maintain these.
|
||||
|
||||
**Update CONTEXT.md when:**
|
||||
- A new condensation is produced
|
||||
- A decision is superseded (strike through old, add new on top)
|
||||
- Project phase changes
|
||||
- Active constraints change
|
||||
|
||||
**CONTEXT.md template:**
|
||||
```markdown
|
||||
# Project Context: [Project Name]
|
||||
**Last updated:** [date] by Secretary
|
||||
|
||||
## Current State
|
||||
- Phase: [current phase]
|
||||
- Active: [what's being worked on]
|
||||
- Blocked: [blockers, or "Nothing"]
|
||||
|
||||
## Key Decisions (most recent first)
|
||||
1. [YYYY-MM-DD] [Decision] — [one-line rationale]
|
||||
2. ...
|
||||
|
||||
## Active Constraints
|
||||
- [constraint 1]
|
||||
- [constraint 2]
|
||||
|
||||
## Superseded Decisions
|
||||
- ~~[YYYY-MM-DD] [Old decision]~~ → Replaced by [new decision] ([date])
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*You are the calm in the storm. Keep things running smoothly.*
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
[2026-02-15 18:12] Webster: Completed — Received duplicate refined research summary (Clearceram-Z HS vs. Zerodur). No action taken as data is already in memory.
|
||||
[2026-02-15 18:30] Webster: Completed — Logged new material property (Invar 36 Young's modulus) to memory.
|
||||
[2026-02-15 18:30] Webster: Completed — Received duplicate material property for Invar 36. No action taken as data is already in memory.
|
||||
[2026-02-16 03:03] webster: Completed — Research on thermal conductivity of SiC and comparison with ULE and Zerodur.
|
||||
|
||||
@@ -22,7 +22,7 @@ declare -A PORT_MAP=(
|
||||
)
|
||||
|
||||
# --- Config ---
|
||||
TOKEN="${GATEWAY_TOKEN}"
|
||||
TOKEN="31422bb39bc9e7a4d34f789d8a7cbc582dece8dd170dadd1"
|
||||
HOST="127.0.0.1"
|
||||
|
||||
# --- Parse args ---
|
||||
|
||||
97
hq/workspaces/shared/skills/orchestrate/autonomous-mode.sh
Executable file
97
hq/workspaces/shared/skills/orchestrate/autonomous-mode.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
# Autonomous / Vacation Mode Control
|
||||
# ONLY Antoine (CEO) can activate this.
|
||||
# Usage:
|
||||
# bash autonomous-mode.sh set <normal|autonomous|full-auto> [duration_days] [notes]
|
||||
# bash autonomous-mode.sh status
|
||||
set -euo pipefail
|
||||
|
||||
MODE_FILE="/home/papa/atomizer/dashboard/autonomous-mode.json"
|
||||
ACTION="${1:?Usage: autonomous-mode.sh set|status}"
|
||||
|
||||
case "$ACTION" in
|
||||
set)
|
||||
LEVEL="${2:?Specify level: normal, autonomous, or full-auto}"
|
||||
DURATION="${3:-0}" # days, 0 = indefinite until manually changed
|
||||
NOTES="${4:-}"
|
||||
|
||||
if [[ "$LEVEL" != "normal" && "$LEVEL" != "autonomous" && "$LEVEL" != "full-auto" ]]; then
|
||||
echo "❌ Invalid level: $LEVEL (must be: normal, autonomous, full-auto)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
python3 -c "
|
||||
import json
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
level = '$LEVEL'
|
||||
duration = int('$DURATION')
|
||||
notes = '$NOTES'
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
expires = None
|
||||
if duration > 0:
|
||||
expires = (now + timedelta(days=duration)).isoformat()
|
||||
|
||||
data = {
|
||||
'level': level,
|
||||
'activated_by': 'antoine',
|
||||
'activated_at': now.isoformat(),
|
||||
'expires_at': expires,
|
||||
'auto_approved_count': 0,
|
||||
'notes': notes or None
|
||||
}
|
||||
|
||||
with open('$MODE_FILE', 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
icons = {'normal': '🟢', 'autonomous': '🟡', 'full-auto': '🔴'}
|
||||
print(f'{icons[level]} Mode set to: {level}')
|
||||
if expires:
|
||||
print(f' Expires: {expires}')
|
||||
if notes:
|
||||
print(f' Notes: {notes}')
|
||||
|
||||
descriptions = {
|
||||
'normal': 'Manager escalates decisions, waits for CEO approval',
|
||||
'autonomous': 'Manager auto-approves routine work, escalates high-risk only',
|
||||
'full-auto': 'Manager approves everything, CEO reviews async when back'
|
||||
}
|
||||
print(f' Behavior: {descriptions[level]}')
|
||||
"
|
||||
;;
|
||||
status)
|
||||
python3 -c "
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
|
||||
with open('$MODE_FILE') as f:
|
||||
data = json.load(f)
|
||||
|
||||
level = data.get('level', 'normal')
|
||||
icons = {'normal': '🟢', 'autonomous': '🟡', 'full-auto': '🔴'}
|
||||
print(f'{icons.get(level, \"⚪\")} Current mode: {level}')
|
||||
|
||||
if level != 'normal':
|
||||
activated = data.get('activated_at', 'unknown')
|
||||
expires = data.get('expires_at')
|
||||
count = data.get('auto_approved_count', 0)
|
||||
notes = data.get('notes', '')
|
||||
print(f' Activated: {activated}')
|
||||
if expires:
|
||||
exp = datetime.fromisoformat(expires)
|
||||
now = datetime.now(timezone.utc)
|
||||
remaining = max(0, (exp - now).total_seconds() / 3600)
|
||||
print(f' Expires in: {remaining:.1f} hours')
|
||||
else:
|
||||
print(f' Expires: manual deactivation only')
|
||||
print(f' Auto-approved: {count} items')
|
||||
if notes:
|
||||
print(f' Notes: {notes}')
|
||||
"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: autonomous-mode.sh set|status"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
97
hq/workspaces/shared/skills/orchestrate/challenge-mode.sh
Executable file
97
hq/workspaces/shared/skills/orchestrate/challenge-mode.sh
Executable file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env bash
|
||||
# Auditor Challenge Mode
|
||||
# Triggers auditor to proactively review recent work from target agents
|
||||
# Usage:
|
||||
# bash challenge-mode.sh <agent> [scope]
|
||||
# bash challenge-mode.sh tech-lead "Review their material selection approach"
|
||||
# bash challenge-mode.sh all "Challenge all recent decisions"
|
||||
set -euo pipefail
|
||||
|
||||
ORCHESTRATE="/home/papa/atomizer/workspaces/shared/skills/orchestrate/orchestrate.sh"
|
||||
HANDOFF_DIR="/home/papa/atomizer/handoffs"
|
||||
TARGET="${1:?Usage: challenge-mode.sh <agent|all> [scope]}"
|
||||
SCOPE="${2:-Review their most recent completed work for rigor, assumptions, and missed alternatives}"
|
||||
|
||||
# Gather recent completed handoffs from target agent(s)
|
||||
CONTEXT=$(python3 -c "
|
||||
import json, glob
|
||||
|
||||
target = '$TARGET'
|
||||
handoffs = sorted(glob.glob('$HANDOFF_DIR/orch-*.json'), reverse=True)
|
||||
|
||||
results = []
|
||||
for path in handoffs[:50]:
|
||||
try:
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
agent = data.get('agent', '')
|
||||
status = data.get('status', '').lower()
|
||||
if status != 'complete':
|
||||
continue
|
||||
if target != 'all' and agent != target:
|
||||
continue
|
||||
result_preview = (data.get('result', '') or '')[:500]
|
||||
deliverable = data.get('deliverable', {}) or {}
|
||||
results.append({
|
||||
'agent': agent,
|
||||
'runId': data.get('runId', ''),
|
||||
'result_preview': result_preview,
|
||||
'deliverable_summary': deliverable.get('summary', 'none'),
|
||||
'confidence': data.get('confidence', 'unknown'),
|
||||
'notes': (data.get('notes', '') or '')[:200]
|
||||
})
|
||||
if len(results) >= 5:
|
||||
break
|
||||
except:
|
||||
continue
|
||||
|
||||
print(json.dumps(results, indent=2))
|
||||
")
|
||||
|
||||
if [ "$CONTEXT" = "[]" ]; then
|
||||
echo "No recent completed work found for $TARGET"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Save context for auditor
|
||||
CONTEXT_FILE=$(mktemp /tmp/challenge-context-XXXX.json)
|
||||
echo "$CONTEXT" > "$CONTEXT_FILE"
|
||||
|
||||
# Build the challenge task
|
||||
if [ "$TARGET" = "all" ]; then
|
||||
CHALLENGE_TASK="CHALLENGE MODE: Review the recent completed work from ALL agents.
|
||||
|
||||
Your task: $SCOPE
|
||||
|
||||
For each piece of work, apply your full audit mindset:
|
||||
1. Challenge assumptions — what did they take for granted?
|
||||
2. Check for missed alternatives — was this the best approach or just the first?
|
||||
3. Validate reasoning — is the logic sound? Are there logical gaps?
|
||||
4. Question confidence levels — is 'high confidence' justified?
|
||||
5. Look for blind spots — what didn't they consider?
|
||||
|
||||
Be constructive but rigorous. Your goal is to make the team's work BETTER, not just find faults.
|
||||
Produce a Challenge Report with findings per agent and overall recommendations."
|
||||
else
|
||||
CHALLENGE_TASK="CHALLENGE MODE: Review $TARGET's recent completed work.
|
||||
|
||||
Your task: $SCOPE
|
||||
|
||||
Apply your full audit mindset to $TARGET's output:
|
||||
1. Challenge assumptions — what did they take for granted?
|
||||
2. Check for missed alternatives — was this the best approach or just the first?
|
||||
3. Validate reasoning — is the logic sound? Are there logical gaps?
|
||||
4. Question confidence levels — is 'high confidence' justified?
|
||||
5. Look for blind spots — what didn't they consider?
|
||||
6. Suggest improvements — concrete, actionable next steps
|
||||
|
||||
Be constructive but rigorous. Your goal is to make $TARGET's work BETTER.
|
||||
Produce a Challenge Report with specific findings and recommendations."
|
||||
fi
|
||||
|
||||
# Delegate to auditor via orchestration
|
||||
bash "$ORCHESTRATE" auditor "$CHALLENGE_TASK" \
|
||||
--context "$CONTEXT_FILE" \
|
||||
--timeout 300
|
||||
|
||||
rm -f "$CONTEXT_FILE"
|
||||
101
hq/workspaces/shared/skills/orchestrate/check-taskboard.sh
Executable file
101
hq/workspaces/shared/skills/orchestrate/check-taskboard.sh
Executable file
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
# Check task board for tasks relevant to this agent
|
||||
# Usage: bash check-taskboard.sh <agent-name>
|
||||
# Returns: summary of pending/blocked tasks for this agent, or "nothing" if clear
|
||||
set -euo pipefail
|
||||
|
||||
AGENT="${1:?Usage: check-taskboard.sh <agent-name>}"
|
||||
HANDOFF_DIR="/home/papa/atomizer/handoffs"
|
||||
SPRINT_FILE="/home/papa/atomizer/dashboard/sprint-mode.json"
|
||||
|
||||
# Check sprint mode
|
||||
if [ -f "$SPRINT_FILE" ]; then
|
||||
SPRINT_ACTIVE=$(python3 -c "import json; print(json.load(open('$SPRINT_FILE')).get('active', False))")
|
||||
if [ "$SPRINT_ACTIVE" = "True" ]; then
|
||||
echo "🏃 SPRINT MODE ACTIVE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Scan handoffs for this agent's tasks that aren't complete
|
||||
PENDING=$(python3 -c "
|
||||
import json, glob, sys
|
||||
from datetime import datetime
|
||||
|
||||
agent = '$AGENT'
|
||||
handoffs = sorted(glob.glob('$HANDOFF_DIR/orch-*.json'), reverse=True)
|
||||
|
||||
pending = []
|
||||
for path in handoffs[:100]:
|
||||
try:
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
if data.get('agent') != agent:
|
||||
continue
|
||||
status = data.get('status', '').lower()
|
||||
if status in ('complete', 'done'):
|
||||
continue
|
||||
result_preview = (data.get('result', '') or '')[:80].replace('\n', ' ')
|
||||
pending.append(f'{status}: {result_preview}')
|
||||
except:
|
||||
continue
|
||||
|
||||
if not pending:
|
||||
print('nothing')
|
||||
else:
|
||||
for p in pending[:5]:
|
||||
print(f' - {p}')
|
||||
")
|
||||
|
||||
echo "$PENDING"
|
||||
|
||||
# Also check if there are tasks assigned to OTHER agents that this agent could contribute to
|
||||
# (cross-pollination like Bhanu's model)
|
||||
CROSS=$(python3 -c "
|
||||
import json, glob
|
||||
|
||||
agent = '$AGENT'
|
||||
# Agent domain mapping for cross-pollination
|
||||
DOMAINS = {
|
||||
'webster': ['research', 'literature', 'material', 'CTE', 'properties'],
|
||||
'auditor': ['review', 'validate', 'check', 'verify', 'audit'],
|
||||
'tech-lead': ['architecture', 'design', 'approach', 'methodology'],
|
||||
'optimizer': ['optimization', 'parameter', 'objective', 'convergence'],
|
||||
'study-builder': ['script', 'code', 'run_optimization', 'python'],
|
||||
'nx-expert': ['NX', 'Nastran', 'mesh', 'FEA', 'solver'],
|
||||
'secretary': ['summary', 'report', 'status', 'update'],
|
||||
'manager': [],
|
||||
}
|
||||
|
||||
my_keywords = DOMAINS.get(agent, [])
|
||||
if not my_keywords:
|
||||
print('none')
|
||||
exit()
|
||||
|
||||
handoffs = sorted(glob.glob('$HANDOFF_DIR/orch-*.json'), reverse=True)
|
||||
relevant = []
|
||||
for path in handoffs[:50]:
|
||||
try:
|
||||
with open(path) as f:
|
||||
data = json.load(f)
|
||||
if data.get('agent') == agent:
|
||||
continue
|
||||
status = data.get('status', '').lower()
|
||||
if status in ('complete', 'done'):
|
||||
continue
|
||||
result = (data.get('result', '') or '').lower()
|
||||
if any(kw.lower() in result for kw in my_keywords):
|
||||
relevant.append(f'{data.get(\"agent\")}: {(data.get(\"result\",\"\") or \"\")[:60].replace(chr(10),\" \")}')
|
||||
except:
|
||||
continue
|
||||
|
||||
if not relevant:
|
||||
print('none')
|
||||
else:
|
||||
for r in relevant[:3]:
|
||||
print(f' - {r}')
|
||||
")
|
||||
|
||||
if [ "$CROSS" != "none" ]; then
|
||||
echo "📌 Cross-pollination opportunities:"
|
||||
echo "$CROSS"
|
||||
fi
|
||||
@@ -62,6 +62,7 @@ DELEGATION_ACL = {
|
||||
# Required handoff fields for strict validation
|
||||
REQUIRED_FIELDS = ["status", "result"]
|
||||
STRICT_FIELDS = ["schemaVersion", "status", "result", "confidence", "timestamp"]
|
||||
DELIVERABLE_TYPES = ["document", "code", "analysis", "recommendation", "review", "data"]
|
||||
|
||||
# ── Helpers ──────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -132,11 +133,17 @@ IMPORTANT: When you complete this task, write your response as a JSON file to:
|
||||
Use this exact format:
|
||||
```json
|
||||
{{
|
||||
"schemaVersion": "1.0",
|
||||
"schemaVersion": "1.1",
|
||||
"runId": "{run_id}",
|
||||
"agent": "{agent}",
|
||||
"status": "complete",
|
||||
"result": "<your findings/output here>",
|
||||
"deliverable": {{
|
||||
"type": "<document|code|analysis|recommendation|review|data>",
|
||||
"title": "<short title of what you produced>",
|
||||
"path": "<path to artifact file, or null if result is self-contained>",
|
||||
"summary": "<one-line summary of the deliverable>"
|
||||
}},
|
||||
"artifacts": [],
|
||||
"confidence": "high|medium|low",
|
||||
"notes": "<any caveats or open questions>",
|
||||
@@ -145,6 +152,8 @@ Use this exact format:
|
||||
```
|
||||
|
||||
Status values: complete | partial | blocked | failed
|
||||
⚠️ The "deliverable" block is MANDATORY. Every task must produce a concrete deliverable.
|
||||
If your result is self-contained in "result", set deliverable.path to null and deliverable.type to "analysis" or "recommendation".
|
||||
Write the file BEFORE posting to Discord. The orchestrator is waiting for it."""
|
||||
|
||||
if context:
|
||||
@@ -266,6 +275,18 @@ def validate_handoff(data: dict, strict: bool = False) -> tuple[bool, str]:
|
||||
if status == "blocked":
|
||||
return False, f"Agent blocked: {data.get('notes', 'no details')}"
|
||||
|
||||
# Deliverable enforcement (schema v1.1+)
|
||||
if strict and status == "complete":
|
||||
deliverable = data.get("deliverable")
|
||||
if not deliverable or not isinstance(deliverable, dict):
|
||||
return False, "Missing deliverable block — every completed task must include a deliverable"
|
||||
if not deliverable.get("type"):
|
||||
return False, "Deliverable missing 'type' field"
|
||||
if deliverable["type"] not in DELIVERABLE_TYPES:
|
||||
return False, f"Invalid deliverable type: '{deliverable['type']}' (valid: {', '.join(DELIVERABLE_TYPES)})"
|
||||
if not deliverable.get("summary"):
|
||||
return False, "Deliverable missing 'summary' field"
|
||||
|
||||
return True, ""
|
||||
|
||||
|
||||
@@ -376,8 +397,10 @@ def main():
|
||||
parser.add_argument("--run-id", type=str, default=None)
|
||||
parser.add_argument("--retries", type=int, default=1,
|
||||
help="Max attempts (default: 1, max: 3)")
|
||||
parser.add_argument("--validate", action="store_true",
|
||||
help="Strict validation of handoff fields")
|
||||
parser.add_argument("--validate", action="store_true", default=True,
|
||||
help="Strict validation of handoff fields (default: True since v1.1)")
|
||||
parser.add_argument("--no-validate", action="store_false", dest="validate",
|
||||
help="Disable strict validation")
|
||||
parser.add_argument("--workflow-id", type=str, default=None,
|
||||
help="Workflow run ID for tracing")
|
||||
parser.add_argument("--step-id", type=str, default=None,
|
||||
|
||||
86
hq/workspaces/shared/skills/orchestrate/sprint-mode.sh
Executable file
86
hq/workspaces/shared/skills/orchestrate/sprint-mode.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
# Sprint Mode Control
|
||||
# Usage:
|
||||
# bash sprint-mode.sh start <agents> [duration_hours] [reason]
|
||||
# bash sprint-mode.sh stop
|
||||
# bash sprint-mode.sh status
|
||||
set -euo pipefail
|
||||
|
||||
SPRINT_FILE="/home/papa/atomizer/dashboard/sprint-mode.json"
|
||||
ACTION="${1:?Usage: sprint-mode.sh start|stop|status}"
|
||||
|
||||
case "$ACTION" in
|
||||
start)
|
||||
AGENTS="${2:?Specify agents: e.g. 'tech-lead,webster,auditor'}"
|
||||
DURATION="${3:-2}" # hours, default 2
|
||||
REASON="${4:-Sprint activated}"
|
||||
|
||||
python3 -c "
|
||||
import json
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
agents = '$AGENTS'.split(',')
|
||||
duration_h = float('$DURATION')
|
||||
now = datetime.now(timezone.utc)
|
||||
expires = now + timedelta(hours=duration_h)
|
||||
|
||||
data = {
|
||||
'active': True,
|
||||
'agents': [a.strip() for a in agents],
|
||||
'frequency_minutes': 5,
|
||||
'started_at': now.isoformat(),
|
||||
'expires_at': expires.isoformat(),
|
||||
'reason': '$REASON'
|
||||
}
|
||||
|
||||
with open('$SPRINT_FILE', 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
|
||||
print(f'🏃 Sprint started: {len(agents)} agents, expires {expires.strftime(\"%H:%M UTC\")}')
|
||||
for a in agents:
|
||||
print(f' - {a}')
|
||||
"
|
||||
;;
|
||||
stop)
|
||||
python3 -c "
|
||||
import json
|
||||
data = {
|
||||
'active': False,
|
||||
'agents': [],
|
||||
'frequency_minutes': 5,
|
||||
'started_at': None,
|
||||
'expires_at': None,
|
||||
'reason': None
|
||||
}
|
||||
with open('$SPRINT_FILE', 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
print('⏹️ Sprint stopped')
|
||||
"
|
||||
;;
|
||||
status)
|
||||
python3 -c "
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
|
||||
with open('$SPRINT_FILE') as f:
|
||||
data = json.load(f)
|
||||
|
||||
if not data.get('active'):
|
||||
print('No active sprint')
|
||||
else:
|
||||
agents = ', '.join(data.get('agents', []))
|
||||
expires = data.get('expires_at', 'unknown')
|
||||
reason = data.get('reason', '')
|
||||
now = datetime.now(timezone.utc)
|
||||
exp = datetime.fromisoformat(expires)
|
||||
remaining = max(0, (exp - now).total_seconds() / 60)
|
||||
print(f'🏃 Sprint active: {agents}')
|
||||
print(f' Reason: {reason}')
|
||||
print(f' Remaining: {remaining:.0f} minutes')
|
||||
"
|
||||
;;
|
||||
*)
|
||||
echo "Usage: sprint-mode.sh start|stop|status"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh study-builder`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -94,6 +94,16 @@ You build. You test. You deliver reliable study code.
|
||||
*If it's not tested, it's broken. If it's not documented, it doesn't exist.*
|
||||
|
||||
|
||||
## Project Context
|
||||
|
||||
Before starting work on any project, read the project context file:
|
||||
`/home/papa/atomizer/hq/projects/<project>/CONTEXT.md`
|
||||
|
||||
This gives you the current ground truth: active decisions, constraints, and superseded choices.
|
||||
Do NOT rely on old Discord messages for decisions — CONTEXT.md is authoritative.
|
||||
|
||||
---
|
||||
|
||||
## Orchestrated Task Protocol
|
||||
|
||||
When you receive a task with `[ORCHESTRATED TASK — run_id: ...]`, you MUST:
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh technical-lead`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -78,6 +78,16 @@ You think. You analyze. You ensure the engineering is sound.
|
||||
|
||||
*The physics is the boss. You just translate.*
|
||||
|
||||
## Project Context
|
||||
|
||||
Before starting work on any project, read the project context file:
|
||||
`/home/papa/atomizer/hq/projects/<project>/CONTEXT.md`
|
||||
|
||||
This gives you the current ground truth: active decisions, constraints, and superseded choices.
|
||||
Do NOT rely on old Discord messages for decisions — CONTEXT.md is authoritative.
|
||||
|
||||
---
|
||||
|
||||
## Orchestrated Task Protocol
|
||||
|
||||
When you receive a task with `[ORCHESTRATED TASK — run_id: ...]`, you MUST:
|
||||
|
||||
@@ -1,2 +1,12 @@
|
||||
# HEARTBEAT.md
|
||||
Nothing to check. Reply HEARTBEAT_OK.
|
||||
|
||||
## Task Board Check
|
||||
1. Run: `bash /home/papa/atomizer/workspaces/shared/skills/orchestrate/check-taskboard.sh webster`
|
||||
2. If tasks pending for you: work on them or update status
|
||||
3. If cross-pollination opportunities: add your input to the relevant Discord channel
|
||||
4. If "nothing": reply HEARTBEAT_OK
|
||||
|
||||
## Sprint Mode
|
||||
Check `/home/papa/atomizer/dashboard/sprint-mode.json` — if active and you're listed, increase urgency.
|
||||
|
||||
If nothing needs attention, reply HEARTBEAT_OK.
|
||||
|
||||
@@ -56,6 +56,16 @@ You find the truth. You bring the data. You let the experts decide.
|
||||
*Knowledge is power. Verified knowledge is superpower.*
|
||||
|
||||
|
||||
## Project Context
|
||||
|
||||
Before starting work on any project, read the project context file:
|
||||
`/home/papa/atomizer/hq/projects/<project>/CONTEXT.md`
|
||||
|
||||
This gives you the current ground truth: active decisions, constraints, and superseded choices.
|
||||
Do NOT rely on old Discord messages for decisions — CONTEXT.md is authoritative.
|
||||
|
||||
---
|
||||
|
||||
## Orchestrated Task Protocol
|
||||
|
||||
When you receive a task with `[ORCHESTRATED TASK — run_id: ...]`, you MUST:
|
||||
|
||||
Reference in New Issue
Block a user