Skip to content

Commit 1f76c1a

Browse files
committed
chore: integrate Teams notifications with squad workflow
Merge decisions inbox into team memory and add Teams notification support for milestone updates (work batches, PRs, issues, decisions). Changes: - Merged 6 decision files from inbox/ into .squad/decisions.md - Added teams-notify.sh script for Microsoft Graph API integration - Added teams-test.sh verification companion - Updated Scribe charter with Teams notification protocols - Updated team.md with Integrations section - Updated agent histories (Linus, Livingston) - Added teams-config.json for channel configuration Teams notifications now enabled via .squad/scripts/teams-notify.sh with event filtering, HTML escaping, and graceful error handling (never breaks CI/CD). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent d3e8714 commit 1f76c1a

12 files changed

Lines changed: 866 additions & 0 deletions

File tree

.squad/agents/linus/history.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ All code roles now use `claude-opus-4.6`. Docs/Scribe/diversity use `gemini-3-pr
9393
- **What:** Added `waza suggest <skill-path>` for LLM-driven eval generation. Command supports `--model`, `--dry-run` (default), `--apply`, `--output-dir`, and `--format yaml|json`. New `internal/suggest` package builds prompt context from SKILL.md + grader types + eval schema summary + example eval, parses structured YAML responses, validates generated `eval_yaml`, and writes `eval.yaml`/task/fixture files when applying.
9494
- **Key learning:** A robust parser needs to handle both structured wrapper YAML (`eval_yaml` + files) and fenced YAML blocks from models. Validating generated `eval_yaml` against `models.BenchmarkSpec.Validate()` catches malformed model output early before writing files.
9595

96+
### Teams Notification Scripts
97+
- **Date:** 2026-03-12
98+
- **Files:** `.squad/scripts/teams-notify.sh`, `.squad/scripts/teams-test.sh`
99+
- **What:** Created Teams notification script using `az rest` + Microsoft Graph API. Reads config from `.squad/identity/teams-config.json`. Supports 5 event types with per-event enable/disable. HTML-formatted messages with emoji headers. Graceful error handling (never exits non-zero). jq preferred, grep/sed fallback. Companion test script for verification.
100+
- **Key learning:** `az rest` handles auth token injection automatically when hitting `graph.microsoft.com` — no manual token management needed. Using `jq -n --arg` for JSON body construction is essential to handle HTML content with special chars safely.
101+
96102
## Learnings
97103
- Windows local test runs can fail in `cmd/waza/tokens/internal/git` when temporary repos inherit strict CRLF behavior; setting `core.autocrlf=false` and `core.safecrlf=false` inside test repo setup makes these tests cross-platform stable.
98104
- PR conflict resolution for `copilot/migrate-copilot-client-usage` in `internal/execution/copilot_test.go` should keep the `TestCopilotExecute_InitializePropagatesStartError` variant from main to preserve startup error propagation coverage.
105+
- Teams Graph API channel messages POST to `/v1.0/teams/{groupId}/channels/{channelId}/messages` with body `{body:{contentType:"html",content:"..."}}`. `az rest` auto-injects bearer tokens for graph.microsoft.com endpoints.
106+
- Squad notification scripts live in `.squad/scripts/` and config in `.squad/identity/teams-config.json`. The notify script always exits 0 to be safe for caller pipelines.

.squad/agents/livingston/history.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,40 @@ All code roles now use `claude-opus-4.6`. Docs/Scribe/diversity use `gemini-3-pr
8888
**Site build verified:** All 14 pages built successfully, ci-cd page included
8989

