toga-ai 1.0.789 → 1.0.790

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,7 +45,7 @@
45
45
  | [OneUptime push-metric monitors for 2.0 workers](features/oneuptime-worker2-monitoring.md) | A second, **OneUptime-reporting** monitoring pattern for the 2.0 worker2 tier, ported from the 1.0 `App_SystemMonitor_Compass` monitors. |
46
46
  | [Platform Cache Cleanup (_Worker_Platform_Cache — Clean + Truncate)](features/platform-cache-cleanup.md) | `_Worker_Platform_Cache` owns maintenance of the shared **Cache** cluster that backs api2's [multi-client data retrieval](../../api2/features/cross-client-data- |
47
47
  | [QA/QC Branch Automation (auto-mirror + rebuild-from-ledger revert)](features/qa-qc-branch-automation.md) | Two CTO-approved (AGREE) pieces of GitHub branch automation, centralized in **worker2** rather than per-repo GitHub Actions. |
48
- | [QA/QC Review Pipeline (ClickUp review chain, QC batch + defect/client-review)](features/qa-qc-review-pipeline.md) | The ClickUp-driven **QA then QC** review chain for the platform-wide QA/QC dev process (per the approved `QA-QC Plan.txt`). |
48
+ | [QA/QC Review Pipeline (ClickUp review chain, QC batch + defect/client-review)](features/qa-qc-review-pipeline.md) | The ClickUp-driven review + promotion chain for the platform-wide QA/QC dev process (per the approved `QA-QC Plan.txt`), moving a task through **Development → Q |
49
49
  | [Service Request → Sales Order → Purchase Order generation (Sync/ServiceRequest)](features/service-request-sales-order-generation.md) | `_Worker_Sync_ServiceRequest` turns a **Service Request into a Sales Order, and then into one Purchase Order per vendor**, for **any** tenant. |
50
50
  | [SSO Stability Monitor (Monitor/Operations/SsoStability)](features/sso-stability-monitor.md) | `_Worker_Monitor_Operations::SsoStability(): string` is the **reporter half** of the SAML uptime monitor. |
51
51
  | [Startech Webhook Handler (worker2)](features/startech-webhook-handler.md) | Receives inbound webhook events from Startech (Easeedesk) and creates or updates the corresponding ticket in TOGA 2.0. |
@@ -6,7 +6,7 @@ project: Worker
6
6
  client: shared
7
7
  type: feature
8
8
  status: draft
9
- updated: 2026-09-08
9
+ updated: 2026-09-09
10
10
  owners: [jcardinal]
11
11
  files:
12
12
  - worker2/Worker/Team/Github.php
@@ -25,9 +25,12 @@ than per-repo GitHub Actions. **Not deployed yet** — on the `feature-qa-qc` br
25
25
  1. **Branch auto-mirror** — keep certain branches a byte-for-byte copy of a source branch.
26
26
  2. **Rebuild-from-ledger revert** — undo one task's changes on a QA/QC branch by rebuilding the
27
27
  branch from its merge ledger, not by `git revert`.
28
+ 3. **The single guarded door to `_production`** — `MergeTaskToProduction`, the only path a merge
29
+ can reach `_production`, plus `FanProductionOut` and a hardened public `Merge()`.
28
30
 
29
- Both feed the QA/QC review flow: a denied review routes a task to Rework and reverts its code —
30
- see [QA/QC review pipeline](./qa-qc-review-pipeline.md).
31
+ All three feed the QA/QC review flow: a denied review routes a task to Rework and reverts its code;
32
+ an approved Task/Hotfix/Feature deploys through `MergeTaskToProduction` — see
33
+ [QA/QC review pipeline](./qa-qc-review-pipeline.md).
31
34
 
32
35
  ## How it works
33
36
 
@@ -54,6 +57,22 @@ see [QA/QC review pipeline](./qa-qc-review-pipeline.md).
54
57
  merge-commit revert (and revert-of-revert) break there — rebuild-from-ledger is the only
55
58
  correct undo.
56
59
 
