toga-ai 1.0.511 → 1.0.512

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.
@@ -364,6 +364,18 @@ in `_underscore` and `library` in the **same** release, and the `/errors` consol
364
364
  `dbchanges2/Logs_Client/2026-08-01a - Drop Error table.sql`. Do not reintroduce it.
365
365
  - **Shared-schema migration collision.** Because these tables live in the *shared* Core Logs
366
366
  DB, only **one** migration may `CREATE` them; later migrations only `ALTER`.
367
+ - **The `dbchanges2/Logs/` migration files LAG the deployed schema — read the live cluster, not the
368
+ migrations.** `dbchanges2/Logs/2026-07-30a - Error reporting Issues and Events.sql` does **not**
369
+ describe the live `Logs.Issue`: notably the identity column is **`issueKey` (varchar 128)**, not
370
+ `code`. Live columns include `reference`, `dtLastOccurred`, `isManaged`, `urgency`,
371
+ `minimumUrgency`, `consecutiveQuietWindows`, `subject`, `errorMessage`, `occurrences`,
372
+ `totalOccurrences`, `recurrenceCount`, `dtLastNotified`, `notificationCount`, `dtAcknowledged`,
373
+ `dtMutedUntil`, `createsClickupTask`, `clickupPriority`, `clickupAssigneeId`. Query
374
+ `information_schema` (or `SHOW TABLES` / `SHOW COLUMNS`) against the live Logs cluster **before**
375
+ writing any SQL against this feature — reading the migrations instead produced confidently wrong
376
+ conclusions twice on 2026-08-04. Same trap for the **singular** table names
377
+ (`Issue`/`Event`/`IssueFingerprint`/`IssueAreaOwner`/`IssueClickupTask`/`IssueEmailAddress`,
378
+ renamed by `2026-08-01a` and confirmed applied in prod).
367
379
  - **Pre-existing committed secrets in this area (not fixed — out of scope, report only).**
368
380
  A ClickUp API token at `_underscore/Component/Api/Clickup/Clickup.php:5`; SES SMTP
369
381
  credentials at `_underscore/Email.php:11-12`; a named individual's Sentry personal access
@@ -418,6 +430,12 @@ clientUserId). **Neither was built.** As built instead:
418
430
 
419
431
  ## Change history
420
432
 
433
+ - 2026-08-04 — **Correction/diagnostic:** recorded that the `dbchanges2/Logs/` migration files lag
434
+ the deployed schema — `2026-07-30a` describes a `code` identity column, but live `Logs.Issue` is
435
+ keyed on **`issueKey` (varchar 128)** — and listed the live column set. Query
436
+ `information_schema` against the live Logs cluster before writing SQL here; trusting the
437
+ migrations (and forgetting the applied singular rename) produced two confidently wrong
438
+ conclusions in one session. No code change. (dfranks)
421
439
  - 2026-08-04 (later, **uncommitted/undeployed** at time of writing) — **Reference encoding reworked
422
440
  to base 32** over `'0123456789ACDEFGHJKMNPQRSTUVWXYZ'` (all digits kept; `O`/`I`/`L`/`B` dropped
423
441
  as impersonators of `0`/`1`/`1`/`8`), replacing the base-26 decimal-counter+letter scheme, with
@@ -7,7 +7,7 @@ client: shared
7
7
  type: feature
8
8
  status: active
9
9
  updated: 2026-08-04
10
- owners: ["jcardinal"]
10
+ owners: ["jcardinal", "dfranks"]
11
11
  files:
12
12
  - worker2/Worker/Infrastructure/Errors.php
13
13
  - worker2/Worker/Notification/Email.php
@@ -28,6 +28,7 @@ related:
28
28
  - ./clickup-project-routing.md
29
29
  - ./notification-email.md
30
30
  - ./notification-email-template.md
31
+ - ../../../clients/compass-usa/features/mits-sales-order-transmission-alerting.md
31
32
  ---
32
33
 
33
34
  ## Summary
@@ -263,6 +264,22 @@ this controller needs the same treatment.**
263
264
  issue gets a **neutral** subject rather than another client's raw error text.
264
265
  - **`IssueEmailAddress.clientId = 0` means "all clients"** and requires an explicit
265
266
  confirmation flag in the Tools console; list views render it as **"ALL CLIENTS"**.
