Skip to content

Commit 8e4f482

Browse files
committed
finished out automation improvements.
1 parent a585ba0 commit 8e4f482

11 files changed

Lines changed: 80 additions & 211 deletions

.github/workflows/baseline-terminal-cleanup.yaml

Lines changed: 0 additions & 122 deletions
This file was deleted.

.github/workflows/stale-role-warning.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ on:
55
# Every Monday at 9am UTC
66
- cron: '0 9 * * 1'
77
workflow_dispatch:
8+
inputs:
9+
dry_run:
10+
description: 'Dry run (log which roles would be warned, without commenting)'
11+
required: false
12+
default: 'true'
13+
type: boolean
814

915
env:
1016
GH_TOKEN: ${{ secrets.ACTIONS_TOKEN }}
@@ -21,8 +27,10 @@ jobs:
2127
steps:
2228
- name: Comment on open roles stale for 90+ days
2329
run: |
30+
DRY_RUN="${{ github.event.inputs.dry_run || 'false' }}"
2431
CUTOFF=$(date -d "-${STALE_DAYS} days" +%s 2>/dev/null || date -v "-${STALE_DAYS}d" +%s)
2532
33+
echo "Dry run: $DRY_RUN"
2634
echo "Checking for roles not updated since $(date -d @$CUTOFF 2>/dev/null || date -r $CUTOFF)..."
2735
2836
CURSOR=""
@@ -102,6 +110,12 @@ jobs:
102110
fi
103111
104112
DAYS_STALE=$(( ( $(date +%s) - UPDATED_TS ) / 86400 ))
113+
114+
if [ "$DRY_RUN" == "true" ]; then
115+
echo "Would warn on #$ISSUE_NUMBER ($DAYS_STALE days since last update)."
116+
continue
117+
fi
118+
105119
echo "Posting stale warning on #$ISSUE_NUMBER ($DAYS_STALE days since last update)..."
106120
107121
# Build the body with printf so every line stays indented inside

README.md

Lines changed: 20 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,52 +27,41 @@ tools/sync/run.sh
2727

2828
**Snapshots are gitignored** — always regenerate them at the start of a work session.
2929

30-
## Write Tools
31-
Write tools for guarded mutations (label changes, issue closes, board moves) are in active development. See `docs/github-tooling.todo.md` for status.
30+
## Write Operations
31+
Guarded writes (label changes, issue closes, board moves) happen two ways: the **board-automation workflows** described below, and the **`gh` CLI** directly for ad-hoc changes — see [AGENTS.md](AGENTS.md) for the command patterns and safety rules. There is no separate Python write-tool layer; the early plan for one (now at `docs/archive/github-tooling.todo.md`) was set aside in favor of workflows + `gh`.
3232

33-
All write operations require `--dry-run` by default and explicit approval before execution.
33+
All write operations follow the write-safety rules: dry-run first where supported, and explicit approval before anything that mutates shared org state.
3434

3535
## Board Automation
3636
GitHub Actions in [`.github/workflows/`](.github/workflows/) keep issue state and the two project boards (Org Kanban, Open Roles) in sync, so closing/reopening an issue and moving a board card stay consistent without manual bookkeeping. **Almost everything is custom Actions in this repo** — with exactly **one deliberate exception**: the native Projects "Auto-close issue" workflow (see below). All other native Projects workflows are intentionally turned **off**, so code is the single source of truth.
3737

38-
Issue events (`opened`, `closed`, `reopened`, `labeled`) are real repository events and drive the board **immediately** in code. The reverse direction — a board card move driving the issue — is **not** available as a repo-level trigger (`projects_v2_item` is an org-level event that never reaches a repo workflow; see [`docs/decisions/0004-projects-v2-automation-triggers.md`](docs/decisions/0004-projects-v2-automation-triggers.md)). That direction splits in two:
39-
- **Card → close** (Done/Filled): the native **`Auto-close issue`** workflow, configured in each Project's Workflows UI. Instant. **This is the one piece of board logic not in the repo** — it has no workflow file. Documented in [`docs/decisions/0005-board-sync-architecture.md`](docs/decisions/0005-board-sync-architecture.md).
40-
- **Card → reopen**: has no native equivalent and no immediate path, so it is the single scheduled reconciliation job (`board-reopen-reconcile`, every ~5 min).
38+
A tracked issue has one continuous lifecycle: it's **opened**, routed once (by whether it carries the `open role` label) to one board, and then cycles between an open state and a closed state on that board. Each cycle transition can be driven from **either side** — act on the issue, or move the card — and they stay in sync.
4139