60
+ ### The single guarded door to `_production` (`MergeTaskToProduction`)
61
+
62
+ - **`_production` is reachable ONLY through `_Worker_Team_GitHub::MergeTaskToProduction`.** It
63
+ groups a task's PRs by repo and merges each — used by the Hotfix flow and the Stage cron.
64
+ - Two layers stop a double-deploy when a webhook re-fires:
65
+ 1. a **per-repo `GET_LOCK`**, and
66
+ 2. a **persisted deploy-claim** — a row in `EnvironmentBranchMerges` with `branch='_production'`.
67
+ A re-fired webhook or a cron re-run sees the claim and resumes instead of re-merging.
68
+ - **Public `Merge()` is split** so no queue message can reach prod by accident:
69
+ - the public `Merge()` is a **thin wrapper that refuses any non-mirror merge to `_production`**;
70
+ - a private `performMerge()` is the actual engine.
71
+ - **`FanProductionOut`** merges `_production` **into the rebuildable branches** after a deploy, to
72
+ keep them current.
73
+ - **Reverts are rebuild-from-ledger, never a merge-commit revert** (see below) — this holds for
74
+ `_production`-carrying branches too.
75
+
57
76
  ### Safety rules (load-bearing)
58
77
 
59
78
  - **Force-push is gated to `REBUILDABLE_BRANCHES` only.** Mirror targets and `_production` are
@@ -70,13 +89,20 @@ see [QA/QC review pipeline](./qa-qc-review-pipeline.md).
70
89
  - **Never `git revert` a QA/QC env-branch merge.** Env branches carry `_production` merges too,
71
90
  so merge-commit revert / revert-of-revert break. Use `RebuildBranch` (reset + re-merge from
72
91
  the ledger).
92
+ - **Nothing merges to `_production` except `MergeTaskToProduction`.** Public `Merge()` refuses a
93
+ non-mirror `_production` merge, so a stray queue message can't deploy. Re-fires are stopped by
94
+ the per-repo `GET_LOCK` + the persisted deploy-claim (`EnvironmentBranchMerges` `branch='_production'`).
73
95
 
74
96
  ## Change history
