toga-ai 1.0.1091 → 1.0.1093

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.
@@ -6,7 +6,7 @@ project: Library
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-10-19
9
+ updated: 2026-10-20
10
10
  owners: [jcardinal, mhammontree, bala, snaredla]
11
11
  files:
12
12
  - library/app/cloud.php
@@ -75,7 +75,7 @@ CodePipeline `Worker` (502, us-west-2) sources `_production` of **both** `agilan
75
75
  - `togadesk` `ebs/check_s3fs.php` + `ebs/register_instance_to_shared_application_load_balancer.php` now assume `WorkloadsRuntime` (TRUE-82718, PR #622, merged 2026-10-13); togaview fix is PR #307 (opened). The s3fs **mount** cannot assume a role — it uses the instance role directly: see [asifiles s3fs mount](../../togadesk/features/s3fs-asifiles-file-storage.md).
76
76
  - **Every 1.0 app that bootstraps `library` needs `aws/aws-sdk-php` in its own `composer.json`** (since TRUE-82705). Without it any App_Cloud call fatals `Class 'Aws\Credentials\CredentialProvider' not found`. Hidden trigger: on prod/worker/bigworker, `App_Database::getDatabaseReaderHost()` (`library/app/database.php` ~156) calls `App_Cloud::getParameter('database_reader_endpoint')` whenever its cache file `databaseReadHost.txt` is older than 30-60 s. The fatal hits before the cache is rewritten, so the cache stays stale and **every** reader-DB request fails — the app looks fully down (TRUE-82793: Vision PunchOut for Canon / S&P Global via SAP Ariba returned HTTP 500). Fix = add `"aws/aws-sdk-php": "^3.328"` and pin `composer.lock` to worker's prod versions (aws-sdk-php 3.328.1, guzzle 7.9.2, promises 2.0.4, psr7 2.7.0, jmespath 2.8.0 — PHP 7.2 safe); EB runs `composer install --no-dev` on deploy (`vendor/` is gitignored).
77
77
  - Has it (`_production`): worker, togadesk (`^3.337`), togaview, tools, toga (TRUE-82714, 63c5ed0; confirmed 2026-10-16), vision (TRUE-82793, merged + deployed 2026-10-15).
78
- - 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`.
78
+ - 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); **still unmerged on 2026-10-20** — caused the S&P Global Ariba PunchOut outage (TRUE-82959: every store page HTTP 500 at `library/app/cloud.php:127`; Guided Buying shows "Unable to connect to supplier's website"). Needs merge + deploy. Its `.ebextensions/015_install_composer.config` already runs `composer install --no-dev`.
79
79
  - **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.
80
80
  - 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.
81
81
  - 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.