267
+ - **A recipient scoped to a specific `clientId` delivers NOTHING for occurrences recorded without
268
+ client attribution.** `loadRecentClientIds()` maps an occurrence whose `clientId` is NULL to
269
+ **`0`**, and `resolveRecipientsForClient()` resolves scope `0` **plus** the erroring client. So
270
+ the rule is: scope to **`0`** when the `issueKey` is raised from a **single client-specific code
271
+ path** (a Compass-only cron, say); **never** scope to `0` for an `issueKey` raised from shared
272
+ code, which would leak one client's alerts to another's recipients.
273
+ - **Configuring a recipient is never retroactive.** `shouldNotify()` notifies on first occurrence
274
+ (`notificationCount` 0), on escalation, or when the backed-off reminder interval has elapsed —
275
+ and returns **false when the current window has zero events**. The first email therefore lands on
276
+ the **next live occurrence**, not on the backlog. Do not read silence right after a config change
277
+ as a failure.
278
+ - **Adding a business recipient is purely additive — it cannot switch ClickUp ticketing off.**
279
+ Routing is **both**, not either: `if ($recipients !== null)` emails the business recipients and
280
+ `if ($issue->createsClickupTask)` tickets the dev team, evaluated **independently**. The in-code
281
+ comment marking this records the earlier `elseif` form, where adding one recipient silently
282
+ disabled an issue's dev-team ticket.
266
283
  - **The ClickUp webhook has no HMAC signature verification** (pre-existing, unfixed). A forged
267
284
  POST can mark issues acknowledged — freezing the neglect axis — or resolve episodes. That is
268
285
  alert suppression against the error-reporting system itself. Fix before relying on this
@@ -273,6 +290,15 @@ this controller needs the same treatment.**
273
290
 
274
291
  ## Change history
275
292
 
293
+ - 2026-08-04 (verified against `origin/_production` + the prod Logs cluster) — Recorded the
294
+ **recipient-routing semantics** a developer needs before configuring a business alert: routing is
295
+ **both** business email and dev-team ClickUp, evaluated independently (adding a recipient is
296
+ purely additive); `IssueEmailAddress.clientId` scoping means a client-scoped row delivers nothing
297
+ for occurrences with NULL `clientId` (mapped to `0`), so single-client `issueKey`s scope to `0`
298
+ and shared-code `issueKey`s never do; and `shouldNotify()` makes configuration
299
+ **non-retroactive** — the first email lands on the next live occurrence. Also noted that prod
300
+ `Logs.IssueEmailAddress` was still empty, making Compass's MITS rejection the platform's first
301
+ business-routed issue. No code change. (dfranks)
276
302
  - 2026-08-04 (later, **uncommitted/undeployed** at time of writing) — **Fixed: escalation email had
277
303
  never been sent, ever**, for two independent reasons. (A) `processTechnicalIssue()` returned early
278
304
  when the ClickUp task would read identically, and that return sat *above* the `if ($shouldNotify)`
@@ -39,7 +39,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
39
39
  - **togatech** (TOGA Technology Website) — 4 doc(s) → [standalone/apps/togatech/INDEX.md](standalone/apps/togatech/INDEX.md)
40
40
  - **websocket** (WebSocket Server) — 2 doc(s) → [standalone/apps/websocket/INDEX.md](standalone/apps/websocket/INDEX.md)
41
41
  - **forward** (Forwarder) — 3 doc(s) → [standalone/apps/forward/INDEX.md](standalone/apps/forward/INDEX.md)
42
- - **claude** (Claude Harness) — 3 doc(s) → [standalone/apps/claude/INDEX.md](standalone/apps/claude/INDEX.md)
42
+ - **claude** (Claude Harness) — 4 doc(s) → [standalone/apps/claude/INDEX.md](standalone/apps/claude/INDEX.md)
43
43
 
44
44
  ## Clients
45
45
 