97
+ - 2026-09-09 — Added the single guarded door to `_production` (draft, `feature-qa-qc`, not
98
+ deployed): `MergeTaskToProduction` (per-repo `GET_LOCK` + persisted deploy-claim in
99
+ `EnvironmentBranchMerges` `branch='_production'`, groups a task's PRs by repo); public `Merge()`
100
+ split into a wrapper that **refuses** any non-mirror `_production` merge + a private
101
+ `performMerge()` engine; `FanProductionOut` merges `_production` into the rebuildable branches.
102
+ (jcardinal)
75
103
  - 2026-09-08 — Initial (draft, on `feature-qa-qc`, not deployed): centralized GitHub branch
76
104
  automation in worker2. Auto-mirror via `MIRROR_MAP` (hard-reset + force-with-lease, push
77
105
  webhook-driven); rebuild-from-ledger revert (`RevertTask`/`RebuildBranch`/`recordMerge`,
78
106
  `REBUILDABLE_BRANCHES`, `Team.EnvironmentBranchMerges`) replacing `git revert -m 1`. Force-push
79
107
  gated to rebuildable branches; `GET_LOCK` serializes merge vs rebuild; conflicts skip+email.
80
108
  (jcardinal)
81
- </content>
82
- </invoke>
@@ -6,15 +6,20 @@ project: Worker
6
6
  client: shared
7
7
  type: feature
8
8
  status: draft
9
- updated: 2026-09-08
9
+ updated: 2026-09-09
10
10
  owners: [jcardinal]
11
11
  files:
12
12
  - worker2/Worker/Clickup/QaReview.php
13
13
  - worker2/Worker/Clickup/QcReview.php
14
14
  - worker2/Worker/Clickup/QcBatch.php
15
+ - worker2/Worker/Clickup/StageBatch.php
16
+ - worker2/Worker/Clickup/FeatureReview.php
17
+ - worker2/Worker/Clickup/BeReview.php
15
18
  - worker2/Worker/Clickup.php
19
+ - worker2/Worker/Github.php
16
20
  - _underscore/Component/Api/Clickup/Clickup.php
17
- - dbchanges2/Core/2026-09-08e - Insert QcBatch CronJob.sql
21
+ - dbchanges2/Core/2026-09-09a - Insert StageBatch CronJob.sql
22
+ - dbchanges2/Team/2026-09-09a - Add isApproved to PullRequests.sql
18
23
  related:
19
24
  - ./clickup-general-automation.md
20
25
  - ./qa-qc-branch-automation.md
@@ -23,17 +28,31 @@ related:
23
28
 
24
29
  ## Summary
25
30
 
26
- The ClickUp-driven **QA then QC** review chain for the platform-wide QA/QC dev process (per the
27
- approved `QA-QC Plan.txt`). Three **new** workers plus a new entry point in the shared ClickUp
28
- webhook handler. **Not deployed yet** — on the `feature-qa-qc` branch working tree.
31
+ The ClickUp-driven review + promotion chain for the platform-wide QA/QC dev process (per the
32
+ approved `QA-QC Plan.txt`), moving a task through **Development → QA → QC → (Client Review) →
33
+ Stage → Production**. Several **new** workers plus entry points in the shared ClickUp webhook
34
+ handler. **Not deployed yet** — on the `feature-qa-qc` branch working tree.
29
35
 
30
- - `_Worker_Clickup_QaReview` — the UI → FE → BE review chain.
31
- - `_Worker_Clickup_QcReview` — QC defect review + client review.
36
+ - `_Worker_Clickup_QaReview` — the UI → FE → BE review chain (branches by Task Type; Hotfix
37
+ BE-approve jumps straight to QC-Hotfix).
38
+ - `_Worker_Clickup_QcReview` — QC defect review + client review; also handles the **Hotfix**
39
+ defect gate and its `DeployHotfix` entry.
32
40
  - `_Worker_Clickup_QcBatch` — a weekday 4:30pm Central CRON that batches QA-Approved tasks into QC.
41
+ - `_Worker_Clickup_StageBatch` — the **Wed 4:30pm Central** CRON that ships "To Deploy" tasks to
42
+ production (the Task-flow prod-deploy piece; replaces the retired legacy status-driven merge).
43
+ - `_Worker_Clickup_FeatureReview` — the **Feature** flow: rolls a multi-subtask feature through the
44
+ same gates as a unit, advancing only when **all** subtasks clear a gate.
45
+ - `_Worker_Clickup_BeReview` — **auto** BE-approve driven by GitHub PR reviews (removes the manual
46
+ BE-review step).
47
+
48
+ **Scope gate — only fires in one ClickUp folder.** The whole automation is gated to the dedicated
49
+ **"(TEST) True Dev Sprints"** folder (id `90116585845`, list `901111612373`) via
50
+ `_Worker_Clickup::QA_QC_FOLDER_ID` + `isTaskInQaQcScope`, so it never touches live sprints.
33
51
 
34
52
  When a review is **denied**, the task is routed to **Rework** and its code changes are **reverted**
35
53
  from the QA/QC branch — see [QA/QC branch automation](./qa-qc-branch-automation.md) for how the
36
- revert (rebuild-from-ledger) works.
54
+ revert (rebuild-from-ledger) works, and for the single guarded door to `_production`
55
+ (`MergeTaskToProduction`) that the Stage cron and Hotfix flow deploy through.
37
56
 
38
57
  ## How it works
39
58
 
@@ -63,6 +82,52 @@ code triggered when a task *left* a status; the QA/QC entry must be on entering
63
82
  - **any Show Stopper** → **Rework** + revert;
64
83
  - otherwise route to **Stage (To Deploy)** or **Client-<letter> (Client Review)**.
65
84
  - **Client review webhook:** **Approved** → Stage / To Deploy; **Denied** → **Rework** + revert.
85
+ - QC entry **sets Environment to `QC-<letter>`** (the plan's "clear" wording was a slip).
86
+
87
+ ### BE auto-approve from a GitHub PR (`_Worker_Clickup_BeReview::FromPr`)
88
+
89
+ - Removes the manual BE-review step. `worker2/Worker/Github.php` gains a `pull_request_review`
90
+ case: it records each PR's approval in `PullRequests.isApproved`, parses the task custom id from
91
+ the PR title (`prTitleToCustomId` — first token, colon stripped), and dispatches `BeReview/FromPr`.
92
+ - `FromPr` sets the task's **BE Review** field **Approved only once ALL of the task's `_production`
93
+ PRs are approved**; a changes-requested on any PR → **Denied**. Multi-repo task = one decision.
94
+ - **PR → task lookup:** `PullRequests.title` (custom id) maps to a ClickUp task via
95
+ `Team.Tasks.customClickupIdentifier ↔ clickupIdentifier`.
96
+ - Setting the BE Review field then drives `QaReview` (Task / Hotfix) or `FeatureReview` (Feature).
97
+
98
+ ### Hotfix flow (`QaReview` + `QcReview`)
99
+
100
+ - Expedites a **single** task straight to production, **skipping Stage**.
101
+ - `QaReview::handleBeReview` branches by Task Type; a **Hotfix** BE-approve → **QC-Hotfix**.
102
+ - `QcReview` handles the Hotfix defect gate and exposes a `DeployHotfix` entry.
103
+ - The merge to `_production` runs from the worker with **no human at the merge moment** — the
104
+ guard chain (task type + status + all-defects-reviewed + no-show-stopper + deploy-claim + lock)
105
+ makes that safe. The actual prod merge goes through `MergeTaskToProduction` — see
106
+ [QA/QC branch automation](./qa-qc-branch-automation.md).
107
+
108
+ ### Stage cron (`_Worker_Clickup_StageBatch`)
109
+
110
+ - The **Wed 4:30pm Central** batch (`'30 16 * * 3'`, seeded by
111
+ `Core/2026-09-09a - Insert StageBatch CronJob.sql`) that ships **"To Deploy"** tasks to production.
112
+ - `Process` loops `Team.Tasks` "to deploy" rows and dispatches **one `DeployTask` per task**, so
113
+ each stays under the 300s worker cap and a re-run **resumes via the deploy-claim** (no double
114
+ deploy). `DeployTask` ships via `MergeTaskToProduction` then the shared finalize
115
+ (`markProductionDeployed` + `releaseSubEnvironment`).
116
+ - Replaces the **retired** legacy status-driven prod-merge (the old `to deploy` / `hotfix review`
117
+ switch cases in `Worker/Clickup.php`).
118
+
119
+ ### Feature flow (`_Worker_Clickup_FeatureReview`)
120
+
121
+ - A large **Feature** is reviewed and deployed **as one unit**: it is **one feature branch**, with
122
+ PRs keyed by the **feature** custom_id; **subtasks are review-only (no code)**.
123
+ - 5 phases: DevFinished QA-entry; UI + FE roll-ups; BE roll-up → QC; QC-defect + Client-review
124
+ roll-ups. Each phase advances the **feature** only when **all subtasks** clear that gate.
125
+ - Runs under a **per-feature `GET_LOCK`** on the feature custom_id with a **fresh-in-lock status
126
+ re-fetch**, so two sibling subtask reviews can't double-advance.
127
+ - `QaReview` / `QcReview` **skip** a Feature task or a Feature subtask (via a `parentIsFeature`
128
+ check) so `FeatureReview` owns them; `StageBatch` ships a Feature as one feature branch and
129
+ finalizes its subtasks (and skips subtasks in the batch scan).
130
+ - The feature's own **BE Review is a MANUAL field for now** (jcardinal + CTO decision).
66
131
 
67
132
  ## Gotchas
68
133
 
@@ -71,12 +136,20 @@ code triggered when a task *left* a status; the QA/QC entry must be on entering
71
136
  - **The unit-test gate is a stub (`runUnitTests()` returns true).** It does not block anything yet.
72
137
  - **Custom-field option VALUES are resolved at runtime, IDs are constants** — see
73
138
  [ClickUp custom-field conventions](./clickup-custom-field-conventions.md).
139
+ - **The automation only fires inside the "(TEST) True Dev Sprints" folder.** `isTaskInQaQcScope`
140
+ gates the fan-out, `handleDevelopmentFinished`, and `QcBatch`. A task outside that folder is
141
+ ignored — verify the folder before expecting the flow to run.
142
+ - **A Feature advances only when ALL subtasks clear a gate** — a single lagging subtask holds the
143
+ whole feature. Subtasks carry no code; only the feature branch does.
144
+ - **`_underscore CLICK_UP_CUSTOM_FIELD_ID__CLIENT_REVIEW` was repointed** to the "(TEST) True Dev
145
+ Sprints" folder's field (`2c4ab51a-…`); all field ids were verified against that folder.
74
146
 
75
147
  ## Known security gaps (discovered, not yet fixed — separate tickets)
76
148
 
77
- - **ClickUp and GitHub webhooks are NOT signature-verified today.** Verification must live at the
78
- **ingestion Lambda over the raw request body** — the worker only ever sees a **transformed**
79
- payload and cannot re-verify a signature. Do not try to add verification in the worker.
149
+ - **ClickUp and GitHub webhooks are NOT signature-verified today.** Verification (incl. the GitHub
150
+ HMAC check) must live at the **ingestion Lambda over the raw request body** — the worker only
151
+ ever sees a **transformed** payload and cannot re-verify a signature. Do not try to add
152
+ verification in the worker.
80
153
  - **`_Component_Api_Clickup::ACCESS_TOKEN` is a hardcoded, committed ClickUp token.** It must be
81
154
  **rotated and moved to an environment variable**. (Only the location is recorded here — never the
82
155
  value.) See also [ClickUp credential rotation](../workflows/clickup-credential-rotation.md).
@@ -84,6 +157,16 @@ code triggered when a task *left* a status; the QA/QC entry must be on entering
84
157
  separate ticket to escape/cast them.
85
158
 
86
159
  ## Change history
160
+ - 2026-09-09 — Added the remaining flows (draft, on `feature-qa-qc`, not deployed): **Hotfix**
161
+ (QaReview branches by Task Type → QC-Hotfix; QcReview `DeployHotfix`), **Stage cron**
162
+ (`_Worker_Clickup_StageBatch`, Wed 4:30pm Central, one `DeployTask` per task, resumes via
163
+ deploy-claim; retired the legacy `to deploy`/`hotfix review` switch cases), **Feature** roll-up
164
+ (`_Worker_Clickup_FeatureReview`, one feature branch keyed by feature custom_id, subtasks
165
+ review-only, per-feature GET_LOCK + fresh-in-lock re-fetch), and **BE auto-approve from PR**
166
+ (`Github.php` `pull_request_review` → `BeReview::FromPr`; all `_production` PRs approved →
167
+ Approved; `PullRequests.isApproved`). Scoped the whole automation to the "(TEST) True Dev
168
+ Sprints" folder (`isTaskInQaQcScope`); repointed CLIENT_REVIEW field; QC entry sets
169
+ Environment `QC-<letter>`; UI Review N/A advances. (jcardinal)
87
170
  - 2026-09-08 — Initial (draft, on `feature-qa-qc`, not deployed): new QA chain (`_Worker_Clickup_QaReview`,
88
171
  UI→FE→BE, approve advances / deny → Rework+revert), QC batch (`_Worker_Clickup_QcBatch`, weekday
89
172
  4:30pm Central, QA-Approved → QC-Task, skips while QC busy) and QC defect/client review
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.789",
3
+ "version": "1.0.790",
4
4
  "description": "TOGA Technology Team Claude Knowledge System — shared AI coding harness with skills, knowledge base CLI, and project installer for Claude Code.",
5
5
  "keywords": [
6
6
  "claude",