4240
```mermaid
43-
flowchart LR
44-
NEW([Issue opened]):::evt
45-
CLOSE([Issue closed]):::evt
46-
REOPEN([Issue reopened]):::evt
41+
flowchart TD
42+
OPENED([Issue opened]) --> Q{Open role?}
4743
4844
subgraph KANBAN["Org Kanban board"]
49-
K_TODO["To Do"]:::col
50-
K_DONE["Done"]:::col
45+
K_TODO["To Do<br/>(issue open)"]
46+
K_DONE["Done<br/>(issue closed)"]
47+
K_TODO -->|"close issue → close-to-done<br/>· or drag card to Done → native Auto-close"| K_DONE
48+
K_DONE -->|"reopen issue → reopened-to-todo<br/>· or drag card off Done → reconcile poll ~5m"| K_TODO
5149
end
50+
5251
subgraph ROLES["Open Roles board"]
53-
R_OPEN["Open"]:::col
54-
R_FILLED["Filled"]:::col
52+
R_OPEN["Open<br/>(issue open)"]
53+
R_FILLED["Filled<br/>(issue closed)"]
54+
R_OPEN -->|"close issue → closed-to-filled<br/>· or drag card to Filled → native Auto-close"| R_FILLED
55+
R_FILLED -->|"reopen issue → open-role-reopened<br/>· or drag card off Filled → reconcile poll ~5m"| R_OPEN
5556
end
5657
57-
%% Issue -> board (event-driven code, immediate)
58-
NEW -->|"not open-role<br/>add-issue-to-kanban"| K_TODO
59-
NEW -->|"open-role label<br/>open-role-add (also removes from Kanban)"| R_OPEN
60-
CLOSE -->|"close-to-done"| K_DONE
61-
CLOSE -->|"open-role<br/>closed-to-filled"| R_FILLED
62-
REOPEN -->|"not open-role<br/>reopened-to-todo"| K_TODO
63-
REOPEN -->|"open-role<br/>open-role-reopened"| R_OPEN
64-
65-
%% Board -> issue (native close = solid, scheduled reopen = dotted)
66-
K_DONE -->|"NATIVE: Auto-close issue"| CLOSE
67-
R_FILLED -->|"NATIVE: Auto-close issue"| CLOSE
68-
K_TODO -.->|"board-reopen-reconcile<br/>scheduled ~5m"| REOPEN
69-
R_OPEN -.->|"board-reopen-reconcile<br/>scheduled ~5m"| REOPEN
70-
71-
classDef evt fill:#dbeafe,stroke:#3b82f6,color:#1e3a5f;
72-
classDef col fill:#f3f4f6,stroke:#9ca3af,color:#111827;
58+
Q -->|no · add-issue-to-kanban| K_TODO
59+
Q -->|yes · open-role-add| R_OPEN
7360
```
7461

75-
Solid arrows are immediate (event-driven code, or the one native close); the **dotted arrow is the single ~5-minute polling job**, so reopening via a board move can lag a few minutes (reopening the issue directly is immediate). Two more custom Actions run on labels: `label-open-role-from-form` reads the open-role issue-form dropdown and applies the team label(s), and `open-role-add` routes newly-labeled open roles and sets their initial status. A one-time `baseline-terminal-cleanup` job (manual) is run once before the reopen reconciler's schedule is enabled, so the reconciler never resurrects issues closed before this automation existed.
62+
Everything on the issue side (open / close / reopen) and the native card→close is **immediate**. The one lagging path is **card → reopen** (dragging a card out of Done/Filled): it's the single scheduled job (`board-reopen-reconcile`), and **GitHub's scheduled runs are best-effort, often delayed 10–30+ minutes** (the first run after enabling is slowest) — so reopening the *issue* directly is the instant option. That reconciler is the one exception to "immediate"; the one exception to "in the repo" is the native `Auto-close issue` workflow (card→close), which is configured in the Projects UI and has no workflow file. A fresh-close guard keeps the reconciler from resurrecting issues closed before this automation existed (it skips anything closed in the last 10 minutes; a one-time cleanup tool used during rollout confirmed the boards were already consistent and has since been removed).
63+
64+
**Routing is right-the-first-time — no board is wastefully double-touched.** An open-role issue created via the form goes straight to Open Roles and never lands on the Kanban. The *only* time anything is removed from a board is **reclassification**: a plain issue that landed on the Kanban is *later* labeled `open role`, so `open-role-add` moves it to Open Roles and clears the now-stale Kanban card. Separately, `label-open-role-from-form` reads the open-role form's team dropdown and applies the team label(s).
7665