@@ -8,6 +8,7 @@
8
8
  | [Compass: Item-Fulfillment TableViews (for-sales-order-items & for-sales-orders, tracking via bridge)](features/item-fulfillment-tracking-tableview.md) | 2.0 | Two sibling Compass TableViews in `Client_Compass` display fulfilled items in toga2-supply, both driven by `TableViews` / `TableViewJoins` / `TableViewFields` c | dbchanges2/Client_Compass/2026-06-10 - ItemFulfillmentsForSalesOrderItemsTableView.sql, dbchanges2/Client_Compass/2026-06-11 - ItemFulfillmentsForSalesOrdersTableView.sql, dbchanges2/Client_Compass/2026-06-15a - FixItemFulfillmentTrackingNumberJoins.sql, dbchanges2/Client/2026-07-15a - ExcludeFeeItemsFromItemFulfillmentsForSalesOrdersView.sql |
9
9
  | [Compass MITS PO → SO Item Linking](features/mits-po-to-so-item-linking.md) | 2.0 | MITS sends Compass inbound Purchase Orders (`POST /v2/purchase-orders`) against a Sales Order (`mitsSalesOrder`). | _underscore/Model/Compass/PurchaseOrder.php, worker/crons/toga2/compass/workflow/3a_import_office_depot_purchase_orders.php |
