toga-ai 1.0.1200 → 1.0.1202

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.
@@ -30,7 +30,7 @@ How BitStorm posts PC scan results to an ODP quote, why one failure wipes the wh
30
30
  ## How it works
31
31
 
32
32
  - `api.php` ~229 wraps **every** route in `App_Database::beginTransaction()`. Any fatal → HTTP 500 → the Device and Diagnostics rows roll back too.
33
- - Results document → `Document::save()` → s3fs mount write (`api` has no AWS SDK; see the no-SDK fallback in [App_Cloud](../../library/features/app-cloud-aws-credentials.md)).
33
+ - Results document → `Document::save()` → s3fs mount write (`api` has no AWS SDK; see the no-SDK fallback in [App_Cloud](../../library/features/app-cloud-aws-credentials.md)). Mount missing or short write → throw → 500 + full rollback, so nothing half-saved.
34
34
 
35
35
  ## Gotchas
36
36
 
@@ -46,4 +46,5 @@ How BitStorm posts PC scan results to an ODP quote, why one failure wipes the wh
46
46
  4. Compare failing vs passing posts with `JSON_EXTRACT` on `Logs.API.requestPayload`.
47
47
 
48
48
  ## Change history
49
+ - 2026-10-29 — Document save fails closed (unmounted s3fs / short write) (TRUE-83311) (snaredla)
49
50
  - 2026-10-29 — Created: no-SDK document save fixes 500 + rollback of diag data; api debug recipe; open ACL risk (TRUE-83311) (snaredla)
@@ -15,6 +15,7 @@ files:
15
15
  - toga/ebs/register_instance_to_shared_application_load_balancer.php
16
16
  - tools/ebs/check_s3fs.php
17
17
  - library/app/model.php
18
+ - library/app/model/toga/document.php
18
19
  - togadesk/ebs/check_s3fs.php
19
20
  - togadesk/ebs/register_instance_to_shared_application_load_balancer.php
20
21
  - togadesk/.ebextensions/020_setup_git_libraries.config