7766
**Scheduled maintenance & reporting** (separate from the sync loop above):
7867

TODO.md

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
This is the coordination map for active work in this repo. See `skills/run-project-spike/SKILL.md` for the full process.
33

44
## Done
5+
### Board ↔ Issue Sync Redesign *(archived: `docs/archive/board-sync-redesign.md`)*
6+
Re-architected board↔issue sync: native `Auto-close issue` is the single non-code exception (card→close), everything else is code, one `board-reopen-reconcile` poller (~5 min) handles card→reopen, all other native Projects workflows off. Confirmed working live 2026-07-08. Durable outcomes in `README.md` (Board Automation) and decisions `0004`/`0005`. Note: GitHub scheduled runs can be badly delayed (first reopen took ~25+ min).
7+
8+
### GitHub Automation *(archived: `docs/archive/github-automation.md`)*
9+
Built the full board/issue automation set — routing, issue↔board status sync, scheduled archive, Slack reporting, form labeling. Two incidents fixed en route: `role-pipeline-report` cron firing daily instead of monthly, and the `projects_v2_item` trigger being invalid so board→issue sync never fired (decision `0004`, which spawned the Board Sync Redesign). Also hardened `label-open-role-from-form` (script-injection) and `stale-role-warning` (YAML block-scalar bug that had kept it from ever running).
10+
11+
### Backlog Triage *(archived: `docs/archive/backlog-triage.md`)*
12+
Restructured label taxonomy to match Refactor 2026 Teams structure. Labeled all issues, closed dead issues, retired old labels. Done column cleanup and "To Do" column review deferred to automation spike and human triage.
13+
514
### Weekly Summary Per-Team Channels *(archived: `docs/archive/weekly-summary-channels.md`)*
615
Broke the weekly org summary into per-team Slack channels (`#oa-board`, `#t-infrastructure`, `#t-finance`, `#t-fundraising`, `#t-communications`, `#t-education`, `#pg-data-fellowship`, plus existing `#t-engagement`); `#oa-org` is now priority-only. First real run posted successfully 2026-07-07. See the archived to-do doc for two editorial points that weren't explicitly re-confirmed before closing (multi-label cross-posting, open-role issues in non-engagement channels).
716

@@ -30,44 +39,21 @@ Getting the repo into a state where agents can work effectively and the methodol
3039
- [x] Update `README.md` to document tooling and workflow
3140

3241
## Active Spikes
33-
### Board ↔ Issue Sync Redesign
34-
**Status:** Planned, not yet implemented
35-
**Spike:** `docs/active-spikes/board-sync-redesign.md`
36-
**Todo:** `docs/active-spikes/board-sync-redesign.todo.md`
37-
38-
Re-architecting board↔issue sync: native `Auto-close issue` for card→close (the one non-code exception), everything else in code, one 5-minute reopen poller, all other native Projects workflows off. Continues from the GitHub Automation spike. Plan is written; implementation pending (starts with native UI config + a one-time baseline cleanup).
39-
40-
### Backlog Triage *(archived: `docs/archive/backlog-triage.md`)*
41-
Restructured label taxonomy to match Refactor 2026 Teams structure. Labeled all issues, closed dead issues, retired old labels. Done column cleanup and "To Do" column review deferred to automation spike and human triage.
42-
43-
### GitHub Automation
44-
**Status:** Active
45-
**Spike:** `docs/active-spikes/github-automation.md`
46-
**Todo:** `docs/active-spikes/github-automation.todo.md`
47-
48-
GitHub Actions to keep boards and issue state in sync. Fixes the root cause of board noise. `ACTIONS_TOKEN` secret and project IDs are confirmed.
49-
50-
**Incident (2026-07-07):** `role-pipeline-report.yaml`'s cron mixed day-of-month and day-of-week fields, which cron evaluates as OR — it fired daily instead of monthly and spammed `#t-engagement`. Fix applied as a plain working-tree change (not yet committed) rather than a PR — see the to-do doc.
42+
None currently active.
5143