10
10
  | [Compass MITS PO Transmission to Vendors](features/mits-po-transmission-to-vendors.md) | 2.0 | The 1.0 worker cron `2_transmit_mits_purchase_orders_to_vendors.php` transmits Compass PurchaseOrders to their vendors (Office Depot, Strategic Systems, Compass | worker/crons/toga2/compass/workflow/2_transmit_mits_purchase_orders_to_vendors.php, worker/crons/toga2/compasscanada/workflow/2_transmit_mits_purchase_orders_to_vendors.php, library/app/client/compass.php |
11
+ | [Compass MITS Sales-Order Transmission — Rejection Alerting (Issue/Event, not email-in-cron)](features/mits-sales-order-transmission-alerting.md) | 2.0 | When MITS **rejects** a Compass sales order transmitted by the 1.0 cron `1_transmit_compass_sales_orders_to_mits.php`, the alert is no longer an email built ins | worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php, worker2/Worker/Infrastructure/Errors.php, _underscore/Model/Core/Logs/Issue.php, _underscore/Model/Core/Logs/IssueEmailAddress.php, dbchanges2/Logs/2026-08-04a - MITS rejection business recipients.sql |
11
12
  | [Compass MR/MA Order Auto-Approval & Status Gate](features/mr-ma-order-approval-and-status.md) | 2.0 | Compass **MR** and **MA** sales orders are system-generated from the MITS / Office Depot EDI pipeline (they do not originate as user-entered SA orders) and must | _underscore/Model/Compass/SalesOrder.php, _underscore/Model/Compass/PurchaseOrder.php, worker/crons/toga2/compass/workflow/3a_import_office_depot_purchase_orders.php |
12
13
  | [Compass USA](profile.md) | 2.0 | Compass USA is a TOGA client running a multi-tier supply-chain commerce operation. | |
13
14
  | [Compass Cross-Kit Bundle Corruption — Detection & Repair](workflows/cross-kit-bundle-corruption.md) | 2.0 | A frontend regression in `toga2-commerce`'s edit-order bundle submission mis-attributed bundle (kit) line items and **fees/warranties** to the **wrong kit**, pe | src/api/syncSalesOrderItemsFromLocalStorageCartToApi.ts |
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: Compass MITS Sales-Order Transmission — Rejection Alerting (Issue/Event, not email-in-cron)
3
+ framework: "2.0"
4
+ project: _Underscore
5
+ client: compass-usa
6
+ type: client-feature
7
+ status: active
8
+ updated: 2026-08-04
9
+ owners: ["dfranks"]
10
+ files:
11
+ - worker/crons/toga2/compass/workflow/1_transmit_compass_sales_orders_to_mits.php
12
+ - worker2/Worker/Infrastructure/Errors.php
13
+ - _underscore/Model/Core/Logs/Issue.php
14
+ - _underscore/Model/Core/Logs/IssueEmailAddress.php
15
+ - dbchanges2/Logs/2026-08-04a - MITS rejection business recipients.sql
16
+ related:
17
+ - mits-po-transmission-to-vendors.md
18
+ - ../../../2.0/apps/worker2/features/error-escalation-cron.md
19
+ - ../../../2.0/apps/_underscore/features/error-reporting-issue-event.md
20
+ - ../../../1.0/apps/library/features/error-capture-1-0.md
21
+ ---
22
+
23
+ ## Summary
24
+
25
+ When MITS **rejects** a Compass sales order transmitted by the 1.0 cron
26
+ `1_transmit_compass_sales_orders_to_mits.php`, the alert is no longer an email built inside the
27
+ cron. It is a **business exception** raised into the shared Logs Issue/Event pipeline, and its
28
+ recipients are **rows in `Logs.IssueEmailAddress`**.
29
+
30
+ **Consequence for anyone handed a ticket like "add <person> to the MITS error emails": there is
31
+ no PHP to change.** It is a one-row data change delivered as a `dbchanges2/Logs/` migration.
32
+
33
+ ## How it works
34
+
35
+ - The cron raises
36
+ `throw new App_Exception_Business('COMPASS_SALES_ORDER_MITS_TRANSMIT_REJECTED', …, URGENCY_HIGH)`
37
+ on a MITS rejection. (Before 2026-08-03 this block was a hardcoded `new App_Email_Agilant()`
38
+ with `addTo('devteam@togatech.com')`.)
39
+ - Capture creates/dedupes a `Logs.Issue` keyed on the `issueKey`, and the worker2
40
+ `Infrastructure/Errors/Escalate` cron does all outbound notification — business email to the
41
+ configured recipients **and**, independently, the dev-team ClickUp task. See
42
+ [error-escalation-cron](../../../2.0/apps/worker2/features/error-escalation-cron.md).
43
+ - Recipients live in `Logs.IssueEmailAddress` (FK `issueId` → `Logs.Issue`), scoped by
44
+ `clientId` (`0` = all clients).
45
+
46
+ ### Adding a recipient (the correct pattern)
47
+
48
+ Write a `dbchanges2/Logs/YYYY-MM-DD<letter>` migration that:
49
+
50
+ 1. **Looks the issue up by `issueKey`**, never by its `id`. The id is assigned on the issue's
51
+ **first occurrence** and is therefore not stable across environments.
52
+ 2. Uses **`clientId = 0`**. This `issueKey` is raised from a Compass-only code path, and an
53
+ occurrence recorded without client attribution resolves against scope `0` only — a row scoped
54
+ to the Compass `clientId` can deliver nothing. (Never use `0` for an `issueKey` raised from
55
+ shared code — that is a cross-tenant leak.)
56
+ 3. Is **idempotent** via `INSERT … WHERE NOT EXISTS`, mirroring the unique key
57
+ `uq_issue_client_address_type`.
58
+
59
+ Configuration is **never retroactive**: `shouldNotify()` fires on the first occurrence, on
60
+ escalation, or when the backed-off reminder interval elapses, and returns false for a window with
61
+ zero events. The first email lands on the **next live rejection**, not on existing history.
62
+
63
+ ## Gotchas / known issues
64
+
65
+ - **Do not "modernize" this alert back into the cron.** Migrating it to
66
+ `_Model_Client_EmailTemplate::send` (or any in-cron email) reverts the move to the Issue/Event
67
+ pipeline and removes the recipient configuration surface entirely.
68
+ - **Never re-introduce the payload dump into the alert.** The original email included the
69
+ transmission payload, which carries ship-to addressee, attention line, street address and phone
70
+ number. The Issue message is stored in a table **shared across every client**, displayed to
71
+ internal staff in the Tools `/errors` console, pushed to ClickUp, and emailed — so the payload
72
+ was deliberately removed. Alerts here name the order, not the person.
73
+ - **The MITS cron holds its API credentials inline in the file.** Treat that file as
74
+ secret-bearing when copying snippets anywhere (tickets, PR bodies, knowledge docs).
75
+ - **Adding a recipient does not turn ClickUp ticketing off.** Routing is both-and, not
76
+ either-or — see the escalation-cron doc for the `elseif` bug this used to be.
77
+ - As of 2026-08-04 prod `Logs.IssueEmailAddress` is empty, so this is the **first business-routed
78
+ issue on the platform**: `processBusinessIssue()` will execute in production for the first time
79
+ when this issue next fires. Watch that run rather than assuming it works.
80
+
81
+ ## Change history
82
+ - 2026-08-04 — Documented that MITS rejection alerting moved (worker `5521854b`, 2026-08-03) from a
83
+ hardcoded in-cron `App_Email_Agilant` to `App_Exception_Business` +
84
+ `Logs.IssueEmailAddress` recipients, so adding an alert recipient is a data change, not a code
85
+ change. Recorded the deliberate removal of the PII-bearing payload dump from the alert, the
86
+ look-up-by-`issueKey` / `clientId = 0` / `NOT EXISTS` migration pattern, and that recipient
87
+ configuration only takes effect on the next live occurrence. (dfranks)
88
+ </content>
89
+ </invoke>
@@ -16,10 +16,11 @@ project: _Underscore
16
16
  client: compass-usa
17
17
  type: profile
18
18
  status: active
19
- updated: 2026-07-16
20
- owners: [jcardinal, bala, tcox, apeterson]
19
+ updated: 2026-08-04
20
+ owners: [jcardinal, bala, tcox, apeterson, dfranks]
21
21
  files: []
22
22
  related:
23
+ - features/mits-sales-order-transmission-alerting.md
23
24
  - features/asn-to-item-fulfillment.md
24
25
  - features/cost-centers.md
25
26
  - features/approval-decision-flow.md
@@ -75,6 +76,10 @@ separate, related client (see its own profile).
75
76
  `worker/crons/toga2/compass/workflow/3b_import_strategic_systems_advance_shipping_notices.php`.
76
77
 
77
78
  ## Key features (this client)
79
+ - [MITS Sales-Order Transmission — Rejection Alerting](features/mits-sales-order-transmission-alerting.md)
80
+ — MITS rejection alerts are `App_Exception_Business` Issues with recipients in
81
+ `Logs.IssueEmailAddress`, **not** an email in the cron: adding an alert recipient is a
82
+ `dbchanges2/Logs/` data change with no PHP.
78
83
  - [Compass ASN → ItemFulfillment Auto-Creation](features/asn-to-item-fulfillment.md) — the
79
84
  `_Model_Compass_AdvanceShippingNotice::postPost` handler.
80
85
  - [Cost Centers (Unit Locations, numeric-only)](features/cost-centers.md) — what a Compass
@@ -5,3 +5,4 @@
5
5
  | [Harness Distribution — How a knowledge.js Fix Reaches Teammates](workflows/harness-distribution.md) | There are **two copies** of `knowledge.js` on a developer's machine, and the skills use only one of them. | claude/scripts/install.js, claude/knowledge.js |
6
6
  | [Knowledge Base Publish / Push Pipeline](workflows/knowledge-publish-pipeline.md) | How `/capture` and `/session-save` get knowledge docs from your working tree into `agilantsolutions/claude` on `_main`. | claude/knowledge.js |
7
7
  | [MCP Tool Usage — "Talos" Means the Internal Knowledge Base, and Run Your Own SELECTs](workflows/mcp-tool-usage.md) | Two MCP connections are available in every session, and **Claude is expected to reach for them on its own judgement — nobody should have to say the word "MCP".* | claude/.claude/skills/kickoff/SKILL.md, claude/.claude/skills/capture/SKILL.md |
8
+ | [Ticket-Branch Creation Safety — How /work-ticket Armed Pushes to Production Branches](workflows/ticket-branch-creation-safety.md) | For roughly a month, `/work-ticket` created ticket branches whose **git upstream was the production branch**. | claude/skills/work-ticket/SKILL.md |
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: Ticket-Branch Creation Safety — How /work-ticket Armed Pushes to Production Branches
3
+ framework: "standalone"
4
+ repo: claude
5
+ project: Claude Harness
6
+ client: shared
7
+ type: workflow
8
+ status: active
9
+ updated: 2026-08-04
10
+ owners: ["dfranks"]
11
+ files:
12
+ - claude/skills/work-ticket/SKILL.md
13
+ related:
14
+ - ./harness-distribution.md
15
+ - ../../../2.0/apps/worker2/workflows/ticket-to-pseudocode-planning.md
16
+ ---
17
+
18
+ ## Summary
19
+
20
+ For roughly a month, `/work-ticket` created ticket branches whose **git upstream was the
21
+ production branch**. Claude's own pushes were unaffected, but a developer using VS Code's
22
+ **Commit + Sync** mid-session pushed ticket code straight to `_main`/`_production` — no PR, no
23
+ review. Two such pushes landed in two days before it was found.
24
+
25
+ The mechanism is generic git behavior, so it is worth understanding beyond this one skill.
26
+
27
+ ## Root cause
28
+
29
+ Branch creation was `git checkout -b TRUE-XXXX "origin/$DEFAULT"`. Git's
30
+ **`branch.autoSetupMerge` defaults to `true`**, so branching from a *remote-tracking ref* adopts
31
+ that ref as the new branch's **upstream**. The ticket branch therefore tracked
32
+ `origin/_main` / `origin/_production` until the skill's later `git push -u` re-pointed it.
33
+
34
+ **Trigger asymmetry is why it hid.** Claude pushes with `git push -u origin <TICKET>` — an
35
+ explicit refspec, which ignores the upstream and was always safe. VS Code's Commit + Sync resolves
36
+ the destination **from the upstream**, so any developer commit made before the skill's first push
37
+ went to the production branch.
38
+
39
+ **A safety fix created the exposure.** Commit `6d155f7` (2026-07-09) moved branch creation from
40
+ *after* implementation to *before* any code is written — itself a genuine fix, because a stale
41
+ local `_production` 12 commits behind nearly reverted upstream work. But it turned a seconds-long
42
+ armed window into the **entire implementation phase**. Correctness fixes can lengthen an existing
43
+ window; check what else depends on the timing you moved.
44
+
45
+ ## The fixes
46
+
47
+ 1. **Skill:** branch creation uses **`--no-track`** *and* publishes the empty branch immediately
48
+ (`git push -u origin TRUE-XXXX`), so the branch has a correct upstream before any code exists.
49
+ The later push is a plain `git push origin <TICKET>`.
50
+ 2. **Global git config:** `branch.autoSetupMerge=simple` (a checkout can no longer adopt a
51
+ production upstream, even outside the skill) plus `push.autoSetupRemote=true`.
52
+ 3. **`pre-push` hook** in each app repo rejecting
53
+ `refs/heads/(_main|_production|_beta|_alpha|master)`, override `ALLOW_PROD_PUSH=1`. This also
54
+ catches Claude, because Claude shells out to real `git`.
55
+ 4. **Deny rules** in `.claude/settings.json`.
56
+ 5. Existing branches still tracking a production branch were **disarmed** individually.
57
+
58
+ `rework-ticket` was never affected — it checks out an existing remote branch.
59
+
60
+ ## Recovery: getting an unreviewed commit off an unprotected default branch
61
+
62
+ Do **not** force-push. Instead:
63
+
64
+ 1. **Revert via PR** on the default branch.
65
+ 2. **Rebuild the ticket branch as a NEW commit** on the post-revert base.
66
+
67
+ > **The revert-remerge trap:** if you keep the original commit and merge that branch later, the
68
+ > original commit is already an **ancestor** of the default branch, so the merge is a silent no-op
69
+ > and the change **never comes back**. The revert wins and nothing warns you.
70
+
71
+ ## Gotchas / known issues
72
+
73
+ - **Everything installed here is local and does not survive a fresh clone.** Hooks and git config
74
+ are per-machine; a teammate or a new laptop is unprotected until they redo it.
75
+ - **Standing exposure (not fixed):** `dbchanges2/_main`, `worker/_production`,
76
+ `worker2/_production` and `api2/_production` have **no branch protection and no rulesets**.
77
+ Server-side protection is the only durable fix and needs an admin GitHub account.
78
+ - **Diagnosing this class of incident:** `git reflog` on the remote-tracking branch shows
79
+ `update by push` entries — that is how both incidents were confirmed and how the other four
80
+ repos were cleared. Pre-existing `_beta` pushes are normal manual practice; check dates before
81
+ calling something an incident.
82
+ - Auditing "did this ever happen elsewhere?" requires sweeping **every** repo the skill touches,
83
+ not just the one that surfaced the bug.
84
+
85
+ ## Change history
86
+ - 2026-08-04 — Documented the `branch.autoSetupMerge` root cause, the Claude-vs-VS-Code trigger
87
+ asymmetry that hid it for a month, and the fixes (`--no-track` + immediate branch publish,
88
+ global `autoSetupMerge=simple`, per-repo `pre-push` hook, settings deny rules). Recorded the
89
+ revert-then-rebuild recovery pattern and its revert-remerge no-op trap, plus the standing lack
90
+ of server-side branch protection on four app repos. (dfranks)
91
+ </content>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.511",
3
+ "version": "1.0.512",
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",