@@ -84,6 +84,7 @@ CodePipeline `Worker` (502, us-west-2) sources `_production` of **both** `agilan
84
84
  - 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).
85
85
 
86
86
  ## Change history
87
+ - 2026-10-20 — store aws-sdk fix still unmerged; caused S&P Global PunchOut outage (TRUE-82959) (snaredla)
87
88
  - 2026-10-19 — aws-sdk-php audit missed `api` + togadesk email cron; `Error` not `Exception` (TRUE-82935) (jcardinal)
88
89
  - 2026-10-16 — aws-sdk-php: store fixed (TRUE-82856), vision deployed, walmarttechservices + webhook not changed (repo gone / reported inactive) (mhammontree)
89
90
  - 2026-10-15 — aws-sdk-php requirement: reader-host crash path, per-app audit, vision fixed (TRUE-82793) (mhammontree)
@@ -6,8 +6,8 @@ project: Library
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-10-13
10
- owners: ["jcardinal", "mhammontree", "bala"]
9
+ updated: 2026-10-20
10
+ owners: ["jcardinal", "mhammontree", "bala", "snaredla"]
11
11
  files:
12
12
  - library/app/error/capture.php
13
13
  - library/app/error.php
@@ -119,7 +119,7 @@ Two things are specifically 1.0:
119
119
 
120
120
  - **Looking for a 1.0 cron fatal? Query `Logs.Issue` on environment `prod`, ordered by `dtLastOccurred`.** The legacy `Logs.Errors` and `Vision_Log.ErrorLog` tables do **not** carry 1.0 cron fatals — searching them wastes time (2026-09-18, DOE outbound-cron outage). Uncaught exceptions reach here via `App_Error::handleException` → `captureException()`, which returns the short quotable reference. **A `catch` BYPASSES capture** — if you catch per record, call `App_Error_Capture::captureException($e)` yourself, and put only the returned reference (never `$e->getMessage()`, which can carry a raw vendor response body) into an email or log.
121
121
  - **Vision does not capture — use Sentry.** `vision/config.prod.ini` has no `[database_toga2logs]` section, so vision errors never reach `Logs.Issue`; only Sentry project `vision` has them. Do not search `Logs.Issue` for vision errors.
122
- - **Open, not fixed (TRUE-82793): a PHP `\Error` (e.g. class not found) breaks the Sentry path and prints the stack trace on the prod page.** `library/app/error.php` ~646 builds `ReflectionProperty('\ErrorException' or '\Exception', 'message')`; `setValue` on an `\Error` throws `Cannot access protected property Error::$message`, which hides the real error, and the catch (~653) calls `debugVar($sentryException, false)`, which prints the full trace to the client (info leak). Fix idea: use `'\Error'` when `$exception instanceof \Error`.
122
+ - **`\Error` and `\Exception` declare `$message` separately — reflect the right base class.** `App_Error::handleException` (`library/app/error.php` ~646) reflected `\Exception::$message` on a PHP `\Error` (e.g. class not found) → `Cannot access protected property Error::$message`, so the error never reached Sentry, and the catch `debugVar()`-ed the full trace onto the prod page (TRUE-82793). Fixed on library branch TRUE-82959: reflect `'\Error'` when `instanceof \Error`, else `'\Exception'`; the catch now `error_log()`s and only `debugVar()`s under `App_Registry::inDevMode()`.
123
123
  - **A `*/` inside PHP docblock prose silently closes the comment early.** Writing something like `list*/fetch*` in a `/** … */` block ends the docblock at the `*/`, and `php -l` then reports a confusing `syntax error, unexpected token` on a later line. Hit while documenting the NetSuite throw sites. Avoid the literal `*/` in docblock text.
124
124
  - **⚠ A grouped `Logs.Issue` row can show a STALE error id — read the live api2 transaction log for the current error.** Two facts combine to mislead: (1) `Event.errorMessage` is **`varchar(255)`**, so a long API response is **truncated** — often before the trailing error id; and (2) `Logs.Issue.subject` / `Issue.errorMessage` hold the **first-occurrence** text, so a long-lived issue keeps showing the error id from whenever it was first seen even after the per-call error has changed. Observed 2026-08-17: issue `3H` still displayed `EO-1` / `3G-6` (the original undefined-method fatal) while the current per-call failure was actually `EV-11` (an FK 1451 on a DELETE). **To see what is failing *now*, read the live api2 transaction log (`Logs_<client>.Api.responsePayload`) for the specific call — not the grouped `Issue` row.**
125
125
  - **Any PHP warning inside capture code would kill the request.** 1.0's `App_Error::handleError()` routes **every** PHP warning into `handleException()`, which renders the red box and calls `exit()` — so a single warning raised while capturing (an unreachable IMDS endpoint is the everyday case: `file_get_contents` warns before returning `false`) terminates the request or cron mid-run while reporting an unrelated error. 2.0's equivalent handler *throws*, which a `catch` absorbs. `captureException()` therefore sets `App_Error::setThrowExceptionsEnabled(false)` for its own duration and restores it in `finally`. This disables the **handler**, not real throws — `App_Query` raises a plain `throw new Exception` on DB errors, so genuine failures still reach the catch. **This is a general 1.0 trap for any code that must not escalate**, not just error capture.
@@ -130,6 +130,7 @@ Two things are specifically 1.0:
130
130
  - **⚠ The legacy pre-Sentry handler dumps the entire config on any error it renders.** `library/app/DELETE_DOA_PRE-SENTRY_error.php` is a dead-named but still-reachable handler whose `htmlBacktrace()` does `print_r($entry['args'])` for **every** frame. On 2026-08-05 a real error page on **https://towfoundation.togaview.com** rendered ~26 pages containing the whole config array — production DB host/user/password, SES SMTP credentials, NetSuite credentials, Payeezy API key/secret/merchant token, SSL Store token — plus ticket PII. The current `library/app/error.php` is safe (it dumps only under `App_Registry::inDevMode()`), but **both** handlers gate on `inDevMode()`, so the affected host was **evaluating as dev mode in production**. Two actions: (1) verify `inDevMode()` per host in production before trusting any error page not to leak, and (2) delete the legacy handler. Rotation of every exposed credential **was escalated to Jeff on 2026-08-05; confirmation that it was completed is still owed** — treat those credentials as compromised until confirmed. (No values are recorded here or anywhere in the KB.)
131
131
 
132
132
  ## Change history
133
+ - 2026-10-20 — Fixed `\Error` reflection + prod trace dump in `handleException` (TRUE-82959) (snaredla)
133
134
  - 2026-10-15 — Vision has no Logs capture (Sentry only); open `\Error` reflection leak in `error.php` (TRUE-82793) (mhammontree)
134
135
  - 2026-10-13 — Open issue: handler crash `App_Error_Capture not found` on tools prod hides the real error (TRUE-82662) (bala)
135
136
  - 2026-10-12 — Removed the committed-AWS-key gotcha: key deleted, `App_Cloud` assumes `WorkloadsRuntime` (TRUE-82705) (jcardinal)
@@ -6,8 +6,8 @@ project: Worker
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-10-06
10
- owners: ["jcardinal", "ajean"]
9
+ updated: 2026-10-20
10
+ owners: ["jcardinal", "ajean", "kyalamarthi"]
11
11
  files:
12
12
  - worker2/Worker/Clickup/QaReview.php
13
13
  - worker2/Worker/Clickup/QcReview.php
@@ -68,6 +68,8 @@ the QA/QC branch — see [QA/QC branch automation](./qa-qc-branch-automation.md)
68
68
  `_Worker_Clickup::handleDevelopmentFinished` is the entry to the QA chain. Fires when a task
69
69
  **enters** "Development Finished". **Moved off the legacy leaving-trigger** — the old code triggered
70
70
  when a task *left* a status; the QA/QC entry must be on entering the status.
71
+ The same `case 'development finished':` first stamps `Team.Tasks.dtDone` for every sprint task, outside
72
+ the scope check — see [Team Sprint Management](./team-sprint-management.md) (data model).
71
73
 
72
74
  ### Review-field reset on status ENTRY (`_Worker_Clickup::resetReviewFieldOnStatusEntry`)
73
75
 
@@ -221,8 +223,9 @@ Batch) QC Review → Stage or Client Review → To Deploy → **manual** deploy.
221
223
  - **`_Component_Api_Clickup::ACCESS_TOKEN` is a hardcoded, committed ClickUp token.** It must be
222
224
  **rotated and moved to an environment variable**. (Only the location is recorded here — never the
223
225
  value.) See also [ClickUp credential rotation](../workflows/clickup-credential-rotation.md).
224
- - **Pre-existing unescaped `custom_id` SQL sites** exist in `worker2/Worker/Clickup.php` — a separate
225
- ticket to escape/cast them.
226
+ - **Pre-existing unescaped SQL in `worker2/Worker/Clickup.php`** — `custom_id`, and `$taskId` (from
227
+ `$payload->task_id`) interpolated into Team SQL file-wide with no `_Database::escape()`. Separate
228
+ ticket. New SQL in this file must escape `$taskId` — do not copy the old pattern.
226
229
 
227
230
  ## Related
228
231
 
@@ -231,6 +234,7 @@ Batch) QC Review → Stage or Client Review → To Deploy → **manual** deploy.
231
234
  - [ClickUp custom-field conventions](./clickup-custom-field-conventions.md)
232
235
 
233
236
  ## Change history
237
+ - 2026-10-20 — Development Finished case now also stamps `dtDone` (moved from `ui review`); unescaped `$taskId` gap recorded (kyalamarthi; TRUE-82723)
234
238
  - 2026-10-06 — BE Review `Conflict` now routes to Rework + revert like Denied (QaReview + FeatureReview) (jcardinal)
235
239
  - 2026-10-01 — DevFinished CatchUp (cron 86); QC Batch turned on (id 75); review fields reset to Needs Review on entry; Stage deploys confirmed manual (ajean; worker2 PR #178, dbchanges2 PR #504)
236
240
  - 2026-09-25 — Scope narrowed to Dev Sprints `90116585845` (jcardinal)
@@ -6,10 +6,11 @@ project: Worker
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-10-01
9
+ updated: 2026-10-20
10
10
  owners: ["jcardinal", "kyalamarthi", "ajean"]
11
11
  files:
12
12
  - worker2/Worker/Team/Sprint.php
13
+ - worker2/Worker/Clickup.php
13
14
  - worker2/Config/production.ini
14
15
  - _underscore/Model/Team/Sprint.php
15
16
  - dbchanges2/Core/2026-09-29a - Record sprint and design CronJobs.sql
@@ -19,6 +20,7 @@ related:
19
20
  - ./clickup-work-type-automation.md
20
21
  - ./clickup-project-routing.md
21
22
  - ./clickup-general-automation.md
23
+ - ./qa-qc-review-pipeline.md
22
24
  - ./committed-secrets-and-config-debt.md
23
25
  - ../workflows/sprint-clickup-folder-repoint.md
24
26
  - ../workflows/php-runtime-upgrade-dependency-audit.md
@@ -224,6 +226,17 @@ values matter:
224
226
  `dtDone IS NOT NULL` is the Power BI "done" test used by the KPI tiles and burndown; `dtCompleted IS