52-
**Incident (2026-07-08):** the board→issue direction of both bidirectional syncs (Filled→close, Open/In Progress→reopen) was silently dead — `on: projects_v2_item` isn't a valid repo-level Actions trigger and never fired. See `docs/decisions/0004-projects-v2-automation-triggers.md`. `filled-to-close.yaml`/`done-to-close.yaml` deleted (superseded by Projects v2's native "Auto-close issue" workflow); `open-roles-reopen.yaml`/`kanban-status-reopen.yaml` rewritten as 15-minute scheduled reconciliation jobs. Also uncommitted working-tree changes.
44+
## Automation — residual QA / watch
45+
Low-priority follow-ups left after archiving the automation spikes (2026-07-08). None block anything; the automation is live and working.
5346

54-
- [x] Automation 1: Enhance open role routing (remove from Org Kanban when `open role` labeled)
55-
- [x] Automation 2: New issue → Org Kanban "To Do"
56-
- [x] Automation 3: Issue closed → move to Done on Org Kanban
57-
- [x] Automation 4: Open Roles "Filled" → auto-close issue
58-
- [x] Automation 5: Done > 6 months → auto-archive (scheduled)
59-
- [x] Automation 6: Done → close issue (bidirectional Kanban)
60-
- [x] Automation 7: To Do/In Progress → reopen issue (bidirectional Kanban)
61-
- [x] Automation 8: Issue reopened → Kanban "To Do"
62-
- [x] Automation 9: Issue closed (open role) → Open Roles "Filled"
63-
- [x] Automation 10: Open Roles Open/In Progress → reopen issue
64-
- [x] Automation 11: Issue reopened (open role) → Open Roles "Open"
65-
- [x] Automation 12: Open Roles Filled > 1 year → auto-archive (scheduled)
66-
- [ ] Human QA: test all workflows in live GitHub environment
47+
- **`role-pipeline-report` next first-Monday** — the cron fix (skip unless day-of-month ≤ 7) hasn't been observed on a real first Monday yet. Confirm it posts once, not daily.
48+
- **`archive-old-done` / `archive-old-filled`** — implemented with dry-run defaults but never exercised. Run each once via the Actions UI with `dry_run=true` to eyeball the output when convenient.
49+
- **`stale-role-warning` dry-run** — YAML parse bug fixed and logic proven locally; a `dry_run` input was added (commit pending). After committing, dispatch once with `dry_run=true` to confirm end-to-end.
50+
- **Two board-sync edge paths** — blank-issue-then-`open role` routing, and the fresh-close guard, are verified by reading but not exercised live.
6751

52+
## Later / Ideas
6853
- **Google Drive agent access** — once the GitHub layer is stable, giving agents GDrive read access would allow them to use org docs, meeting notes, and wiki exports as context without needing everything committed to the repo
6954
- **Staleness surfacing** — periodic snapshot-based digest of stale issues for agent-assisted triage sessions
7055
- **Board resolution tracking** — low priority for now; decision-making is highly human/interpersonal
7156
- **Board onboarding doc** — carried over from the wiki migration (`docs/archive/wiki-migration.md`); unconfirmed whether existing material exists or still needs creating (closed #393 noted onboarding should be handled here)
57+
- **Contributor Profile board** — handled in the CoP repos, not here; the org-repo automation doesn't touch it (user to log a ticket)
7258

7359
*(Completed spikes and tasks are archived here or moved to `docs/archive/`.)*

0 commit comments

Comments
 (0)