File size: 6,750 Bytes
62f3e9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4637f97
62f3e9a
4637f97
 
 
 
 
 
 
 
 
 
62f3e9a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# How a DemoPrep change gets to test

*2026-10-22. Agreed with boone on 10-20 and 10-21. Code: `demoprep_app/tracker/`,
`scripts/pipeline_run.py`, `scripts/agent_worker.sh`, the tracker tools in
`mcp_server.py`. The agent that fronts it: `docs/agentspot_task_manager_agent.md`.*

## The shape

```
branch off develop ──> pull request into develop ──> approved ──> pickup run (4x a day)
                                                                     β”‚
                                              merge into develop, suite, push origin,
                                              push the test Space when it is idle
                                                                     β”‚
                                                       boone promotes test ──> prod by hand
```

**One integration branch: `develop` on origin.** The test Space (`hf-mcp-test`,
test-mcp) always runs `develop`. Only the pickup run moves it. Production is
unchanged: `prod/mcp` is pushed to `hf-mcp` by boone, fast-forward, in prose.

**Every change is a new branch off `develop`** with a name that says what it
does, the task key first when there is one:

| Kind | Example |
|---|---|
| fix | `fix/t42-yodeck-grade-handles-null-rates` |
| feat | `feat/tracker-tasks-beside-pull-requests` |
| docs, test, chore | `docs/t51-development-process` |
| the agent's | `agent/t42-yodeck-grade-handles-null-rates` (the worker names these) |

A pull request into `develop` is the only way back. Put the task key (`T-42`)
in the title or body if the branch name does not carry it; the tracker links
the PR to its task from either.

## Approval

| Who opened it | What happens |
|---|---|
| Mike (`boone10`) or Jack (`jackrayner-ts`), on any branch except `agent/` | approved on arrival (`auto`) |
| anyone else, or any `agent/` branch | waits for Mike or Jack: a GitHub review, or "approve #57" to the Task Manager agent, which calls `approve_pull_request` |
| an approver requests changes | held (`changes_requested`) until their later review approves |

To hold your own PR back, make it a draft. The policy lives in
`tracker_people.can_approve` / `auto_merge`, derived by the sync in
`demoprep_app/tracker/github_sync.py`.

## The pickup run

`scripts/pipeline_run.py`, on boone's Mac under launchd at **7:30, 11:30, 15:30
and 19:30 Eastern** (`scripts/launchd/com.demoprep.pipeline.plist`). Each run:

1. On the 7:30 run, turns recent build warnings (`demo_findings`) into tasks for
   the agent, one per finding code (`demoprep_app/tracker/findings.py`).
2. Reads the queue: open PRs that are approved, not drafts, targeting `develop`,
   not red, not conflicting. The rest are listed with the reason they are held.
3. In its own worktree (`pipeline/` in the repo, gitignored), merges each ready
   PR into `develop`, oldest first, `--no-ff`. A conflict skips that PR and
   notes its task.
4. Runs the unit suite (`pytest tests --noconftest`). A failure that is not in
   `scripts/pipeline_known_failures.txt` means no push and a p1 task for the
   agent.
5. Pushes `develop` to origin.
6. Waits until the test Space has been idle for three minutes (no active build,
   no build finished in the last three minutes: a push restarts the Space and
   wipes results SEs are still polling), pushes `develop` to `hf-mcp-test` main,
   waits for `ping` to report the pushed sha, records a `deployments` row, and
   notes "on test-mcp as <sha>" on each merged PR's task.

If the Space stays busy for twenty minutes, origin is pushed and the next run
pushes the Space. A push that is not a fast-forward (someone pushed to the Space
by hand) is refused and reported, never forced. Nothing here touches prod.

Where to look: `logs/pipeline.log`, the `pipeline_status` and `list_deployments`
tools (ask the Task Manager agent "what shipped to test today"), the Pipeline
tab of the Team Tracker Liveboard, the `pipeline_runs` and `deployments` tables.

## The agent

The agent is a row in `tracker_people` (`is_agent`); tasks are assigned to it like
to anyone. `scripts/agent_worker.sh` takes its top open task, cuts
`agent/t<id>-<what>` off `develop` in its own worktree, runs Claude Code with
`scripts/agent_worker_prompt.md`, and if a commit resulted, pushes the branch
and opens the PR under boone's credentials. The agent has no GitHub login; the
`agent/` prefix is what keeps its PRs off the auto-approve path. Run the worker
by hand or add it to launchd beside the pickup run.

## One-time setup

1. **Supabase.** Run `demoprep_app/tracker/schema.sql` in the project's SQL editor
   (idempotent), then the `tracker_reader` role lines at its bottom with a password.
2. **`develop` to the test tip, once.** In the main checkout:
   ```bash
   git fetch hf-mcp-test origin
   git branch -f develop hf-mcp-test/main
   git push origin develop
   ```
   It is a fast-forward (origin's `develop` is an ancestor of the test tip).
   Retarget Jack's open PRs to `develop`: `gh pr edit <n> --base develop`.
3. **The test Space env:** `GITHUB_TOKEN`, `TRACKER_REPOS=boone10/DemoPrep,thoughtspot/tse_demos`,
   `TRACKER_INTEGRATION_BRANCH=develop`. Setting a variable restarts the Space:
   check `status` first. The token is a GitHub fine-grained personal access token
   (Settings, Developer settings, Personal access tokens, Fine-grained) with:
   Repository access "Only select repositories" including `boone10/DemoPrep`;
   Repository permissions **Pull requests: Read-only** (Metadata: Read-only comes
   with it). Optional, for the `checks` column once GitHub Actions exist: Checks
   and Commit statuses, Read-only; without them the sync records "none". A token
   missing Pull requests answers 403 "Resource not accessible by personal access
   token" on the first sync (seen 2026-10-22). Editing the token's permissions
   keeps its value, so the Space secret need not change. Only the test Space
   gets `TRACKER_REPOS`: the sync runs in one place.
4. **The Mac:** `gh` and `claude` on PATH, `gh auth login` as boone10;
   `cp scripts/launchd/com.demoprep.pipeline.plist ~/Library/LaunchAgents/ &&
   launchctl load ~/Library/LaunchAgents/com.demoprep.pipeline.plist`. The first
   run creates the `pipeline/` worktree. `MCP_ACCESS_TOKEN` and `HF_TOKEN` are
   already in `.env`.
5. **ThoughtSpot:** the Supabase Tracker connection and the TML in
   `demoprep_app/tracker/tml/` (see the agent doc).

## Not in this version, on the list

- GitHub Actions running the suite on every PR (the pickup run runs it for now).
- Slack intake from the SC demo tools channel: AgentSpot reads it with boone's
  login and calls `create_task`; nothing server-side.
- Test to staging to prod: boone, by hand, until the test line has run this way
  for a while.