9090
**Branch:** squad/89-ci-integration-guide → PR to microsoft/waza main
91+
92+
## 📌 Skill Documentation: Teams Notifications (2026-03-12)
93+
94+
**Created:** `.squad/skills/teams-notify/SKILL.md`
95+
96+
**What the skill documents:**
97+
The Teams notification system that the squad uses to communicate milestones to the "Waza Squad" Teams channel. Uses Microsoft Graph API via `az rest` (Azure CLI) — no Power Automate, no webhooks, no app registration.
98+
99+
**Key components documented:**
100+
1. **Architecture** — Azure CLI (`az rest`) posts to Graph API, Scribe-driven
101+
2. **Configuration** — teams-config.json with group ID, channel ID, per-event toggles
102+
3. **Event types** — work_complete, pr_opened, pr_merged, issue_closed, decisions, ralph_status
103+
4. **Usage** — Manual notifications via `.squad/scripts/teams-notify.sh <event_type> "<message>"`
104+
5. **Troubleshooting** — Login issues, 403 permissions, channel ID extraction, script not found
105+
6. **Graceful degradation** — Full functionality without Teams configured, no impact on dev workflow
106+
7. **Configuration checklist** — Prerequisites and test procedure
107+
108+
**Key design patterns established:**
109+
- Master `enabled` toggle gates all notifications
110+
- Per-event toggles allow selective notification (e.g., decisions=true, ralph_status=false)
111+
- Script pattern: read config → check enabled and event type → format → post → exit silently on disable
112+
- Teams channel ID extracted from Teams UI (right-click → copy link) or Azure CLI
113+
- No retry logic — fire-and-forget HTTP POST to Graph API
114+
115+
**File paths:**
116+
- Skill document: `.squad/skills/teams-notify/SKILL.md`
117+
- Configuration: `.squad/identity/teams-config.json`
118+
- Script location (for user reference): `.squad/scripts/teams-notify.sh` (not yet created; documented as expected location)
119+
- Graph API endpoint: `/me/teamwork/sendActivityNotification` (documented in See Also)
120+
121+
**Clarity improvements over requirements:**
122+
- Added mermaid-like flow diagram to show architecture
123+
- Included step-by-step channel ID extraction procedure (Teams UI + CLI)
124+
- Provided schema table with field descriptions
125+
- Added troubleshooting decision tree with specific `az` commands to test
126+
- Clarified graceful degradation (no errors, no noise when disabled)
127+
- Included configuration checklist with pre-flight items

.squad/agents/scribe/charter.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,25 @@ Never start work unprompted. Scribe is always spawned after substantial work by
4747

4848
Always run in `mode: "background"` — non-blocking, async logging.
4949

50+
## Teams Notifications
51+
52+
After completing logging and decision merging tasks, check if Teams notifications are enabled:
53+
54+
1. Read `.squad/identity/teams-config.json`
55+
2. If `enabled` is `true`, call `.squad/scripts/teams-notify.sh` with the appropriate event type and a brief summary
56+
3. Event type mapping:
57+
- After a work batch → `work_complete` with agent names and what they did
58+
- After PR creation → `pr_opened` with PR number, title, and branch
59+
- After PR merge → `pr_merged` with PR number and title
60+
- After issue close → `issue_closed` with issue number and title
61+
- After decision merge → `decisions` with the decision summary
62+
4. If the script fails or Teams is not configured, continue normally — notifications never block logging
63+
64+
The script handles all formatting and auth. Scribe just calls it with the event type and message string:
65+
```bash
66+
.squad/scripts/teams-notify.sh work_complete "🔧 Linus refactored auth module. 🧪 Basher added 12 test cases."
67+
```
68+
5069
## Voice
5170

5271
Quiet. Observant. The institutional memory of the team. Doesn't have opinions, just facts. Makes sure decisions don't get lost.

.squad/decisions.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,129 @@ All issues routed to qualified squad members:
399399
| #89 | CI/CD integration guide (P1) | squad:livingston + squad:saul | Documentation with doc-review gate |
400400

