diff --git a/.squad/agents/keaton/history.md b/.squad/agents/keaton/history.md index 423026c27..20e4400a0 100644 --- a/.squad/agents/keaton/history.md +++ b/.squad/agents/keaton/history.md @@ -49,6 +49,9 @@ ## Learnings +- PAO external comms architecture decision: Phase 1 uses a scanβ†’draftβ†’reviewβ†’post pipeline with humanizer tone enforcement, SQLite review state, append-only audit logs, and a `pao halt` freeze switch. +- Phase 1 scope and constraints: manual-trigger only, never autonomous, every draft requires explicit human approval before posting, and scheduled scans stay blocked pending Brady approval. + ## πŸ“Œ v0.8.22 Release Disaster β€” 2026-03-07T20:50:00Z **THE WORST RELEASE IN SQUAD HISTORY.** Brady was rightfully upset. This was a catastrophe. Full retrospective written with brutal honesty. diff --git a/.squad/agents/mcmanus/charter.md b/.squad/agents/mcmanus/charter.md index 56406a947..7c417551c 100644 --- a/.squad/agents/mcmanus/charter.md +++ b/.squad/agents/mcmanus/charter.md @@ -16,6 +16,9 @@ - Demos and examples - Tone review and messaging - i18n patterns +- External community responses (draft-only, human review gate) +- Tone enforcement via humanizer skill +- Community signal aggregation (unanswered issues β†’ product signals) ## How I Work @@ -23,10 +26,13 @@ - Celebration blog structure: wave:null, parallel narrative - docs/proposals/ pattern: proposals before execution - Every public-facing statement must be substantiated +- **EXTERNAL COMMS (hard rule):** NEVER post community responses autonomously. All responses are drafted, presented in a review table with confidence flags, and require explicit human approval before posting. +- **HUMANIZER (hard rule):** All external-facing content must pass tone validation β€” warm, helpful, human-sounding. No corporate speak, no marketing hype, no empty acknowledgments. +- **AUDIT TRAIL (hard rule):** Every draft-review-post action is logged to `.squad/comms/audit/`. The audit log is append-only. ## Boundaries -**I handle:** Documentation, demos, messaging, tone review, developer experience, i18n. +**I handle:** README, API docs, demos, examples, tone review, community messaging, contributor recognition, external community response drafting (with human review gate). **I don't handle:** Runtime implementation, architecture decisions, security, distribution mechanics. diff --git a/.squad/comms/.gitignore b/.squad/comms/.gitignore new file mode 100644 index 000000000..1313383b1 --- /dev/null +++ b/.squad/comms/.gitignore @@ -0,0 +1,7 @@ +# Runtime state (not committed) +review-state.db +review-state.db-journal +review-state.db-wal +review-state.db-shm +audit/ +!audit/.gitkeep diff --git a/.squad/comms/README.md b/.squad/comms/README.md new file mode 100644 index 000000000..8359c476a --- /dev/null +++ b/.squad/comms/README.md @@ -0,0 +1,27 @@ +# PAO External Communications + +> Phase 1: Manual-trigger, draft-only mode with human review gate. + +## Directory Structure + +- `audit/` β€” Runtime-only audit trail for every draft-review-post action (not committed to git; keep `audit/.gitkeep`) +- `review-state.db` β€” SQLite-based single-reviewer lease and draft state (created at runtime) +- `templates/` β€” Response templates for common scenarios +- `tests/` β€” Comms workflow and review-state coverage + +## Workflow + +1. Human manually triggers PAO to scan issues and discussions for unanswered items +2. PAO drafts responses using humanizer skill +3. PAO presents review table with confidence flags +4. Human reviews, approves/edits/skips each draft +5. Human posts approved responses +6. Every action is logged to runtime-only `audit/` + +## Safety + +- `banana` β€” freezes all pending drafts (safe word) +- Phase 1 is manual-trigger only +- All responses require explicit human approval +- Audit trail is append-only and runtime-only +- SQLite lease prevents concurrent review race conditions diff --git a/.squad/comms/templates/audit-entry.md b/.squad/comms/templates/audit-entry.md new file mode 100644 index 000000000..2bec18bff --- /dev/null +++ b/.squad/comms/templates/audit-entry.md @@ -0,0 +1,41 @@ +--- +timestamp: "{ISO-8601}" +action: "scan|draft|approve|edit|skip|post|halt|resume|delete|lint_failure|expire" +--- + +> All other fields are conditional on the action type. See **Conditional Fields** table below. +> Frontmatter includes `timestamp` and `action` universally, plus any action-specific required fields from the table. +> Include only the body sections relevant to your action type. + +## Context (draft, approve, edit, skip, post, delete actions) +- Thread depth: {comment count} +- Response type: {welcome|troubleshooting|feature-guidance|redirect|acknowledgment|closing|technical-uncertainty|empathetic-disagreement|information-request} +- Confidence: {🟒|🟑|πŸ”΄} +- Long thread flag: {true|false} + +## Draft Content (draft, edit, post actions) +{full draft text} + +## Reviewer Notes (approve, edit, skip actions) +{any edits or comments from reviewer, or "β€”" if none} + +## Post Result (post, delete actions) +{link to posted comment, or original URL if deleted} + +## Conditional Fields + +Not all fields apply to every action. The `outcome` value is contextual per action: + +| Action | Required Fields | Outcome Value | Optional Fields | +|--------|----------------|---------------|-----------------| +| scan | timestamp, action | item count found (e.g., "5 candidates") | β€” | +| draft | timestamp, action, item_type, item_number, draft_id, confidence, draft_content | β€” (no outcome for draft) | thread_depth | +| approve | timestamp, action, draft_id, reviewer | "approved" | reviewer_notes | +| edit | timestamp, action, draft_id, reviewer, draft_content | "edited" | reviewer_notes | +| skip | timestamp, action, draft_id, reviewer | "skipped" | reviewer_notes | +| post | timestamp, action, item_number, draft_id, reviewer | "posted" + post_result link | β€” | +| halt | timestamp, action, reviewer (halter) | "halted" | reason | +| resume | timestamp, action, reviewer (resumer) | "resumed" | β€” | +| delete | timestamp, action, item_number | "deleted" + original URL | reason | +| lint_failure | timestamp, action, draft_id | violation details (free text) | β€” | +| expire | timestamp, action, draft_id | "expired" | β€” | diff --git a/.squad/comms/templates/review-state-schema.sql b/.squad/comms/templates/review-state-schema.sql new file mode 100644 index 000000000..d49de8d11 --- /dev/null +++ b/.squad/comms/templates/review-state-schema.sql @@ -0,0 +1,72 @@ +-- Runtime reminder: PRAGMA foreign_keys = ON; +-- PAO External Communications: Review State Database +-- Created at runtime in .squad/comms/review-state.db +-- Zero new dependencies (Copilot CLI already uses SQLite) + +-- Single global review lease β€” only ONE reviewer at a time +CREATE TABLE IF NOT EXISTS review_lease ( + id INTEGER PRIMARY KEY CHECK (id = 1), + status TEXT NOT NULL DEFAULT 'available' CHECK (status IN ('available', 'held')), + reviewer TEXT, + hostname TEXT, + pid INTEGER, + acquired_at TEXT, + expires_at TEXT +); + +-- Initialize the single lease row +INSERT OR IGNORE INTO review_lease (id, status) VALUES (1, 'available'); + +-- Acquire: UPDATE review_lease +-- SET status = 'held', reviewer = ?, hostname = ?, pid = ?, acquired_at = datetime('now'), expires_at = datetime('now', '+1 hour') +-- WHERE id = 1 AND (status = 'available' OR expires_at < datetime('now')); +-- Release: UPDATE review_lease +-- SET status = 'available', reviewer = NULL, hostname = NULL, pid = NULL, acquired_at = NULL, expires_at = NULL +-- WHERE id = 1; +-- Check: SELECT * FROM review_lease WHERE id = 1; +-- Cleanup expired lease before work: UPDATE review_lease +-- SET status = 'available', reviewer = NULL, hostname = NULL, pid = NULL, acquired_at = NULL, expires_at = NULL +-- WHERE id = 1 AND status = 'held' AND expires_at < datetime('now'); + +-- Draft tracking table +CREATE TABLE IF NOT EXISTS draft_queue ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + reviewer TEXT, + item_type TEXT NOT NULL CHECK (item_type IN ('issue', 'discussion')), + item_number INTEGER NOT NULL, + item_url TEXT, + response_type TEXT NOT NULL, + confidence TEXT NOT NULL CHECK (confidence IN ('high', 'medium', 'low')), + draft_content TEXT NOT NULL, + thread_depth INTEGER DEFAULT 0, + long_thread_flag INTEGER DEFAULT 0, + status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'approved', 'edited', 'skipped', 'posted', 'halted', 'deleted')), + reviewed_at TEXT, + posted_url TEXT, + created_at TEXT NOT NULL DEFAULT (datetime('now')) +); + +-- Halt state (safe word "banana" mechanism) +CREATE TABLE IF NOT EXISTS halt_state ( + id INTEGER PRIMARY KEY CHECK (id = 1), + halted INTEGER NOT NULL DEFAULT 0, + halted_by TEXT, + halted_at TEXT, + reason TEXT +); + +-- Initialize halt state (not halted by default) +INSERT OR IGNORE INTO halt_state (id, halted) VALUES (1, 0); + +-- Audit log (append-only, mirrors runtime audit files) +CREATE TABLE IF NOT EXISTS audit_log ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TEXT NOT NULL DEFAULT (datetime('now')), + action TEXT NOT NULL, + item_type TEXT, + item_number INTEGER, + draft_id INTEGER, + reviewer TEXT, + outcome TEXT, + details TEXT +); diff --git a/.squad/comms/templates/tone-validation.json b/.squad/comms/templates/tone-validation.json new file mode 100644 index 000000000..c66625fc3 --- /dev/null +++ b/.squad/comms/templates/tone-validation.json @@ -0,0 +1,88 @@ +{ + "version": 1, + "description": "Tone validation patterns for PAO external communications", + "reject_patterns": [ + { + "id": "corporate-speak", + "pattern": "(?:[Ww]e appreciate your patience|[Pp]lease be advised|[Pp]er our discussion|[Aa]s per|[Kk]indly note|[Pp]lease do not hesitate)", + "message": "Corporate speak detected. Use conversational tone instead." + }, + { + "id": "passive-voice-formal", + "pattern": "(?:[Ii]t has been determined|[Ii]t was decided|[Hh]as been escalated|[Ii]s being investigated|[Hh]as been noted)", + "message": "Formal passive voice detected. Use active voice: 'We determined...' or 'We're looking into...'" + }, + { + "id": "marketing-hype", + "pattern": "(?:[Bb]est[- ]in[- ]class|[Cc]utting[- ]edge|[Rr]evolutionary|[Gg]ame[- ]changing|[Ii]ndustry[- ]leading|[Nn]ext[- ]generation|[Aa]mazing feature)", + "message": "Marketing hype detected. Be specific about what the feature does, not how great it is." + }, + { + "id": "empty-acknowledgment", + "pattern": "^\\s*(?:[Tt]hanks for your feedback\\.?|[Tt]hank you for reaching out\\.?)\\s*$", + "message": "Empty acknowledgment without substance. Add specific context or next steps." + }, + { + "id": "robot-signature", + "pattern": "(?:[Bb]est regards|[Ss]incerely|[Kk]ind regards|[Rr]espectfully|[Ww]arm regards)\\s*[,.]?\\s*(?:[Pp][Aa][Oo]|[Tt]he [Ss]quad [Tt]eam|[Ss]quad [Bb]ot)", + "message": "Robot signature detected. Responses should end naturally, not with formal sign-offs." + }, + { + "id": "over-promising", + "pattern": "(?:[Ww]e will ship|[Ww]e'll release|[Cc]oming soon|[Ii]n the next release|[Dd]efinitely fix|[Gg]uaranteed)", + "message": "Over-promising detected. Only commit to what the team has explicitly agreed to." + }, + { + "id": "dismissive", + "pattern": "(?:[Ww]orks as designed|[Nn]ot a bug|[Ww]on't fix|[Tt]hat's expected|[Uu]ser error)", + "message": "Dismissive language detected. Acknowledge the experience before explaining the design." + }, + { + "id": "profanity", + "pattern": "\\b(?:[Dd]amn|[Hh]ell|[Cc]rap|[Ss]hit|[Ff]uck|[Aa]ss|[Bb]astard|[Bb]itch)\\b", + "message": "Profanity detected. Never include profanity, even when quoting." + } + ], + "require_patterns": [ + { + "id": "acknowledgment", + "pattern": "(?:[Tt]hanks|[Tt]hank you|[Gg]ood catch|[Gg]reat question|[Ii]nteresting|[Aa]ppreciate|[Ww]elcome)", + "message": "Response should include acknowledgment of the author's contribution.", + "applies_to": ["welcome", "troubleshooting", "acknowledgment"] + }, + { + "id": "action-oriented", + "pattern": "(?:[Ll]et us know|[Ff]eel free|[Hh]appy to help|[Ww]e'll update|[Rr]each out|[Ww]e'll dig|[Kk]eep us posted)", + "message": "Response should end with an action-oriented close.", + "applies_to": ["troubleshooting", "feature-guidance", "technical-uncertainty"] + }, + { + "id": "context-provided", + "pattern": "(?:[Cc]urrently|[Rr]ight now|[Aa]t the moment|[Aa]s of|[Tt]he way it works)", + "message": "Feature guidance should provide context on current state.", + "applies_to": ["feature-guidance"] + }, + { + "id": "uncertainty-honest", + "pattern": "(?:[Nn]ot sure|[Nn]ot 100%|[Dd]on't know yet|[Ss]till investigating|[Uu]nclear|[Hh]aven't determined)", + "message": "Technical uncertainty should be honest about unknowns.", + "applies_to": ["technical-uncertainty"] + } + ], + "confidence_thresholds": { + "high": { + "description": "Answered before, clear docs, community consensus", + "min_similarity": 0.8, + "baseline_blocking": true + }, + "medium": { + "description": "Technically sound but minor uncertainty or tone-dependent", + "min_similarity": 0.6 + }, + "low": { + "description": "Technical uncertainty, policy decision, reputational risk", + "min_similarity": 0.0, + "requires_review": true + } + } +} diff --git a/.squad/comms/tests/ci-gate.md b/.squad/comms/tests/ci-gate.md new file mode 100644 index 000000000..ba9f658e3 --- /dev/null +++ b/.squad/comms/tests/ci-gate.md @@ -0,0 +1,54 @@ +# CI Tone Lint Gate + +> Automated quality checks for PAO community response drafts. + +## When This Runs + +- Before any draft enters the review table +- As part of PR review when modifying humanizer or external-comms skills +- Weekly tone analytics (manual trigger via `pao analytics`) + +## Checks + +### Mandatory (blocks draft) + +1. **Anti-pattern scan** β€” Run all `reject_patterns` from `tone-validation.json` against draft +2. **Profanity filter** β€” Zero tolerance, even in quotes +3. **Minimum substance** β€” Draft must be >50 characters (no empty acknowledgments) +4. **Thread read verification** β€” Confirm all comments in thread were read before drafting + +### Mandatory for High-Confidence Drafts (🟒 only) + +5. **Baseline similarity** β€” Block if tone similarity to gold standard <80% for high-confidence (🟒) drafts. Aligns with `baseline_blocking: true` in `tone-validation.json`. + +### Warning (flags but doesn't block) + +1. **Positive pattern check** β€” Warn if response type should contain patterns from `require_patterns` +2. **Length check** β€” Warn if draft >500 words (may be too verbose for a GitHub comment) +3. **Emoji count** β€” Warn if >2 emoji in draft +4. **Similarity check** β€” Warn if tone similarity to gold standard <80% for medium/low-confidence drafts + +### Informational + +1. **Response type classification** β€” Log which template was used +2. **Confidence level** β€” Log confidence flag and rationale +3. **Thread depth** β€” Log comment count for analytics + +## Output Format + +``` +βœ… PASS: Anti-pattern scan (0 violations) +βœ… PASS: Profanity filter (clean) +βœ… PASS: Minimum substance (127 chars) +⚠️ WARN: Positive pattern β€” missing action-oriented close +⚠️ WARN: Similarity to GS-2: 72% (threshold: 80%) +ℹ️ INFO: Response type: troubleshooting | Confidence: 🟑 | Thread: 4 comments +``` + +## Failure Mode + +If ANY mandatory check fails: +1. Draft is NOT added to review table +2. Error message shown to PAO with specific violation +3. PAO must redraft before presenting to reviewer +4. Failure logged to audit trail (action: "lint_failure") diff --git a/.squad/comms/tests/tone-validation-spec.md b/.squad/comms/tests/tone-validation-spec.md new file mode 100644 index 000000000..4e8edd5d9 --- /dev/null +++ b/.squad/comms/tests/tone-validation-spec.md @@ -0,0 +1,154 @@ +# Tone Validation Test Specification + +> Quality gates for PAO's external communications. All tests must pass before a draft enters the review table. + +## Test Categories + +### T1: Reject Anti-Patterns + +Drafts containing these patterns MUST be rejected: + +| Test ID | Pattern | Example (should FAIL) | +|---------|---------|----------------------| +| T1.1 | Corporate speak | "We appreciate your patience as we investigate this matter" | +| T1.2 | Formal passive voice | "It has been determined that this is a known issue" | +| T1.3 | Marketing hype | "Squad is the best-in-class solution for this" | +| T1.4 | Empty acknowledgment | "Thanks for your feedback." (with nothing else) | +| T1.5 | Robot signature | "Best regards, PAO" | +| T1.6 | Over-promising | "We'll definitely ship this in the next release" | +| T1.7 | Dismissive language | "Works as designed" (without empathy) | +| T1.8 | Profanity | Any profanity, even quoted from the original issue | + +### T2: Require Positive Patterns + +Drafts of specific types MUST contain these patterns: + +| Test ID | Response Type | Required Pattern | Example (should PASS) | +|---------|---------------|-----------------|----------------------| +| T2.1 | Welcome | Author acknowledgment | "Hey @user! Welcome to Squad πŸ‘‹" | +| T2.2 | Troubleshooting | Action-oriented close | "Let us know if that helps!" | +| T2.3 | Feature guidance | Context on current state | "Currently, Squad handles this by..." | +| T2.4 | Technical uncertainty | Honesty about unknowns | "We're not 100% sure yet..." | + +### T3: Confidence Flag Accuracy + +| Test ID | Scenario | Expected Confidence | +|---------|----------|-------------------| +| T3.1 | Issue matches existing FAQ | 🟒 High | +| T3.2 | Technical question with partial docs | 🟑 Medium | +| T3.3 | Architecture question requiring Flight | πŸ”΄ Needs review | +| T3.4 | Question about unreleased feature | πŸ”΄ Needs review | +| T3.5 | Simple "how to install" question | 🟒 High | + +### T4: Thread Safety + +| Test ID | Scenario | Expected Behavior | +|---------|----------|------------------| +| T4.1 | Thread with >10 comments | ⚠️ Long thread flag set | +| T4.2 | Thread with deleted comments | Validation warning | +| T4.3 | Thread where squad member already responded | Skip (no draft) | +| T4.4 | Thread in different language | Flag for review | + +### T5: Review Gate Enforcement + +| Test ID | Scenario | Expected Behavior | +|---------|----------|------------------| +| T5.1 | Draft without human review | BLOCKED β€” cannot post | +| T5.2 | `pao approve` command without draft ID | Error message | +| T5.3 | Concurrent review sessions | SQLite lock prevents race | +| T5.4 | Stale lock (>1 hour) | Auto-cleanup, new session allowed | +| T5.5 | `banana` issued (safe word) | All pending drafts frozen | +| T5.6 | `pao resume` after banana | Drafts unfrozen | + +### T6: Audit Trail Completeness + +| Test ID | Action | Expected Audit Entry | +|---------|--------|---------------------| +| T6.1 | Scan completed | scan action with item count | +| T6.2 | Draft created | draft action with content | +| T6.3 | Draft approved | approve action with reviewer | +| T6.4 | Draft skipped | skip action with reviewer | +| T6.5 | Response posted | post action with URL | +| T6.6 | `banana` issued (safe word) | halt action with issuer | +| T6.7 | Draft deleted (rollback) | delete action with reason | + +### T7: Baseline Comparison (Weekly) + +| Test ID | Metric | Threshold | Frequency | +|---------|--------|-----------|-----------| +| T7.1 | Tone similarity to gold standard | >80% | Per draft | +| T7.2 | Response type distribution | No single type >60% | Weekly | +| T7.3 | Confidence flag distribution | πŸ”΄ items <20% | Weekly | +| T7.4 | Average thread read depth | >95% of comments read | Per draft | + +## Gold Standard Responses + +The following 7 gold standard responses serve as the tone baseline. New drafts should align with this tone: + +### GS-1: Welcome (High confidence) +> Hey @newuser! Welcome to Squad πŸ‘‹ Thanks for opening this β€” great first issue! +> +> To answer your question: Squad uses `.squad/team.md` to define your team roster. You can add members by editing that file directly or running `squad init`. +> +> Let us know if you hit any snags β€” happy to help! + +### GS-2: Troubleshooting (High confidence) +> Thanks for the detailed report, @reporter! +> +> This looks like it might be related to the casting registry not finding the universe file. Here's what we'd suggest: +> 1. Check that `.squad/casting/registry.json` exists and is valid JSON +> 2. Run `squad build` to regenerate from source +> 3. If that doesn't work, try deleting `.squad/casting/` and re-running `squad init` +> +> Let us know if that helps, or if you're seeing something different. + +### GS-3: Feature Guidance (Medium confidence) +> Great question! Right now, Squad handles cross-repo orchestration through the hub-and-spoke model β€” you'd have a central `.squad/` in one repo and reference it from others. +> +> We know this isn't ideal for every setup. There's been some discussion about making this more seamless (see #316 for the RFC). +> +> For now, the workaround is to use `squad export` to share config across repos. Hope that helps! + +### GS-4: Acknowledgment (High confidence) +> Good catch, @finder. We've confirmed this is a real issue with the session pool cleanup. +> +> It looks like sessions aren't being released when the adapter disconnects unexpectedly. We're tracking it and will update this thread when we have a fix. +> +> Thanks for flagging it β€” this one would have been hard to find without your repro steps! + +### GS-5: Technical Uncertainty (Low confidence) +> Interesting find, @explorer. We're not 100% sure what's causing this yet. +> +> Here's what we've ruled out: +> - It's not a casting issue (registry looks fine) +> - It's not a config issue (your squad.config.ts parses correctly) +> +> Could you share the output of `squad build --verbose`? That would help us narrow it down. We'll dig deeper and update this thread. + +### GS-6: Redirect (High confidence) +> Thanks for reaching out, @asker! This one is actually better suited for the Squad-IRL repo, which covers deployment patterns and infrastructure around Squad. +> +> You can open it here: https://github.com/bradygaster/Squad-IRL β€” they'll be able to help with the Terraform setup specifically. +> +> Feel free to link back to this thread for context! + +### GS-7: Closing (High confidence) +> This should be resolved in v0.8.22! πŸŽ‰ +> +> The fix was in PR #389 β€” the casting registry now handles universe overflow correctly when you have more than 15 agents. +> +> Thanks for reporting this, @reporter β€” your repro steps made this one easy to track down. Closing this out! + +## Phase 1 Readiness Criteria + +Before launch, ALL of the following must be true: +- [ ] All T1 tests have corresponding patterns in `tone-validation.json` +- [ ] All T2 tests verified against humanizer skill templates +- [ ] All 7 gold standard responses reviewed and approved by Brady or Dina +- [ ] All 9 response types have corresponding templates (7 original + empathetic disagreement + information request) +- [ ] Thread-read verification tested with threads of 1, 5, 10, and 20+ comments +- [ ] Rollback workflow (delete-and-repost) tested end-to-end +- [ ] Review gate SQLite schema tested with concurrent access +- [ ] Audit trail format validated against template +- [ ] `banana` / `pao resume` flow tested end-to-end +- [ ] At least one full scanβ†’draftβ†’reviewβ†’post cycle completed successfully diff --git a/.squad/routing.md b/.squad/routing.md index 7c1108849..28fc98bae 100644 --- a/.squad/routing.md +++ b/.squad/routing.md @@ -11,6 +11,7 @@ | Runtime performance | Fortier ⚑ | Streaming, event loop health, session management, async iterators, memory profiling | | Tests & quality | Hockney πŸ§ͺ | Test coverage, Vitest, edge cases, CI/CD, quality gates | | Docs & messaging | McManus πŸ“£ | README, API docs, getting-started, demos, tone review | +| Community response | McManus πŸ“£ | Manual-trigger scan of unanswered issues/discussions, draft responses with human review gate | | Architecture & review | Keaton πŸ—οΈ | Product direction, architectural decisions, code review, scope/trade-offs | | Distribution | Rabin πŸ“¦ | npm packaging, esbuild config, global install, marketplace prep | | Release management | Trejo 🚒 | Semantic versioning, GitHub Releases, changelogs, devβ†’main merges, release gating | diff --git a/.squad/skills/external-comms/SKILL.md b/.squad/skills/external-comms/SKILL.md new file mode 100644 index 000000000..9ac372dca --- /dev/null +++ b/.squad/skills/external-comms/SKILL.md @@ -0,0 +1,329 @@ +--- +name: "external-comms" +description: "PAO workflow for scanning, drafting, and presenting community responses with human review gate" +domain: "community, communication, workflow" +confidence: "low" +source: "manual (RFC #426 β€” PAO External Communications)" +tools: + - name: "github-mcp-server-list_issues" + description: "List open issues for scan candidates and lightweight triage" + when: "Use for recent open issue scans before thread-level review" + - name: "github-mcp-server-issue_read" + description: "Read the full issue, comments, and labels before drafting" + when: "Use after selecting a candidate so PAO has complete thread context" + - name: "github-mcp-server-search_issues" + description: "Search for candidate issues or prior squad responses" + when: "Use when filtering by keywords, labels, or duplicate response checks" + - name: "gh CLI" + description: "Fallback for GitHub issue comments and discussions workflows" + when: "Use gh issue list/comment and gh api or gh api graphql when MCP coverage is incomplete" +--- + +## Context + +Phase 1 is **draft-only mode**. + +- PAO scans issues and discussions, drafts responses with the humanizer skill, and presents a review table for human approval. +- **Human review gate is mandatory** β€” PAO never posts autonomously. +- Every action is logged to `.squad/comms/audit/`. +- This workflow is triggered manually only ("PAO, check community") β€” no automated or Ralph-triggered activation in Phase 1. + +## Patterns + +### 1. Scan + +Find unanswered community items with GitHub MCP tools first, or `gh issue list` / `gh api` as fallback for issues and discussions. + +- Include **open** issues and discussions only. +- Filter for items with **no squad team response**. +- Limit to items created in the last 7 days. +- Exclude items labeled `squad:internal` or `wontfix`. +- Include discussions **and** issues in the same sweep. +- Phase 1 scope is **issues and discussions only** β€” do not draft PR replies. + +### Discussion Handling (Phase 1) + +Discussions use the GitHub Discussions API, which differs from issues: + +- **Scan:** `gh api /repos/{owner}/{repo}/discussions --jq '.[] | select(.answer_chosen_at == null)'` to find unanswered discussions +- **Categories:** Filter by Q&A and General categories only (skip Announcements, Show and Tell) +- **Answers vs comments:** In Q&A discussions, PAO drafts an "answer" (not a comment). The human marks it as accepted answer after posting. +- **Phase 1 scope:** Issues and Discussions ONLY. No PR comments. + +### 2. Classify + +Determine the response type before drafting. + +- Welcome (new contributor) +- Troubleshooting (bug/help) +- Feature guidance (feature request/how-to) +- Redirect (wrong repo/scope) +- Acknowledgment (confirmed, no fix) +- Closing (resolved) +- Technical uncertainty (unknown cause) +- Empathetic disagreement (pushback on a decision or design) +- Information request (need more reproduction details or context) + +### Template Selection Guide + +| Signal in Issue/Discussion | β†’ Response Type | Template | +|---------------------------|-----------------|----------| +| New contributor (0 prior issues) | Welcome | T1 | +| Error message, stack trace, "doesn't work" | Troubleshooting | T2 | +| "How do I...?", "Can Squad...?", "Is there a way to...?" | Feature Guidance | T3 | +| Wrong repo, out of scope for Squad | Redirect | T4 | +| Confirmed bug, no fix available yet | Acknowledgment | T5 | +| Fix shipped, PR merged that resolves issue | Closing | T6 | +| Unclear cause, needs investigation | Technical Uncertainty | T7 | +| Author disagrees with a decision or design | Empathetic Disagreement | T8 | +| Need more reproduction info or context | Information Request | T9 | + +Use exactly one template as the base draft. Replace placeholders with issue-specific details, then apply the humanizer patterns. If the thread spans multiple signals, choose the highest-risk template and capture the nuance in the thread summary. + +### Confidence Classification + +| Confidence | Criteria | Example | +|-----------|----------|---------| +| 🟒 High | Answer exists in Squad docs or FAQ, similar question answered before, no technical ambiguity | "How do I install Squad?" | +| 🟑 Medium | Technical answer is sound but involves judgment calls, OR docs exist but don't perfectly match the question, OR tone is tricky | "Can Squad work with Azure DevOps?" (yes, but setup is nuanced) | +| πŸ”΄ Needs Review | Technical uncertainty, policy/roadmap question, potential reputational risk, author is frustrated/angry, question about unreleased features | "When will Squad support Claude?" | + +**Auto-escalation rules:** +- Any mention of competitors β†’ πŸ”΄ +- Any mention of pricing/licensing β†’ πŸ”΄ +- Author has >3 follow-up comments without resolution β†’ πŸ”΄ +- Question references a closed-wontfix issue β†’ πŸ”΄ + +### 3. Draft + +Use the humanizer skill for every draft. + +- Complete **Thread-Read Verification** before writing. +- Read the **full thread**, including all comments, before writing. +- Select the matching template from the **Template Selection Guide** and record the template ID in the review notes. +- Treat templates as reusable drafting assets: keep the structure, replace placeholders, and only improvise when the thread truly requires it. +- Validate the draft against the humanizer anti-patterns. +- Flag long threads (`>10` comments) with `⚠️`. + +### Thread-Read Verification + +Before drafting, PAO MUST verify complete thread coverage: + +1. **Count verification:** Compare API comment count with actually-read comments. If mismatch, abort draft. +2. **Deleted comment check:** Use `gh api` timeline to detect deleted comments. If found, flag as ⚠️ in review table. +3. **Thread summary:** Include in every draft: "Thread: {N} comments, last activity {date}, {summary of key points}" +4. **Long thread flag:** If >10 comments, add ⚠️ to review table and include condensed thread summary +5. **Evidence line in review table:** Each draft row includes "Read: {N}/{total} comments" column + +### 4. Present + +Show drafts for review in this exact format: + +```text +πŸ“ PAO β€” Community Response Drafts +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +| # | Item | Author | Type | Confidence | Read | Preview | +|---|------|--------|------|------------|------|---------| +| 1 | Issue #N | @user | Type | 🟒/🟑/πŸ”΄ | N/N | "First words..." | + +Confidence: 🟒 High | 🟑 Medium | πŸ”΄ Needs review + +Full drafts below β–Ό +``` + +Each full draft must begin with the thread summary line: +`Thread: {N} comments, last activity {date}, {summary of key points}` + +### 5. Human Action + +Wait for explicit human direction before anything is posted. + +- `pao approve 1 3` β€” approve drafts 1 and 3 +- `pao edit 2` β€” edit draft 2 +- `pao skip` β€” skip all +- `banana` β€” freeze all pending (safe word) + +### Rollback β€” Bad Post Recovery + +If a posted response turns out to be wrong, inappropriate, or needs correction: + +1. **Delete the comment:** + - Issues: `gh api -X DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}` + - Discussions: `gh api graphql -f query='mutation { deleteDiscussionComment(input: {id: "{node_id}"}) { comment { id } } }'` +2. **Log the deletion:** Write audit entry with action `delete`, include reason and original content +3. **Draft replacement** (if needed): PAO drafts a corrected response, goes through normal review cycle +4. **Postmortem:** If the error reveals a pattern gap, update humanizer anti-patterns or add a new test case + +**Safe word β€” `banana`:** +- Immediately freezes all pending drafts in the review queue +- No new scans or drafts until `pao resume` is issued +- Audit entry logged with halter identity and reason + +### 6. Post + +After approval: + +- Human posts via `gh issue comment` for issues or `gh api` for discussion answers/comments. +- PAO helps by preparing the CLI command. +- Write the audit entry after the posting action. + +### 7. Audit + +Log every action. + +- Location: `.squad/comms/audit/{timestamp}.md` +- Required fields vary by action β€” see `.squad/comms/templates/audit-entry.md` Conditional Fields table +- Universal required fields: `timestamp`, `action` +- All other fields are conditional on the action type + +## Examples + +These are reusable templates. Keep the structure, replace placeholders, and adjust only where the thread requires it. + +### Example scan command + +```bash +gh issue list --state open --json number,title,author,labels,comments --limit 20 +``` + +### Example review table + +```text +πŸ“ PAO β€” Community Response Drafts +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +| # | Item | Author | Type | Confidence | Read | Preview | +|---|------|--------|------|------------|------|---------| +| 1 | Issue #426 | @newdev | Welcome | 🟒 | 1/1 | "Hey @newdev! Welcome to Squad..." | +| 2 | Discussion #18 | @builder | Feature guidance | 🟑 | 4/4 | "Great question! Today the CLI..." | +| 3 | Issue #431 ⚠️ | @debugger | Technical uncertainty | πŸ”΄ | 12/12 | "Interesting find, @debugger..." | + +Confidence: 🟒 High | 🟑 Medium | πŸ”΄ Needs review + +Full drafts below β–Ό +``` + +### Example audit entry (post action) + +```markdown +--- +timestamp: "2026-03-16T21:30:00Z" +action: "post" +item_number: 426 +draft_id: 1 +reviewer: "@bradygaster" +--- + +## Context (draft, approve, edit, skip, post, delete actions) +- Thread depth: 3 +- Response type: welcome +- Confidence: 🟒 +- Long thread flag: false + +## Draft Content (draft, edit, post actions) +Thread: 3 comments, last activity 2026-03-16, reporter hit a preview-build regression after install. + +Hey @newdev! Welcome to Squad πŸ‘‹ Thanks for opening this. +We reproduced the issue in preview builds and we're checking the regression point now. +Let us know if you can share the command you ran right before the failure. + +## Post Result (post, delete actions) +https://github.com/bradygaster/squad/issues/426#issuecomment-123456 +``` + +### T1 β€” Welcome + +```text +Hey {author}! Welcome to Squad πŸ‘‹ Thanks for opening this. +{specific acknowledgment or first answer} +Let us know if you have questions β€” happy to help! +``` + +### T2 β€” Troubleshooting + +```text +Thanks for the detailed report, {author}! +Here's what we think is happening: {explanation} +{steps or workaround} +Let us know if that helps, or if you're seeing something different. +``` + +### T3 β€” Feature Guidance + +```text +Great question! {context on current state} +{guidance or workaround} +We've noted this as a potential improvement β€” {tracking info if applicable}. +``` + +### T4 β€” Redirect + +```text +Thanks for reaching out! This one is actually better suited for {correct location}. +{brief explanation of why} +Feel free to open it there β€” they'll be able to help! +``` + +### T5 β€” Acknowledgment + +```text +Good catch, {author}. We've confirmed this is a real issue. +{what we know so far} +We'll update this thread when we have a fix. Thanks for flagging it! +``` + +### T6 β€” Closing + +```text +This should be resolved in {version/PR}! πŸŽ‰ +{brief summary of what changed} +Thanks for reporting this, {author} β€” it made Squad better. +``` + +### T7 β€” Technical Uncertainty + +```text +Interesting find, {author}. We're not 100% sure what's causing this yet. +Here's what we've ruled out: {list} +We'd love more context if you have it β€” {specific ask}. +We'll dig deeper and update this thread. +``` + +### T8 β€” Empathetic Disagreement + +```text +We hear you, {author}. That's a fair concern. + +The current design choice was driven by {reason}. We know it's not ideal for every use case. + +{what alternatives exist or what trade-off was made} + +If you have ideas for how to make this work better for your scenario, we'd love to hear them β€” open a discussion or drop your thoughts here! +``` + +### T9 β€” Information Request + +```text +Thanks for reporting this, {author}! + +To help us dig into this, could you share: +- {specific ask 1} +- {specific ask 2} +- {specific ask 3, if applicable} + +That context will help us narrow down what's happening. Appreciate it! +``` + +## Anti-Patterns + +- ❌ Posting without human review (NEVER β€” this is the cardinal rule) +- ❌ Drafting without reading full thread (context is everything) +- ❌ Ignoring confidence flags (πŸ”΄ items need Flight/human review) +- ❌ Scanning closed issues (only open items) +- ❌ Responding to issues labeled `squad:internal` or `wontfix` +- ❌ Skipping audit logging (every action must be recorded) +- ❌ Drafting for issues where a squad member already responded (avoid duplicates) +- ❌ Drafting pull request responses in Phase 1 (issues/discussions only) +- ❌ Treating templates like loose examples instead of reusable drafting assets +- ❌ Asking for more info without specific requests diff --git a/.squad/skills/humanizer/SKILL.md b/.squad/skills/humanizer/SKILL.md new file mode 100644 index 000000000..4dbb854df --- /dev/null +++ b/.squad/skills/humanizer/SKILL.md @@ -0,0 +1,105 @@ +--- +name: "humanizer" +description: "Tone enforcement patterns for external-facing community responses" +domain: "communication, tone, community" +confidence: "low" +source: "manual (RFC #426 β€” PAO External Communications)" +--- + +## Context + +Use this skill whenever PAO drafts external-facing responses for issues or discussions. + +- Tone must be warm, helpful, and human-sounding β€” never robotic or corporate. +- Brady's constraint applies everywhere: **Humanized tone is mandatory**. +- This applies to **all external-facing content** drafted by PAO in Phase 1 issues/discussions workflows. + +## Patterns + +1. **Warm opening** β€” Start with acknowledgment ("Thanks for reporting this", "Great question!") +2. **Active voice** β€” "We're looking into this" not "This is being investigated" +3. **Second person** β€” Address the person directly ("you" not "the user") +4. **Conversational connectors** β€” "That said...", "Here's what we found...", "Quick note:" +5. **Specific, not vague** β€” "This affects the casting module in v0.8.x" not "We are aware of issues" +6. **Empathy markers** β€” "I can see how that would be frustrating", "Good catch!" +7. **Action-oriented closes** β€” "Let us know if that helps!" not "Please advise if further assistance is required" +8. **Uncertainty is OK** β€” "We're not 100% sure yet, but here's what we think is happening..." is better than false confidence +9. **Profanity filter** β€” Never include profanity, slurs, or aggressive language, even when quoting +10. **Baseline comparison** β€” Responses should align with tone of 5-10 "gold standard" responses (>80% similarity threshold) +11. **Empathetic disagreement** β€” "We hear you. That's a fair concern." before explaining the reasoning +12. **Information request** β€” Ask for specific details, not open-ended "can you provide more info?" +13. **No link-dumping** β€” Don't just paste URLs. Provide context: "Check out the [getting started guide](url) β€” specifically the section on routing" not just a bare link + +## Examples + +### 1. Welcome + +```text +Hey {author}! Welcome to Squad πŸ‘‹ Thanks for opening this. +{substantive response} +Let us know if you have questions β€” happy to help! +``` + +### 2. Troubleshooting + +```text +Thanks for the detailed report, {author}! +Here's what we think is happening: {explanation} +{steps or workaround} +Let us know if that helps, or if you're seeing something different. +``` + +### 3. Feature guidance + +```text +Great question! {context on current state} +{guidance or workaround} +We've noted this as a potential improvement β€” {tracking info if applicable}. +``` + +### 4. Redirect + +```text +Thanks for reaching out! This one is actually better suited for {correct location}. +{brief explanation of why} +Feel free to open it there β€” they'll be able to help! +``` + +### 5. Acknowledgment + +```text +Good catch, {author}. We've confirmed this is a real issue. +{what we know so far} +We'll update this thread when we have a fix. Thanks for flagging it! +``` + +### 6. Closing + +```text +This should be resolved in {version/PR}! πŸŽ‰ +{brief summary of what changed} +Thanks for reporting this, {author} β€” it made Squad better. +``` + +### 7. Technical uncertainty + +```text +Interesting find, {author}. We're not 100% sure what's causing this yet. +Here's what we've ruled out: {list} +We'd love more context if you have it β€” {specific ask}. +We'll dig deeper and update this thread. +``` + +## Anti-Patterns + +- ❌ Corporate speak: "We appreciate your patience as we investigate this matter" +- ❌ Marketing hype: "Squad is the BEST way to..." or "This amazing feature..." +- ❌ Passive voice: "It has been determined that..." or "The issue is being tracked" +- ❌ Dismissive: "This works as designed" without empathy +- ❌ Over-promising: "We'll ship this next week" without commitment from the team +- ❌ Empty acknowledgment: "Thanks for your feedback" with no substance +- ❌ Robot signatures: "Best regards, PAO" or "Sincerely, The Squad Team" +- ❌ Excessive emoji: More than 1-2 emoji per response +- ❌ Quoting profanity: Even when the original issue contains it, paraphrase instead +- ❌ Link-dumping: Pasting URLs without context ("See: https://...") +- ❌ Open-ended info requests: "Can you provide more information?" without specifying what information diff --git a/docs/concepts/agent-on-disk.md b/docs/concepts/agent-on-disk.md new file mode 100644 index 000000000..e3a425c71 --- /dev/null +++ b/docs/concepts/agent-on-disk.md @@ -0,0 +1,394 @@ +# What It Means on Disk to Be a Squad Agent + +> Developer-oriented concept doc: the on-disk anatomy of a Squad agent + +## Overview + +A Squad agent is not a single file or code module. It's a **distributed identity** spanning three layers: + +1. **Runtime state** β€” `.squad/` directory (team-specific, git-committed) +2. **SDK infrastructure** β€” `packages/squad-sdk/src/agents/` (compiled code) +3. **Configuration** β€” `squad.config.ts` or `squad.config.json` (optional overrides) + +This doc explains how these layers work together to create an agent that can be spawned, collaborate, and accumulate knowledge over time. + +## Directory Structure + +Each agent exists in `.squad/agents/{name}/`: + +``` +.squad/ +└── agents/ + β”œβ”€β”€ flight/ + β”‚ β”œβ”€β”€ charter.md # Agent's identity, boundaries, voice + β”‚ └── history.md # Append-only learnings (optional) + β”œβ”€β”€ capcom/ + β”‚ └── charter.md + β”œβ”€β”€ scribe/ + β”‚ └── charter.md + └── _alumni/ + └── verbal/ # Retired agents live here + └── charter.md +``` + +### Key Files + +#### `charter.md` β€” The Agent's DNA + +**Who writes it:** The team (usually via a specialist like Procedures, or manually by the team owner). + +**Who reads it:** The SDK's charter compiler (`charter-compiler.ts`) at agent spawn time. + +**What it contains:** + +```markdown +# {Name} β€” {Role} + +> {One-line personality statement} + +## Identity +- **Name:** Flight +- **Role:** Lead +- **Expertise:** Product vision, architecture, code review +- **Style:** Decisive. Opinionated when it matters. + +## What I Own +- Product direction and architectural decisions +- Code review and quality gates + +## How I Work +- Architecture decisions compound +- Proposal-first: meaningful changes need docs/proposals/ before code + +## Boundaries +**I handle:** Architecture, product direction, code review, scope. +**I don't handle:** Implementation details, test writing, docs, distribution. + +## Model +Preferred: auto +``` + +**Parsed sections:** +- **Identity** β†’ `name`, `role`, `expertise`, `style` +- **What I Own** β†’ `ownership` (plain text) +- **Boundaries** β†’ `boundaries` (plain text) +- **Model** β†’ `modelPreference`, `modelRationale`, `modelFallback` + +The charter is compiled into a `SquadCustomAgentConfig` object that includes: +- The full charter content as the agent's system prompt +- Parsed metadata (name, role, model preference) +- Team context (from `team.md`, `routing.md`, `decisions.md`) + +**Format expectations:** +- Markdown headings (`## `) structure the charter +- The SDK parses specific sections by heading name +- Freeform content is preserved and passed to the LLM +- Personality and voice matter β€” agents have opinions + +#### `history.md` β€” Append-Only Learnings + +**Who writes it:** The agent itself, after completing work. + +**Who reads it:** The agent, before starting new work (via the charter compiler's history shadow feature). + +**What it contains:** + +```markdown +# Flight β€” Project History + +> Knowledge accumulated through leading Squad development. + +## Core Context + +Three-branch model (main/dev/insiders). Apollo 13 team, 3931 tests. +Boundary review heuristic: "Squad Ships It" β€” if Squad doesn't ship +the code, it's IRL content. + +## Learnings + +### Adoption Tracking Architecture +Three-tier opt-in system: Tier 1 (aggregate-only, `.github/adoption/`) +ships first; Tier 2 (opt-in registry) designed next; Tier 3 (public +showcase) launches when β‰₯5 projects opt in. + +### Remote Squad Access +Three-phase rollout: Phase 1 β€” GitHub Discussions bot with `/squad` +command (1 day, zero hosting). Phase 2 β€” GitHub Copilot Extension via +Contents API (1 week). Phase 3 β€” Slack/Teams bot (2 weeks). +``` + +**What goes in:** +- Context that persists across sessions (project patterns, established decisions) +- Learnings that inform future work (what worked, what didn't) +- Domain-specific knowledge accumulated over time + +**What doesn't go in:** +- Transient task state (use the session-scoped SQL database for that) +- Raw command output or logs (use `.squad/log/` for session logs) +- Decisions that affect other agents (those go in `.squad/decisions.md`) + +**Format:** +- Top-level `## Core Context` β€” stable facts +- Top-level `## Learnings` β€” append new `### ` blocks here +- No deletion β€” history is append-only + +### Alumni β€” The Retirement Pattern + +When an agent is no longer needed, it's moved to `.squad/agents/_alumni/{name}/`: + +``` +.squad/agents/_alumni/ +β”œβ”€β”€ verbal/ +β”‚ └── charter.md +β”œβ”€β”€ kobayashi/ +β”‚ └── charter.md +└── mcmanus/ + └── charter.md +``` + +**What happens on retirement:** +1. Agent directory moved from `.squad/agents/{name}/` to `.squad/agents/_alumni/{name}/` +2. Agent removed from `team.md` roster +3. Routing rules updated to remove agent from work assignments +4. Charter preserved for historical reference +5. Casting name returned to the pool (if using the casting system) + +Alumni agents cannot be spawned. Their charters are read-only archives. + +## The Casting System + +Squad uses a **thematic casting model** to assign memorable names from fictional universes. + +### Files + +#### `casting-registry.json` β€” Name Allocation + +```json +{ + "agents": { + "flight": { + "universe": "Apollo 13", + "character": "Flight Director", + "assigned": "2026-02-21T10:00:00Z" + } + } +} +``` + +**Purpose:** Tracks which names are in use, which universe they're from, and when they were assigned. + +**Who manages it:** The casting module (`packages/squad-sdk/src/casting/`). + +**Lifecycle:** +- Name allocated when agent created β†’ entry added +- Agent retired β†’ entry remains (name not reused within same universe) +- Universe exhausted β†’ new universe added to `casting-policy.json` + +#### `casting-policy.json` β€” Universe Rules + +```json +{ + "casting_policy_version": "1.1", + "allowlist_universes": [ + "The Usual Suspects", + "Reservoir Dogs", + "Alien", + "Ocean's Eleven" + ], + "universe_capacity": { + "The Usual Suspects": 6, + "Reservoir Dogs": 8, + "Alien": 8, + "Ocean's Eleven": 14 + } +} +``` + +**Purpose:** Defines which fictional universes are available and how many names each can provide. + +**Who manages it:** The team owner (manually edited when adding new universes). + +**Rules:** +- Each universe has a capacity limit (prevents name dilution) +- Names must be recognizable characters from that universe +- No universe mixing on the same team (maintains thematic coherence) + +#### `casting-history.json` β€” Audit Log + +```json +{ + "universe_usage_history": [ + { + "timestamp": "2026-02-21T10:00:00Z", + "universe": "Apollo 13", + "agent": "flight", + "character": "Flight Director", + "action": "assigned" + } + ], + "assignment_cast_snapshots": {} +} +``` + +**Purpose:** Immutable audit trail of all casting decisions. + +**Who writes it:** The casting module (append-only). + +**Why it matters:** Enables rollback, debugging, and understanding team evolution over time. + +## How an Agent "Exists" + +An agent is **active** when all three conditions are met: + +1. **Charter exists** β€” `.squad/agents/{name}/charter.md` is present +2. **Roster entry** β€” Agent listed in `team.md` with status `βœ… Active` or `πŸ“‹ Silent` +3. **Routing rules** β€” Agent appears in `routing.md` work assignments + +Without all three, the agent cannot be spawned. + +**Spawn flow:** + +``` +User request + ↓ +Coordinator reads routing.md + ↓ +Identifies agent to spawn (e.g., "flight") + ↓ +SDK reads .squad/agents/flight/charter.md + ↓ +SDK reads .squad/agents/flight/history.md (if exists) + ↓ +SDK reads .squad/team.md, routing.md, decisions.md + ↓ +Charter compiler builds SquadCustomAgentConfig + ↓ +SDK spawns agent with compiled prompt + ↓ +Agent runs, writes to history.md after work +``` + +## Relationship to SDK Source Files + +The `.squad/` directory is **runtime state**, not code. The SDK provides the **infrastructure** to load, parse, and execute agents: + +| SDK Module | Purpose | +|------------|---------| +| `packages/squad-sdk/src/agents/charter-compiler.ts` | Parses `charter.md` into `SquadCustomAgentConfig` | +| `packages/squad-sdk/src/agents/history-shadow.ts` | Loads `history.md` and injects into agent context | +| `packages/squad-sdk/src/agents/lifecycle.ts` | Agent spawn, session management, termination | +| `packages/squad-sdk/src/agents/model-selector.ts` | Resolves `## Model` preference to actual model | +| `packages/squad-sdk/src/casting/` | Name allocation, registry management | + +**Key insight:** The SDK never hardcodes agent names or roles. It's a generic **agent runtime**. All specificity lives in `.squad/`. + +This means: +- You can add new agents without changing SDK code +- Multiple projects using the same SDK have different teams +- Agents can be dynamically added, retired, or renamed + +## What About `squad.config.ts`? + +The optional `squad.config.ts` file provides **overrides** for charter-based agents: + +```typescript +export default { + agents: { + flight: { + model: 'gpt-4.1', // Override charter's "Preferred: auto" + tools: ['read', 'write'], // Restrict tool access + extraPrompt: 'Focus on performance trade-offs.' // Append to charter + } + } +} +``` + +**Merge order (config wins on conflict):** +1. Charter parsed β†’ base `SquadCustomAgentConfig` +2. Config overrides applied β†’ merged `SquadCustomAgentConfig` +3. Team context injected β†’ final prompt sent to LLM + +This allows: +- Per-environment tuning (staging vs production) +- Temporary restrictions (disable tools during testing) +- A/B testing different prompts without editing charters + +## Cross-Agent Context Propagation + +Agents don't share memory. Context flows via **explicit artifacts**: + +### `team.md` β€” Shared Roster +All agents read this to know who else exists and what they do. + +### `routing.md` β€” Work Assignment Rules +Defines which agent handles which type of work. Coordinator uses this to route requests. + +### `decisions.md` β€” Canonical Decisions Log +All agents read this before starting work. It's the shared memory. + +### `.squad/decisions/inbox/` β€” Decision Drop-Box +Agents write decisions here. Scribe merges them into `decisions.md`. + +**Flow:** + +``` +Flight makes a decision + ↓ +Flight writes .squad/decisions/inbox/flight-api-versioning.md + ↓ +Scribe (background agent) runs + ↓ +Scribe reads inbox, appends to decisions.md, deletes inbox file + ↓ +CAPCOM starts work, reads decisions.md + ↓ +CAPCOM sees Flight's decision, respects it +``` + +### `.squad/log/` β€” Session Logs +Scribe writes session summaries here. Useful for auditing and debugging. + +**Example log file:** + +``` +.squad/log/2026-03-16T10-00-00-feature-adoption-tracking.md +``` + +Contains: +- Who worked +- What was done +- Decisions made +- Key outcomes + +## Key Takeaways + +1. **An agent is a directory** β€” `.squad/agents/{name}/` with at least `charter.md`. +2. **Charter is the source of truth** β€” defines identity, boundaries, voice. +3. **History is optional** β€” but recommended for agents doing repeated work. +4. **Casting adds personality** β€” thematic names make agents memorable. +5. **SDK is generic infrastructure** β€” no agent-specific code in the runtime. +6. **Context flows via files** β€” `team.md`, `routing.md`, `decisions.md`, `.squad/log/`. +7. **Retirement is move + remove** β€” alumni live in `_alumni/`, can't be spawned. + +## Developer Checklist: Creating a New Agent + +- [ ] Create `.squad/agents/{name}/` directory +- [ ] Write `charter.md` using `.squad/templates/charter.md` as reference +- [ ] Add agent to `team.md` roster with status `βœ… Active` +- [ ] Add agent to `routing.md` with work type assignments +- [ ] (Optional) Allocate name via casting system +- [ ] (Optional) Create `history.md` if agent needs persistent memory +- [ ] Test spawn: `squad spawn {name} "Hello, world"` + +## Further Reading + +- **Charter format reference:** `.squad/templates/charter.md` +- **Roster format reference:** `.squad/templates/roster.md` +- **SDK agent infrastructure:** `packages/squad-sdk/src/agents/` +- **Casting system design:** `packages/squad-sdk/src/casting/` + +--- + +**Author:** Flight +**Requested by:** Dina (via Brady) +**Date:** 2026-03-16