Compare commits

...

4 Commits

Author SHA1 Message Date
a356c4929a P2 #518: Add cross-agent quality audit scorecard for timmy-home
Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 23s
Smoke Test / smoke (pull_request) Failing after 21s
Validate Config / YAML Lint (pull_request) Failing after 21s
Validate Config / JSON Validate (pull_request) Successful in 20s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 1m1s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 53s
Validate Config / Cron Syntax Check (pull_request) Successful in 11s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 11s
Validate Config / Playbook Schema Validation (pull_request) Successful in 31s
PR Checklist / pr-checklist (pull_request) Failing after 4m27s
Architecture Lint / Lint Repository (pull_request) Failing after 24s
Audit of 30 PRs across 10 agent identities in timmy-home (PRs #945–#980).
Findings: 0.0% merge rate — bottleneck is human review queue depth, not agent quality.

- Agents producing valid PRs: ROCKACHOPA (18), BEZALEL (2), TIMMY (2), plus 7 single-PR specialists
- Implements: timmy-home#518 — Scorecard filed in timmy-config as requested

No agent bans recommended; dupe-collision detection (#971 vs #972) and gate staffing up recommended.
2026-04-30 06:47:52 +00:00
Rockachopa
54093991ab STEP35-476 patch: use scripts/ path for dispatch_router
Some checks failed
Architecture Lint / Linter Tests (push) Successful in 17s
Smoke Test / smoke (push) Failing after 12s
Validate Config / YAML Lint (push) Failing after 10s
Validate Config / JSON Validate (push) Successful in 16s
Validate Config / Python Syntax & Import Check (push) Failing after 37s
Validate Config / Python Test Suite (push) Has been skipped
Validate Config / Cron Syntax Check (push) Successful in 15s
Validate Config / Shell Script Lint (push) Failing after 46s
Validate Config / Deploy Script Dry Run (push) Successful in 10s
Validate Config / Playbook Schema Validation (push) Successful in 16s
Architecture Lint / Lint Repository (push) Failing after 13s
- dispatch_router.py resides in scripts/ (existing dir)
- Updated orchestrator to call ../scripts/dispatch_router.py
2026-04-30 06:41:38 +00:00
Rockachopa
1ea6bf6e33 STEP35-476: Integrate dispatch_router into orchestrator triage loop
Some checks failed
Architecture Lint / Linter Tests (push) Successful in 31s
Smoke Test / smoke (push) Failing after 24s
Validate Config / YAML Lint (push) Failing after 17s
Validate Config / JSON Validate (push) Successful in 18s
Validate Config / Python Syntax & Import Check (push) Failing after 57s
Validate Config / Python Test Suite (push) Has been skipped
Validate Config / Shell Script Lint (push) Failing after 1m0s
Validate Config / Cron Syntax Check (push) Successful in 11s
Validate Config / Deploy Script Dry Run (push) Successful in 14s
Validate Config / Playbook Schema Validation (push) Successful in 25s
Architecture Lint / Lint Repository (push) Failing after 23s
- Added dispatch_router.py call for agent assignment routing
- Added dispatch decision logging to $LOG_DIR/dispatch_decisions.log
- Fall back to 'claude' if router fails
- Logs agent, score, category, reason per dispatch
2026-04-30 06:32:30 +00:00
Rockachopa
874ce137b0 feat(backup): add automated Gitea daily backup and recovery runbook
Some checks failed
Architecture Lint / Linter Tests (push) Successful in 30s
Smoke Test / smoke (push) Failing after 24s
Validate Config / YAML Lint (push) Failing after 16s
Validate Config / JSON Validate (push) Successful in 21s
Validate Config / Cron Syntax Check (push) Successful in 15s
Validate Config / Deploy Script Dry Run (push) Successful in 14s
Validate Config / Python Syntax & Import Check (push) Failing after 1m2s
Validate Config / Python Test Suite (push) Has been skipped
Validate Config / Shell Script Lint (push) Failing after 1m3s
Validate Config / Playbook Schema Validation (push) Successful in 24s
Architecture Lint / Linter Tests (pull_request) Successful in 27s
Smoke Test / smoke (pull_request) Failing after 22s
Validate Config / YAML Lint (pull_request) Failing after 16s
Validate Config / JSON Validate (pull_request) Successful in 23s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 1m5s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Cron Syntax Check (pull_request) Successful in 12s
Validate Config / Shell Script Lint (pull_request) Failing after 1m6s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 13s
Validate Config / Playbook Schema Validation (pull_request) Successful in 25s
PR Checklist / pr-checklist (pull_request) Failing after 4m33s
Architecture Lint / Lint Repository (push) Failing after 26s
Architecture Lint / Lint Repository (pull_request) Failing after 26s
- Add bin/gitea-backup.sh: daily backup script using gitea dump
- Add cron/vps/gitea-daily-backup.yml: Hermes cron job (2 AM daily)
- Add docs/backup-recovery-runbook.md: complete recovery procedures

Addresses [AUDIT][RISK] Single-node VPS is a single point of failure.
Closes #481
2026-04-30 01:44:05 -04:00
5 changed files with 421 additions and 14 deletions

87
bin/gitea-backup.sh Normal file
View File

@@ -0,0 +1,87 @@
#!/bin/bash
# Gitea Daily Backup Script
# Uses Gitea's native dump command to create automated backups of repositories and SQLite databases.
# Designed to run on the VPS (Ezra) as part of a daily cron job.
#
# Configuration via environment variables:
# GITEA_BIN Path to gitea binary (default: auto-detect)
# GITEA_BACKUP_DIR Directory for backup archives (default: /var/backups/gitea)
# GITEA_BACKUP_RETENTION Days to retain backups (default: 7)
# GITEA_BACKUP_LOG Log file path (default: /var/log/gitea-backup.log)
set -euo pipefail
GITEA_BIN="${GITEA_BIN:-$(command -v gitea 2>/dev/null || echo "/usr/local/bin/gitea")}"
BACKUP_DIR="${GITEA_BACKUP_DIR:-/var/backups/gitea}"
RETENTION_DAYS="${GITEA_BACKUP_RETENTION:-7}"
DATE="$(date +%Y-%m-%d_%H%M%S)"
BACKUP_FILE="${BACKUP_DIR}/gitea-backup-${DATE}.tar.gz"
LOG_FILE="${GITEA_BACKUP_LOG:-/var/log/gitea-backup.log}"
mkdir -p "${BACKUP_DIR}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "${LOG_FILE}"
}
log "=== Starting Gitea daily backup ==="
# Verify gitea binary exists
if [ ! -x "${GITEA_BIN}" ]; then
log "ERROR: Gitea binary not found at ${GITEA_BIN}"
log "Set GITEA_BIN environment variable to the gitea binary path (e.g., /usr/bin/gitea)"
exit 1
fi
# Detect Gitea WORK_PATH
WORK_PATH=""
APP_INI=""
for path in /etc/gitea/app.ini /home/git/gitea/custom/conf/app.ini ~/gitea/custom/conf/app.ini; do
if [ -f "$path" ]; then
APP_INI="$path"
break
fi
done
if [ -n "$APP_INI" ]; then
# Parse [app] WORK_PATH = /var/lib/gitea
WORK_PATH=$(sed -n 's/^[[:space:]]*WORK_PATH[[:space:]]*=[[:space:]]*//p' "$APP_INI" | head -1)
log "Detected WORK_PATH from app.ini: ${WORK_PATH}"
fi
# Fallback detection
if [ -z "$WORK_PATH" ]; then
for d in /var/lib/gitea /home/git/gitea /srv/gitea /opt/gitea; do
if [ -d "$d" ]; then
WORK_PATH="$d"
break
fi
done
log "Inferred WORK_PATH: ${WORK_PATH:-not found}"
fi
if [ -z "$WORK_PATH" ]; then
log "ERROR: Could not determine Gitea WORK_PATH. Set GITEA_WORK_PATH manually."
exit 1
fi
# Perform gitea dump
# Flags: --work-path sets the Gitea working directory, --file writes dump to tar.gz
log "Running: gitea dump --work-path ${WORK_PATH} --file ${BACKUP_FILE}"
"${GITEA_BIN}" dump --work-path "${WORK_PATH}" --file "${BACKUP_FILE}" 2>>"${LOG_FILE}"
if [ $? -ne 0 ]; then
log "ERROR: gitea dump failed — check ${LOG_FILE} for details"
exit 1
fi
FILE_SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
log "Backup created: ${BACKUP_FILE} (${FILE_SIZE})"
# Prune old backups (keep last N days)
find "${BACKUP_DIR}" -name "gitea-backup-*.tar.gz" -type f -mtime +$((${RETENTION_DAYS}-1)) -delete 2>/dev/null || true
log "Pruned backups older than ${RETENTION_DAYS} days"
log "=== Backup completed successfully ==="
exit 0

View File

@@ -129,20 +129,42 @@ Preserved by timmy-orchestrator to prevent loss." 2>/dev/null && git p
# Auto-assignment is opt-in because silent queue mutation resurrects old state. # Auto-assignment is opt-in because silent queue mutation resurrects old state.
if [ "$unassigned_count" -gt 0 ]; then if [ "$unassigned_count" -gt 0 ]; then
if [ "$AUTO_ASSIGN_UNASSIGNED" = "1" ]; then if [ "$AUTO_ASSIGN_UNASSIGNED" = "1" ]; then
log "Assigning $unassigned_count issues to claude..." log "Assigning $unassigned_count issues via dispatch router..."
while IFS= read -r line; do DISPATCH_LOG="$LOG_DIR/dispatch_decisions.log"
local repo=$(echo "$line" | sed 's/.*REPO=\([^ ]*\).*/\1/') while IFS= read -r line; do
local num=$(echo "$line" | sed 's/.*NUM=\([^ ]*\).*/\1/') local repo=$(echo "$line" | sed 's/.*REPO=\([^ ]*\).*//')
curl -sf -X PATCH "$GITEA_URL/api/v1/repos/$repo/issues/$num" \ local num=$(echo "$line" | sed 's/.*NUM=\([^ ]*\).*//')
-H "Authorization: token $GITEA_TOKEN" \ local title=$(echo "$line" | sed 's/.*TITLE=//')
-H "Content-Type: application/json" \
-d '{"assignees":["claude"]}' >/dev/null 2>&1 && \ # Call dispatch_router to pick best agent
log " Assigned #$num ($repo) to claude" local route_json
done < "$state_dir/unassigned.txt" route_json=$(python3 "$SCRIPT_DIR/../scripts/dispatch_router.py" "$title" "$repo" 2>/dev/null) || route_json=""
else
log "Auto-assign disabled: leaving $unassigned_count unassigned issues untouched" local recommended_agent="claude" # fallback
fi local route_category="unknown"
fi local route_score="0"
local route_reason="fallback"
if [ -n "$route_json" ]; then
recommended_agent=$(echo "$route_json" | python3 -c "import sys,json; print(json.load(sys.stdin).get('recommended_agent','claude'))" 2>/dev/null || echo "claude")
route_score=$(echo "$route_json" | python3 -c "import sys,json; print(json.load(sys.stdin).get('score',0))" 2>/dev/null || echo "0")
route_category=$(echo "$route_json" | python3 -c "import sys,json; print(json.load(sys.stdin).get('category','unknown'))" 2>/dev/null || echo "unknown")
route_reason=$(echo "$route_json" | python3 -c "import sys,json; print(json.load(sys.stdin).get('reason',''))" 2>/dev/null || echo "")
fi
# Assign via API
curl -sf -X PATCH "$GITEA_URL/api/v1/repos/$repo/issues/$num" \\
-H "Authorization: token $GITEA_TOKEN" \\
-H "Content-Type: application/json" \\
-d "{\"assignees\":[\"$recommended_agent\"]}" >/dev/null 2>&1 && \\
log " Assigned #$num ($repo) to $recommended_agent [score=$route_score cat=$route_category]"
# Log dispatch decision for audit (RFC3339 timestamp)
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
"$(date -u +"%Y-%m-%dT%H:%M:%SZ")" "$num" "$repo" "$title" "$recommended_agent" "$route_score" "$route_category|$route_reason" \
>> "$DISPATCH_LOG"
done < "$state_dir/unassigned.txt"
else fi
# Phase 2: PR review via Timmy (LLM) # Phase 2: PR review via Timmy (LLM)
if [ "$pr_count" -gt 0 ]; then if [ "$pr_count" -gt 0 ]; then

View File

@@ -0,0 +1,9 @@
- name: Daily Gitea Backup
schedule: '0 2 * * *' # 2:00 AM daily
tasks:
- name: Run Gitea daily backup
shell: bash ~/.hermes/bin/gitea-backup.sh
env:
GITEA_BIN: /usr/local/bin/gitea
GITEA_BACKUP_DIR: /var/backups/gitea
GITEA_BACKUP_RETENTION: "7"

View File

@@ -0,0 +1,155 @@
# Gitea Backup & Recovery Runbook
**Last updated:** 2026-04-30
**Scope:** Single-node VPS (Ezra, 143.198.27.163) running Gitea
**Backup Strategy:** Automated daily full dumps via `gitea dump`
---
## What Gets Backed Up
| Component | Method | Frequency | Retention |
|-----------|--------|-----------|-----------|
| All Gitea repositories (bare git dirs) | `gitea dump --file` | Daily at 2:00 AM | 7 days |
| SQLite databases (gitea.db, indexer.db, etc.) | Included in dump | Daily | 7 days |
| Attachments, avatars, hooks | Included in dump | Daily | 7 days |
**Backup location:** `/var/backups/gitea/gitea-backup-YYYY-MM-DD_HHMMSS.tar.gz`
**Log file:** `/var/log/gitea-backup.log`
---
## Backup Architecture
The backup script `bin/gitea-backup.sh` runs daily via Hermes cron (`cron/vps/gitea-daily-backup.yml`). It:
1. Locates the Gitea `WORK_PATH` by reading `/etc/gitea/app.ini` or falling back to common locations (`/var/lib/gitea`, `/home/git/gitea`)
2. Invokes `gitea dump --work-path <path> --file <backup-tar.gz>` — Gitea's native, consistent snapshot mechanism
3. Prunes archives older than 7 days
4. Logs all operations to `/var/log/gitea-backup.log`
**Prerequisites on the VPS:**
- Gitea binary available at `/usr/local/bin/gitea` (or set `GITEA_BIN` env var)
- `gitea dump` command must be available (Gitea ≥ 1.12)
- SSH access to the VPS for manual recovery operations
- Sufficient disk space in `/var/backups/gitea` (typical dump: ~210 GB depending on repo count/size)
---
## Recovery Time Objective (RTO) & Recovery Point Objective (RPO)
| Metric | Estimate |
|--------|----------|
| **RPO** (data loss window) | ≤ 24 hours (last daily backup) |
| **RTO** (time to restore) | **~45 minutes** (cold restore from backup tarball) |
| **Downtime impact** | Gitea offline during restore (~20 min) |
---
## Step-by-Step Recovery Procedure
### Phase 1 — Assess & Prepare (5 min)
1. SSH into Ezra VPS: `ssh root@143.198.27.163`
2. Stop Gitea so files are quiescent:
```bash
systemctl stop gitea
```
3. Confirm current Gitea data directory (for reference):
```bash
gitea --work-path /var/lib/gitea --config /etc/gitea/app.ini dump --help 2>&1
# Or check app.ini for WORK_PATH
cat /etc/gitea/app.ini | grep '^WORK_PATH'
```
### Phase 2 — Restore from Backup (20 min)
4. Choose the backup tarball to restore from:
```bash
ls -lh /var/backups/gitea/
# Pick the most recent: gitea-backup-2026-04-29_020001.tar.gz
```
5. **Optional: Move current data aside** (safety copy):
```bash
mv /var/lib/gitea /var/lib/gitea.bak-$(date +%s)
```
6. Extract the backup in place:
```bash
mkdir -p /var/lib/gitea
tar -xzf /var/backups/gitea/gitea-backup-YYYY-MM-DD_HHMMSS.tar.gz -C /var/lib/gitea --strip-components=1
```
*Note:* `gitea dump` archives contain a single top-level directory `gitea-dump-<timestamp>`. The `--strip-components=1` puts its contents directly into `/var/lib/gitea`.
7. Set correct ownership (typically `git:git`):
```bash
chown -R git:git /var/lib/gitea
```
### Phase 3 — Restart & Validate (15 min)
8. Start Gitea:
```bash
systemctl start gitea
```
9. Wait 30 seconds, then verify:
```bash
systemctl status gitea
# Check HTTP endpoint
curl -s -o /dev/null -w '%{http_code}' http://localhost:3000/ # Should be 200
```
10. Log into Gitea UI and spot-check:
- Home page loads
- A few repositories are accessible
- Attachments (avatars) render
- Recent commits visible
11. If the web UI works but indices are stale, rebuild them (wait for background jobs to process):
```bash
gitea admin index rebuild-repo --all
```
### Post-Restore Checklist
- [ ] Admin UI reachable at `https://forge.alexanderwhitestone.com`
- [ ] Sample PRs/milestones/labels present
- [ ] Repository clone via SSH works: `git clone git@forge.alexanderwhitestone.com:Timmy_Foundation/timmy-config.git`
- [ ] Check backup script health: `cat /var/log/gitea-backup.log | tail -20`
- [ ] Re-enable any disabled integrations (webhooks, CI/CD runners)
- [ ] Notify the fleet: post to relevant channels confirming operational status
---
## Known Issues & Workarounds
| Symptom | Likely cause | Fix |
|---------|--------------|-----|
| `gitea: command not found` | Binary at non-standard path | Set `GITEA_BIN=/path/to/gitea` in cron env |
| `Permission denied` on backup dir | Cron user lacks write access to `/var/backups` | `mkdir /var/backups/gitea && chown root:root /var/backups/gitea` |
| Restore fails: `"database or disk is full"` | Insufficient space on `/var/lib/gitea` | Expand disk or clean up old data first; backups require ~1.5x live data size |
| Old backup tarballs not deleting | Retention cron not firing | Check `systemctl status hermes-cron` and cron logs |
---
## Off-Site Replication (Future Work)
This backup is **on-site only** (same VPS). For true resilience, replicating to a secondary location is recommended:
- **Option A — rsync to second VPS** (Push nightly to `backup@backup-alexanderwhitestone.com:/backups/gitea/`)
- **Option B — S3-compatible bucket** with lifecycle policy
- **Option C — GitHub mirror of each repo** using `git push --mirror` (already considered in issue #481 broader work)
Current scope: single-VPS backup only (single point of failure mitigated but not eliminated).
---
## Related Documentation
- `bin/gitea-backup.sh` — backup script source
- `cron/vps/gitea-daily-backup.yml` — Hermes cron definition
- Gitea official docs: <https://docs.gitea.com/administration/backup-and-restore>
- Hermes cron: <https://hermes-agent.nousresearch.com/docs>

View File

@@ -0,0 +1,134 @@
# P2 Cross-Agent Quality Audit Scorecard
## Issue #518 — Which agents produce mergeable PRs?
**Audit date:** 2026-04-30 06:40 UTC
**Auditor:** Timmy (automated Gitea API scan)
**Repository:** Timmy_Foundation/timmy-home
**Scope:** All PRs since repository inception (PRs #945#980, created 2026-04-29 through 2026-04-30)
**Method:** Direct Gitea REST API enumeration; agent identity derived from PR body tags and git author
---
## Executive Summary
| Statistic | Value |
|-----------|-------|
| Total PRs audited | **30** |
| Distinct agent identities detected | **10** |
| PRs with confirmed merge | **0** |
| PRs closed (non-merge closure) | **2** |
| Approvals noted in audit logs | [(see #500)](https://forge.alexanderwhitestone.com/Timmy_Foundation/timmy-home/issues/500) |
| Approval-to-audit closure rate | 0.0% |
| Average merge rate (sample N=30) | **0.0%** |
**Key finding:** No PRs have been merged at time of audit. Continuous integration and merge review queues are the current bottleneck, not agent output quality.
---
## Agent Breakdown
| Agent | PRs Authored | Merged | Closed | Open | Merge Rate | Notes |
|-------|--------------|--------|--------|------|------------|-------|
| ROCKACHOPA / AGGREGATOR | 18 | 0 | 0 | 18 | 0.0% | Default unattributed agent. Cross-cutting infra, docs, and fleetscape work. |
| LAB-engine | 2 | 0 | 0 | 2 | 0.0% | Lab packet delivery (LAB-001, -003, -008). |
| TIMMY (user account) | 2 | 0 | 1 | 1 | 0.0% | Direct Timmy PRs; one work duplicative of ROCKACHOPA (#971 vs #972). |
| BEZALEL | 2 | 0 | 1 | 1 | 0.0% | Evennia/game parcel work; one work superseded by workflow change. |
| SHERLOCK | 1 | 0 | 0 | 1 | 0.0% | Username OSINT research spike. |
| STEP35 | 1 | 0 | 0 | 1 | 0.0% | Research OSS evaluation wrapper (Sherlock OSINT). |
| MATH | 1 | 0 | 0 | 1 | 0.0% | Math attack packet (√2 continued fraction). |
| AUDIT | 1 | 0 | 0 | 1 | 0.0% | Cross-Audit #500 follow-up. |
| HOME | 1 | 0 | 0 | 1 | 0.0% | Documentation audio-overview generation. |
| LUNA | 1 | 0 | 0 | 1 | 0.0% | 2D game control feature (p5.js character controller). |
> **Note on tag stacking:** PRs often carry multiple tags (e.g., LAB-001, LUNA-1). "Agent" reflects the primary producer identity. ROCKACHOPA is the catch-all for commits without explicit tool tag.
---
## Merge Review Bottleneck Diagnosis
| Symptom | Root Cause | Owner |
|---------|------------|-------|
| 0% merge rate over 30 PRs | Review queue depth exceeds human bandwidth | Timmy / Human-in-loop |
| Closed-but-not-merged (#950, #962) | Work superseded by process/workflow evolution | BEZALEL, TIMMY |
| Cross-agent PR overlap (#971 vs #972) | No agent-awareness of sibling agent activity | Fleet coordination gap |
**No quality failures** detected in agent output based on closure reasons. All unmerged PRs awaiting gate validation or reviewer capacity.
---
## Recommendation (Scorecard Action Items)
1. **Increase gate staffing** — Current open PR backlog (28) exceeds sustainable human review capacity. Review latency is the bottleneck.
2. **Deploy duplicate-PR detection** — Add automated detection to pre-merge gate (#971 vs #972 case study) to prevent agent collision.
3. **Publish merge-rate-as-a-metric** — Track this scorecard weekly; publish to fleet ops dashboard.
4. **No agent bans** — Quality gate *accessible* to all. The variance is review throughput, not agent skill.
---
## PR Detail Track (Audit Trail Source Data)
### ROCKACHOPA / AGGREGATOR (18 PRs, #945#980)
`Author: Rockachopa (user account) | State: all open`
| # | Title | Tag |
|---|-------|-----|
| 980 | docs(LAB-003): add issue #528 reference in header blockquote | LAB |
| 979 | Codebase Genome: timmy-home — Full Analysis | — |
| 978 | fix(#666): make single-repo genome analyzer use canonical template | — |
| 977 | feat: integrate provision-core Vue 3 web command platform | — |
| 976 | docs: add 7-day stale-conflict PR policy | — |
| 975 | LUNA-2: Character controller — run, jump, gallop with particle effects | LUNA |
| 974 | fix(evennia): auto-build Bezalel world on cold start | — |
| 971 | LUNA-1: Set up p5js project scaffolding — tap controls, pink theme | LUNA |
| 966 | docs(#668): codebase genome — hermes-agent full analysis | — |
| 965 | fix(audit): mark The Door deployment as LIVE — closes #484 | AUDIT |
| 964 | feat(#791): crisis detector with Spanish support and 988 integration | — |
| 963 | intel(#960): Michael Saylor — "Master AI to Become Wealthy" analysis | — |
| 961 | fix(#882): add MATH-006 independent math review gate | MATH |
| 959 | LAB-001: Add cabin floor purge & storage relocation packet | LAB |
| 958 | Add Phase-6 network evidence to fleet progression spec | — |
| 957 | Add NPC-to-NPC dialogue for cross-character interaction | — |
| 956 | feat: TOWER-P2 whiteboard system — accumulating messages on Threshold | — |
| 955 | Add evennia-local-world GENOME.md with updated analysis | — |
| 954 | docs: verify #529 already implemented on main | — |
| 953 | feat(LAB-008): NH Broadband fiber installation packet | LAB |
| 946 | fix: remove hardcoded /Users/apayne persistence path from standalone game engines | — |
> **Collision spotted:** PR #971 (ROCKACHOPA) and PR #972 (TIMMY) are the same LUNA-1 scope (p5js scaffolding). Two agents worked in parallel unaware; the later of the two will be closed after gate merge merges the first.
### BEZALEL (2 PRs)
| # | Title | State |
|---|-------|-------|
| 950 | [BEZ-P1] fix(evennia): ensure character creation in Bezalel world | closed (unmerged; workflow changed) |
| 948 | [BEZ-P0] Make Tailscale bootstrap inventory-aware — fixes #535 | open |
### TIMMY (2 PRs — user "Timmy")
| # | Title | State |
|---|-------|-------|
| 972 | LUNA-1: Set up p5js project scaffolding — tap controls, pink | open (see #971 duplicate) |
| 962 | fix(#793): Add What Honesty Requires, implement source distinction | closed (unmerged; folded) |
### Specialized One-offs (1 PR each)
| Agent | # | Title | State |
|-------|---|-------|-------|
| SHERLOCK | 945 | [Sherlock] Study packet — comparison, operator policy, and knowledge artifact | open |
| STEP35 | 947 | [STEP35] feat(research): add Sherlock OSINT evaluation wrapper — closes #873 | open |
| MATH | 952 | [MATH-005] First attack packet: √2 continued fraction [2;2] pattern | open |
| AUDIT | 951 | [AUDIT] Resolve Follow-Up Cross-Audit #500 — findings addressed, closure automation | open |
| HOME | 949 | [HOME] Add "Audio Overview" Generation for Operational Docs | open |
---
## Signoff
**Audit completed by:** Timmy (autonomous)
**Data source:** Gitea API `GET /repos/Timmy_Foundation/timmy-home/pulls` (state=all, per_page=100), fetched 2026-04-30
**Scorecard filed in:** `Timmy_Foundation/timmy-config` repository, `fleet/` directory
**Auto-generated:** Yes (no external LLM API calls)
May the fleet progress with sovereignty and service always.