401401
**Why:** Batch review + triage ensures all green PRs merge cleanly and new work is routed to the right specialist without manual coordination. Parallel work begins immediately once triage is complete.
402+
403+
## 2026-03-10: PR Feedback Pass 2 — Design Decision Rationale
404+
405+
**By:** Linus (Backend Developer)
406+
**Date:** 2026-03-10
407+
408+
**What:** Resolved all 49 unresolved review threads across PRs #79#96. Key design decisions documented:
409+
410+
1. **Trigger grader empty prompt handling** (PR #90): Empty prompts now fail immediately. Previously score=0 in negative mode would pass (0 < threshold), a false positive.
411+
412+
2. **Snapshot path resolution** (PR #95): `resolvePathWithSymlinks` now recursively walks up the path tree, enabling snapshot writes to non-existent intermediate directories. This was blocking the parent-dir-creation use case.
413+
414+
3. **Coverage threshold** (PR #92): ≥2 grader types for "Full" coverage is intentional — a single grader validates one dimension; multi-angle coverage requires multiple grader types. Documented in code.
415+
416+
4. **Base ref fallback chain** (PR #93): Changed from origin/main → main to origin/main → main → HEAD per chlowell's review. Enables diff command in repos without remotes.
417+
418+
**Why:** Clearing the review feedback backlog to unblock merge queue. All human reviewer feedback (wbreza, chlowell) addressed with code or rationale. Copilot automated comments assessed individually — genuine bugs fixed, design choices documented and resolved.
419+
420+
**Impact:** All 8 authored PRs now have 0 unresolved threads and are ready for merge.
421+
422+
## 2026-03-10: Fork PR Branch Fix Protocol
423+
424+
**By:** Linus (Backend Developer)
425+
**Date:** 2026-03-10
426+
427+
**What:** When squad feedback sweep commits land on the wrong remote (origin/microsoft instead of fork/spboyer), the fix protocol is:
428+
429+
1. Fetch both remotes
430+
2. Compare `origin/<branch>` vs `fork/<branch>` — identify unique origin commits by deduplicating on commit message
431+
3. Create detached worktrees from fork branch tips
432+
4. Cherry-pick only unique, architecturally-compatible commits (skip commits targeting superseded code)
433+
5. Push to fork remote
434+
6. Verify PR head SHA advanced on GitHub
435+
436+
**Key rule for #93 (tokens diff):** When a fork branch was independently reworked (diff→compare consolidation), do NOT cherry-pick old fix commits that target removed code. Only cherry-pick architecture-neutral commits (docs, CHANGELOG).
437+
438+
**Why:** Fork-backed PRs only advance when the fork branch moves. Pushing to origin branches (same name) has no effect on the PR. This protocol avoids introducing conflicts from stale commits while ensuring all review feedback reaches the actual PR.
439+
440+
**Impact:** All future feedback sweeps must verify they're pushing to the correct remote (`fork` for fork-backed PRs, `origin` for origin-backed PRs) before pushing. Check `gh pr view <N> --json headRepository` to confirm.
441+
442+
## 2026-03-10: hasConfiguredTokenLimits: non-nil pointer = authoritative
443+
444+
**By:** Linus (Backend Developer)
445+
**PR:** #96
446+
**Date:** 2026-03-10
447+
448+
**What:** `hasConfiguredTokenLimits` now returns `true` for any non-nil `*TokenLimitsConfig` pointer, not just when Defaults or Overrides maps are populated. This means `tokens.limits: {}` in `.waza.yaml` is treated as authoritative and suppresses the deprecated `.token-limits.json` fallback.
449+
450+
**Why:** A non-nil pointer from YAML unmarshaling means the user explicitly declared the section. Requiring populated child maps created a semantic gap where `limits: {}` silently fell back to legacy JSON — surprising behavior during migration.
451+
452+
**Impact:** Users migrating from `.token-limits.json` to `.waza.yaml` can now safely write an empty `tokens.limits:` section to disable the legacy fallback before populating their limits.
453+
454+
## 2026-03-12: Teams Notification Script Design
455+
456+
**By:** Linus (Backend Developer)
457+
**Date:** 2026-03-12
458+
459+
### Context
460+
461+
Created `.squad/scripts/teams-notify.sh` for sending squad notifications to the Waza Squad Teams channel via Microsoft Graph API.
462+
463+
### Decisions
464+
465+
1. **Always exit 0** — The notification script never returns a non-zero exit code. If az isn't installed, not logged in, config is missing, or the API call fails, it logs a warning to stderr and exits cleanly. This prevents notification failures from breaking CI/CD pipelines or squad automation.
466+
467+
2. **jq with grep/sed fallback** — Uses jq for JSON parsing when available, falls back to grep/sed for environments without jq. The jq path is preferred because it properly handles JSON escaping in the request body.
468+
469+
3. **HTML content escaping** — Message content is escaped (`&`, `<`, `>`, `"`) before embedding in HTML to prevent injection in Teams messages.
470+
471+
4. **Config-driven event filtering** — Each event type can be independently enabled/disabled in `teams-config.json` via the `notify_on` object. The script checks this before making any API call.
472+
473+
5. **TEAM_ROOT resolution** — Script auto-detects the team root by walking up from its own location (`../../` from `.squad/scripts/`). Can be overridden via `TEAM_ROOT` env var.
474+
475+
### Files
476+
477+
- `.squad/scripts/teams-notify.sh` — Main notification script
478+
- `.squad/scripts/teams-test.sh` — Test/verification companion
479+
- `.squad/identity/teams-config.json` — Channel config (pre-existing)
480+
481+
482+
## 2026-03-12: Microsoft Teams Notifications via Graph API
483+
484+
**By:** Coordinator (in consultation with Linus and Shayne Boyer)
485+
**Date:** 2026-03-12T13:45Z
486+
**Related:** User directive (2026-03-12)
487+
488+
**What:** Implemented Teams notifications for squad milestone updates via Microsoft Graph API. System sends notifications to "Waza Squad" Teams channel on work batches, PR lifecycle, issue closure, and decision merges.
489+
490+
**Components:**
491+
- **Script:** `.squad/scripts/teams-notify.sh` — Main notification sender
492+
- **Test:** `.squad/scripts/teams-test.sh` — Verification tool
493+
- **Config:** `.squad/identity/teams-config.json` — Channel config (pre-existing)
494+
- **Skill:** `.squad/skills/teams-notify/SKILL.md` — Usage documentation
495+
496+
**Design Decisions:**
497+
498+
1. **Always exit 0** — Notification failures never block automation. Graceful degradation: if az isn't installed, not logged in, config missing, or API fails, the script logs a warning to stderr and exits cleanly.
499+
500+
2. **jq with grep/sed fallback** — JSON parsing prefers jq (proper HTML/JSON escaping) but falls back to grep/sed for minimal environments without jq installed.
501+
502+
3. **HTML content escaping** — Message content escaped for `&`, `<`, `>`, `"` before embedding in Teams HTML to prevent injection vulnerabilities.
503+
504+
4. **Config-driven event filtering** — Each event type (`work_complete`, `pr_opened`, `pr_merged`, `issue_closed`, `decisions`) independently controllable via `notify_on` object in teams-config.json. Allows disabling noisy events while keeping critical ones.
505+
506+
5. **TEAM_ROOT auto-detection** — Script walks up from its location (`../../` from `.squad/scripts/`) to find repo root. Can be overridden via `TEAM_ROOT` environment variable for CI/CD flexibility.
507+
508+
**Event Types:**
509+
- `work_complete` — Agent work batch summaries (names + what they did)
510+
- `pr_opened` — New PR (number, title, branch)
511+
- `pr_merged` — Merged PR (number, title)
512+
- `issue_closed` — Closed issue (number, title)
513+
- `decisions` — Decision merges (summary)
514+
515+
**Integration:**
516+
- Scribe calls notification system after completing logging tasks
517+
- All agents can manually trigger notifications for their work
518+
- Coordinator uses for orchestration milestones
519+
- Failures never block automation — entirely optional enhancement
520+
521+
**Testing:**
522+
- `.squad/scripts/teams-test.sh` verified notification delivery to Teams
523+
- Message successfully appeared in "Waza Squad" channel
524+
- No blocking errors observed
525+
526+
**Why:**
527+
User request (Shayne Boyer) to send squad milestone updates to Teams channel. System enables real-time team awareness of work completion, PRs, and decisions without requiring polling or manual updates. Designed to never interfere with CI/CD or squad automation — a pure enhancement to team communication.

.squad/identity/teams-config.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"enabled": true,
3+
"group_id": "450e4e32-11f8-4436-a9b4-4990ae16fe58",
4+
"channel_id": "19:288df9bbfec84a1da3aec636c7b829a5@thread.tacv2",
5+
"channel_name": "Waza Squad",
6+
"notify_on": {
7+
"work_complete": true,
8+
"pr_opened": true,
9+
"pr_merged": true,
10+
"issue_closed": true,
11+
"decisions": true,
12+
"ralph_status": false
13+
}
14+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Session Log: Teams Integration Sprint
2+
**Date:** 2026-03-12T13:45:00Z
3+
4+
## Work Batch
5+
6+
**Participants:** Linus (Backend), Livingston (Documentation), Coordinator
7+
8+
## What Shipped
9+
10+
- **Notification System**`.squad/scripts/teams-notify.sh` for Teams milestone updates via Microsoft Graph API
11+
- **Test Suite**`.squad/scripts/teams-test.sh` verified notification delivery
12+
- **Skill Documentation**`.squad/skills/teams-notify/SKILL.md` with comprehensive usage guide
13+
- **Configuration**`.squad/identity/teams-config.json` with event filtering controls
14+
- **Decision Records** — Merged inbox decisions into team memory
15+
16+
## Event Types
17+
18+
- `work_complete` — Agent work batch summaries
19+
- `pr_opened` / `pr_merged` — Pull request lifecycle
20+
- `issue_closed` — Issue closure
21+
- `decisions` — Decision merges
22+
23+
## Key Design
24+
25+
All notifications exit 0 — failures never block automation. JSON parsing falls back gracefully. HTML content properly escaped. Event types independently configurable.
26+
27+
## Verification
28+
29+
Test notification successfully delivered to "Waza Squad" Teams channel.
30+
31+
## Team Notes
32+
33+
System ready for use. Scribe can now call notifications for future work batches. All documentation current.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Orchestration: Linus — Teams Notification System
2+
**Date:** 2026-03-12T13:45:00Z
3+
**Agent:** Linus (Backend Developer)
4+
**Mode:** background
5+
**Outcome:** ✅ success
6+
7+
## Work Summary
8+
9+
Created the Teams notification system for squad milestone updates via Microsoft Graph API.
10+
11+
## Artifacts
12+
13+
### Code
14+
- **`.squad/scripts/teams-notify.sh`** — Main notification script
15+
- Sends messages to Teams channel via Microsoft Graph API (`az rest`)
16+
- Supports multiple event types: `work_complete`, `pr_opened`, `pr_merged`, `issue_closed`, `decisions`
17+
- Event filtering driven by `.squad/identity/teams-config.json`
18+
- Always exits 0 — notification failures never block automation
19+
- Robust: Falls back from jq to grep/sed for JSON parsing
20+
- HTML content escaping for security
21+
22+
- **`.squad/scripts/teams-test.sh`** — Test/verification companion
23+
- Standalone test of notification delivery to Teams
24+
- Verified notification appeared in Waza Squad channel
25+
26+
## Design Decisions
27+
28+
1. **Always exit 0** — Notification script handles all errors gracefully. If az isn't installed, not logged in, config missing, or API fails, it logs warning and exits cleanly.
29+
30+
2. **jq with grep/sed fallback** — JSON parsing prefers jq (proper escaping) but falls back to grep/sed for minimal environments.
31+
32+
3. **HTML content escaping** — Message content escaped (`&`, `<`, `>`, `"`) before embedding in Teams HTML.
33+
34+
4. **Config-driven event filtering** — Each event type independently controlled via `notify_on` object in teams-config.json.
35+
36+
5. **TEAM_ROOT auto-detection** — Script walks up from location to find repo root. Can be overridden via env var.
37+
38+
## Verification
39+
40+
- Test notification sent via `teams-test.sh`
41+
- Message successfully delivered to "Waza Squad" Teams channel
42+
- No blocking errors observed
43+
44+
## Next Steps
45+
46+
- Scribe will merge decisions and call notifications after logging
47+
- Livingston to document skill
48+
- Coordinator to verify integration completeness
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Orchestration: Livingston — Teams Notification Skill
2+
**Date:** 2026-03-12T13:45:00Z
3+
**Agent:** Livingston (Documentation Specialist)
4+
**Mode:** background
5+
**Outcome:** ✅ success
6+
7+
## Work Summary
8+
9+
Created comprehensive skill documentation for the Teams notification system.
10+
11+
## Artifacts
12+
13+
### Documentation
14+
- **`.squad/skills/teams-notify/SKILL.md`** — Full Teams notification skill
15+
- Explains purpose and usage of notification system
16+
- Documents all event types and when to trigger them
17+
- Shows example calls and expected Teams message format
18+
- References configuration at `.squad/identity/teams-config.json`
19+
- Provides troubleshooting section for common issues
20+
- Includes script exit codes and error handling notes
21+
22+
## Key Sections
23+
24+
1. **Overview** — Teams notifications via Graph API for squad milestones
25+
2. **Event Types** — work_complete, pr_opened, pr_merged, issue_closed, decisions
26+
3. **Usage** — How and when to call `.squad/scripts/teams-notify.sh`
27+
4. **Configuration** — teams-config.json format and event filtering
28+
5. **Examples** — Real example calls and message formatting
29+
6. **Troubleshooting** — Common issues and solutions
30+
31+
## Integration Points
32+
33+
- Scribe calls this after logging other team work
34+
- Coordinator invokes during setup or manual milestone recording
35+
- All agents can trigger notifications for their work
36+
37+
## Next Steps
38+
39+
- Scribe will merge decisions and use this skill for notification
40+
- Integration complete once Coordinator verifies

0 commit comments

Comments
 (0)