225
227
  NOT NULL` is the "Complete" test used by the per-dev segment breakdown. Do not substitute one for the
226
228
  other.
229
+ - **`dtDone` is stamped on the FIRST ClickUp move to `development finished`** (since 2026-10-20,
230
+ TRUE-82723; before that it was `ui review`). Writer: the `taskStatusUpdated` webhook switch in
231
+ `Worker/Clickup.php`, `case 'development finished':` — for any task with a `sprint N` tag, **before
232
+ and outside** `isTaskInQaQcScope()`; `dtDone IS NULL` guard keeps the first time. So every
233
+ `dtDone`-based consumer (Power BI, tools `/developer`, api2 sprint Record Scripts) now counts a task
234
+ done at Development Finished. Old rows were **not** backfilled — rows stamped under the UI Review
235
+ rule keep their value. `dtCompleted` (set on `complete`) is unchanged. The comment in
236
+ `dbchanges2/Core/2026-04-30 - Team Tasks dtDone dtCompleted.sql` ("captured when task reaches UI
237
+ Review") is stale; the migration already ran — do not edit it.
238
+ - **Only that webhook sets `dtDone`.** `Capture*`, `SprintLock`, and `Clickup/DevFinished/CatchUp` do
239
+ not — a missed webhook, or a task with no `Tasks` row yet in that sprint, leaves `dtDone` NULL.
227
240
  - **`sprintPointsNow` / `sprintPointsAtLock`** — the points measured by every dashboard metric below
228
241
  use `sprintPointsNow` (current state), not the at-lock value.
229
242
 
@@ -412,9 +425,6 @@ see [TOGa Talos Sprint Dashboard API](../../api2/features/sprint-dashboard-api.m
412
425
  one map for both jobs. This pattern is replicated identically in `SprintLock()`, `CaptureSprintEnd()`,
413
426
  and `CaptureSprintDaily()` — fix all three together.
414
427
 
415
- ## Change history
416
- - 2026-09-25 — renamed product references from "TOGa IQ" to "TOGa Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
417
-
418
428
  ## Related
419
429
 
420
430
  - [Worker (worker2) Architecture](../architecture.md)
@@ -426,6 +436,7 @@ see [TOGa Talos Sprint Dashboard API](../../api2/features/sprint-dashboard-api.m
426
436
  - [Record Scripts](../../api2/features/record-scripts.md)
427
437
 
428
438
  ## Change history
439
+ - 2026-10-20 — `dtDone` now stamped on first move to `development finished`, not `ui review`; no backfill (kyalamarthi; TRUE-82723, worker2 `cc5f001`)
429
440
  - 2026-10-01 — getSprint() deterministic + null-safe; JSON run summaries; SprintEnd skips before capture; release-notes key from `[talos] api_key`; SprintLock copies/resets Condition; new ResetInProgress + scheduled warning wrappers; cron rows recorded in dbchanges2 (ajean; worker2 PR #178, #179)
430
- - 2026-09-25 — Condition write removed from SprintLock (reversed 2026-10-01) (jcardinal)
441
+ - 2026-09-25 — Condition write removed from SprintLock (reversed 2026-10-01); "TOGa IQ" → "TOGa Talos" rebrand (jcardinal)
431
442
  - 2026-09-16 — Repointed to the Dev Sprints folder; tables reset (kyalamarthi)
@@ -5,13 +5,16 @@ apps:
5
5
  - library
6
6
  - worker
7
7
  - vision
8
+ - store
8
9
  project: Worker
9
10
  client: spglobal
10
11
  type: profile
11
12
  status: active
12
- updated: 2026-10-15
13
- owners: ["jcardinal", "mhammontree"]
14
- files: []
13
+ updated: 2026-10-20
14
+ owners: ["jcardinal", "mhammontree", "snaredla"]
15
+ files:
16
+ - store/_/app/framework.php
17
+ - store/common/spglobal/welcome/get.php
15
18
  related:
16
19
  - ../../1.0/apps/worker/features/netsuite-togasupply-per-client-sync.md
17
20
  - ../../1.0/apps/library/features/app-cloud-aws-credentials.md
@@ -28,4 +31,4 @@ S&P Global TOGa-Supply NetSuite integration client on the shared 1.0 worker+libr
28
31
  ## Integration touchpoints
29
32
 
30
33
  - **`worker` / `library` (1.0)** — shared togasupply sync engine + `App_Api_Toga2` bridge.
31
- - **`vision` (1.0) — PunchOut from SAP Ariba** (same flow as Canon). Outage example + fix: TRUE-82793, see [1.0 AWS credentials](../../1.0/apps/library/features/app-cloud-aws-credentials.md#gotchas). Vision errors are in Sentry only, not `Logs.Issue`.
34
+ - **`store` (1.0) — PunchOut from SAP Ariba** (Classic Buyer + Guided Buying) lands on `spglobal.togacommerce.com`: spglobal host block in `store/_/app/framework.php`, client code in `store/common/spglobal/`. Not vision (that is Canon's flow). A store HTTP 500 shows in Guided Buying as "Unable to connect to supplier's website". Outage 2026-10-20 (TRUE-82959): store missing `aws/aws-sdk-php`, see [1.0 AWS credentials](../../1.0/apps/library/features/app-cloud-aws-credentials.md#gotchas).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.1091",
3
+ "version": "1.0.1093",
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",