@@ -80,7 +81,7 @@ CodePipeline `Worker` (502, us-west-2) sources `_production` of **both** `agilan
80
81
  - **Testing gotcha:** after one passing run, `databaseReadHost.txt` is fresh for 30-60 s, so a control run right after also passes. Wait > 60 s (or delete the cache file) before the control.
81
82
  - store: fixed on branch (TRUE-82856, ae1861f4f — same pins plus aws-crt-php 1.2.7, psr/http-client 1.0.3, polyfill-mbstring 1.31.0; verified on PHP 7.2.33); needs merge + deploy. Its `.ebextensions/015_install_composer.config` already runs `composer install --no-dev`.
82
83
  - **Missed by the audit (TRUE-82935): the 1.0 `api` repo** (no composer at all) and **togadesk's email cron** (`crons/tickets.php` loads only `desk/vendor/autoload.php`; the root togadesk composer with aws is not loaded there). Both stopped `App_Cloud`: [Talos ticket API](../../api/features/talos-ticket-endpoint.md), [email intake](../../togadesk/features/email-to-ticket-intake.md). Audit per **entry point**, not per repo: a CLI cron or sub-app can load a different autoloader than the web app.
83
- - **`App_Model_Toga_Document::save()` has a no-SDK fallback (TRUE-83311).** If `!class_exists('Aws\S3\S3Client')` it writes to `storage_folder` + the same `/togadocuments-<env>/<clientId>/<id>` path (`storage_folder` = s3fs mount of `asifiles`) instead of `App_Cloud::copyFileToS3`. SDK apps (toga, togadesk, worker, togaview) unchanged; api, vision, store, worker1.5, compass take the mount path. The library autoloader returns `false` on a `class_exists` miss, so the check is safe. Caller: [BitStorm diagnostic endpoint](../../api/features/bitstorm-order-diagnostic-endpoint.md).
84
+ - **`App_Model_Toga_Document::save()` has a no-SDK fallback (TRUE-83311).** If `!class_exists('Aws\S3\S3Client')` it writes to `storage_folder` + the same `/togadocuments-<env>/<clientId>/<id>` path (`storage_folder` = s3fs mount of `asifiles`) instead of `App_Cloud::copyFileToS3`. SDK apps (toga, togadesk, worker, togaview) unchanged; api, vision, store, worker1.5, compass take the mount path. The library autoloader returns `false` on a `class_exists` miss, so the check is safe. **Fails closed:** throws `Storage folder is not mounted` when `storage_folder` has the same `stat` device as its parent (dropped s3fs mount = plain local folder, writes never reach S3); writes with `fopen`/`fwrite`/`fclose` and throws unless every byte is written and `fclose` succeeds (s3fs uploads on close). An `fopen` failure raises a warning that `App_Error` turns into exit before the throw — still a failed request. Caller: [BitStorm diagnostic endpoint](../../api/features/bitstorm-order-diagnostic-endpoint.md).
84
85
  - The missing class throws **`Error`, not `Exception`** — `catch (Exception)` around an App_Cloud call does not catch it; use `\Throwable` where a fallback is meant.
85
86
  - Not changed on TRUE-82856: walmarttechservices — GitHub repo `agilantsolutions/walmarttechservices` no longer exists ("Repository not found", checked 2026-10-16); webhook — reported no longer active by the developer (2026-10-16). Removal / deprecation is left to the owners.
86
87
  - Verify assume-role in CloudTrail (`AssumeRole` on `WorkloadsRuntime`, by session name: `library-app-cloud`, `setup-git-libraries`, `register-instance`, `worker-deploy`).
@@ -88,6 +89,7 @@ CodePipeline `Worker` (502, us-west-2) sources `_production` of **both** `agilan
88
89
  - Every long-lived key still in code across repos (SES SMTP, s3fs, ALB scripts, other accounts): [audit 2026-10-13](../../../../2.0/apps/worker2/features/cross-account-aws-access.md#long-lived-keys-still-in-code-audit-2026-10-13).
89
90
 
90
91
  ## Change history
92
+ - 2026-10-29 — no-SDK document save fails closed on unmounted folder / short write (TRUE-83311) (snaredla)
91
93
  - 2026-10-29 — `App_Model_Toga_Document::save()` falls back to the s3fs mount when the SDK is missing (TRUE-83311) (snaredla)
92
94
  - 2026-10-23 — walmart-activate added aws-sdk-php; moved-app check + read-host cache testing gotcha (TRUE-83161) (rgirish)
93
95
  - 2026-10-22 — Leaked key was abused (Bedrock LLM-jacking, GuardDuty, TRUE-82983) (jcardinal)
@@ -11,6 +11,7 @@
11
11
  | [_ApiRequest — JSON encode/decode & api-logging behavior](features/apirequest-json-content-type.md) | `_ApiRequest`, the 2.0 outbound HTTP client — JSON encode/decode, retry, and api-logging traps; open before calling it or reading `Logs.Api`. |
12
12
  | [Assortment Name Translation (AssortmentTranslations sidecar)](features/assortment-name-translation.md) | Serves Assortment names in multiple languages via an `AssortmentTranslations` sidecar table on the metadata-driven translation layer; open when translating asso |
13
13
  | [Asynchronous Query Execution (writes-only, via Worker)](features/async-query-execution.md) | Run a slow WRITE asynchronously via the Worker tier so a long request write cannot hold a stale connection and hit "MySQL server has gone away"; open before usi |
14
+ | [Aurora MySQL binlog on the 2.0 clusters — current settings, who reads it, and what a change costs](features/aurora-binlog-configuration.md) | Binlog state of the prod and non-prod 2.0 Aurora MySQL clusters, the us-east-1 vs us-west-2/eu-west-1 parameter group mismatch, proof nothing reads the binlog, |
14
15
  | [Record numbering (FIELD_AUTOINCREMENT: per-client sequential numbers from RecordNumbers)](features/autoincrement-record-numbering.md) | ORM record numbers (`SA139197`, `AJ100000`, `CL146`) counted in order per client from a `RecordNumbers` table; open when adding a numbered model/prefix, debuggi |
15
16
  | [Calculated-column filter options (`<field>FilterOptions` model static → table meta)](features/calculated-column-filter-options.md) | Lets a calculated (`FIELD_SQL`) table column supply its own filter dropdown options via a `<field>FilterOptions` model static; open when adding a data-driven co |
16
17
  | [FIELD_SQL calculated fields — the underscore-prefix + same-name-method contract](features/calculated-sql-fields.md) | A `FIELD_SQL` (calculated) field on a `_Model` is bound by a **two-part contract that `_Model` enforces by throwing at model-construction time**, not by convent |
@@ -0,0 +1,82 @@
1
+ ---
2
+ title: Aurora MySQL binlog on the 2.0 clusters — current settings, who reads it, and what a change costs
3
+ framework: "2.0"
4
+ repo: _underscore
5
+ project: _Underscore
6
+ client: shared
7
+ type: feature
8
+ status: active
9
+ updated: 2026-10-29
10
+ owners: ["rgirish"]
11
+ files: []
12
+ related:
13
+ - ../architecture.md
14
+ - ../../../../1.0/apps/worker1.5/features/database-backups.md
15
+ ---
16
+
17
+ Binlog state of the prod and non-prod 2.0 Aurora MySQL clusters, the us-east-1 vs us-west-2/eu-west-1 parameter group mismatch, proof nothing reads the binlog, and why a binlog_format change needs a writer reboot (outage); open before touching any binlog parameter or planning CDC/replication off the 2.0 databases.
18
+
19
+ ## Summary
20
+
21
+ Prod has binlog ON (`STATEMENT`, enhanced binlog) on core/client/archive/logs, but **nothing reads it** (checked 2026-10-29, TRUE-83342). `binlog_format` is a **static** parameter: changing it needs a **writer reboot**, and every prod cluster has **one instance only**, so the reboot is a real write outage for that family. The same-named parameter group **differs by region** — change all 3 regions together.
22
+
23
+ ## How it works
24
+
25
+ ### Prod (account 654654170868, primary us-east-1)
26
+
27
+ - 5 Aurora MySQL Global Databases, engine `8.0.mysql_aurora.3.08.2`: `production-{core,client,archive,logs,cache}-global`.
28
+ - Writer cluster `production-<x>-1` (us-east-1); secondaries `-2` (us-west-2), `-3` (eu-west-1).
29
+ - **Each cluster has exactly 1 instance** (`production-<x>-1-i01`). No in-region reader, no in-region failover target.
30
+ - Global Database replicates at the **storage layer**, not via binlog. Binlog is not needed for the secondaries.
31
+
32
+ | Cluster | Cluster parameter group | Binlog |
33
+ |---|---|---|
34
+ | core, client, archive, logs | `true-rds-cluster-parameters` | ON |
35
+ | cache | `default.aurora-mysql8.0` | OFF |
36
+
37
+ `true-rds-cluster-parameters` values per region:
38
+
39
+ | Parameter | us-east-1 (writers today) | us-west-2 and eu-west-1 |
40
+ |---|---|---|
41
+ | `binlog_format` | `STATEMENT` | `STATEMENT` |
42
+ | `aurora_enhanced_binlog` | `1` | off |
43
+ | `binlog_backup` | `0` | `1` |
44
+ | `binlog_replication_globaldb` | `0` | `1` |
45
+ | `binlog_row_image` | `MINIMAL` | not checked |
46
+
47
+ Live check on us-east-1 writers: `log_bin = ON`.
48
+
49
+ ### Non-prod (account 975050298201, us-east-1)
50
+
51
+ - 19 single-instance clusters (`sandbox-dev`, `sandbox-client`, `stage`, `demo`, `client-*`, `qa-*`, `qc-*`), engine `3.10.3`.
52
+ - All on `true-rds-cluster-parameters` with `binlog_format = OFF` (`log_bin = 0`). No Global Database.
53
+
54
+ ### Who reads the binlog (2026-10-29: nobody)
55
+
56
+ - No `Binlog Dump` threads on prod core/client/archive/logs writers (the login sees `rdsadmin` threads, so the processlist is complete).
57
+ - Only `rdsadmin` and `rds_superuser_role` hold `REPLICATION SLAVE` / `REPLICATION CLIENT`.
58
+ - No RDS zero-ETL integrations and no binlog replica clusters in us-east-1, us-west-2, eu-west-1.
59
+ - **Not checked:** AWS DMS — SSO role `GoAgilant-Developers` gets AccessDenied on `dms:Describe*`. The processlist check is one point in time.
60
+
61
+ ### Changing a binlog parameter
62
+
63
+ 1. Re-run the reader checks below first (a reader may have appeared).
64
+ 2. Change the parameter in `true-rds-cluster-parameters` in **all 3 regions** (us-east-1, us-west-2, eu-west-1).
65
+ 3. `binlog_format` (and other `ApplyType = static` parameters) leave the cluster `pending-reboot` until the writer reboots.
66
+ 4. Reboot each writer in a window. Estimate ~30-60 s per writer, maybe longer: with binlog ON, binlog recovery runs at startup (enhanced binlog shortens it). Secondaries keep serving reads during the primary reboot. No real reboot timing exists (no reboot events in the last 14 days); a non-prod test gives only a lower bound because binlog is off there.
67
+
68
+ ### Read-only checks
69
+
70
+ - Static vs dynamic: `aws rds describe-db-cluster-parameters --db-cluster-parameter-group-name true-rds-cluster-parameters --region <r>` → `ApplyType` column.
71
+ - Binlog readers (toga-db): `SELECT * FROM information_schema.PROCESSLIST WHERE COMMAND LIKE 'Binlog Dump%'`.
72
+ - Replication grants: `SELECT * FROM information_schema.USER_PRIVILEGES WHERE PRIVILEGE_TYPE LIKE 'REPLICATION%'`.
73
+ - Zero-ETL: `aws rds describe-integrations --region <r>`.
74
+
75
+ ## Gotchas
76
+
77
+ - **Region mismatch:** after a Global Database failover, the new writer (us-west-2 or eu-west-1) runs plain, non-enhanced binlog with `binlog_backup = 1`. Settings silently change on failover unless all 3 regions match.
78
+ - **Reboot = outage:** one instance per cluster, so rebooting `production-<x>-1-i01` stops writes for that whole family.
79
+ - Binlog ON with no reader only costs write overhead and storage; turning it off is safe today only if the reader checks are still empty.
80
+
81
+ ## Change history
82
+ - 2026-10-29 — First version: prod/non-prod binlog state, region mismatch, no readers found, static-parameter reboot cost (TRUE-83342) (rgirish)
@@ -22,7 +22,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
22
22
 
23
23
  ## 2.0 framework
24
24
 
25
- - **_underscore** (_Underscore) _(framework core)_ — 117 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
25
+ - **_underscore** (_Underscore) _(framework core)_ — 118 doc(s) → [2.0/apps/_underscore/INDEX.md](2.0/apps/_underscore/INDEX.md)
26
26
  - **worker2** (Worker) — 102 doc(s) → [2.0/apps/worker2/INDEX.md](2.0/apps/worker2/INDEX.md)
27
27
  - **api2** (API) — 29 doc(s) → [2.0/apps/api2/INDEX.md](2.0/apps/api2/INDEX.md)
28
28
  - **dbchanges2** (Database Changes) _(framework core)_ — 24 doc(s) → [2.0/apps/dbchanges2/INDEX.md](2.0/apps/dbchanges2/INDEX.md)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.1200",
3
+ "version": "1.0.1202",
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",