toga-ai 1.0.276 → 1.0.278

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,6 +6,7 @@ _Auto-generated by `knowledge.js index`. Do not hand-edit._
6
6
 
7
7
  - **library** (Library) _(framework core)_ — 11 doc(s) → [1.0/apps/library/INDEX.md](1.0/apps/library/INDEX.md)
8
8
  - **worker** (Worker) — 13 doc(s) → [1.0/apps/worker/INDEX.md](1.0/apps/worker/INDEX.md)
9
+ - **worker1.5** (Worker 1.5) — 0 doc(s) → [1.0/apps/worker1.5/INDEX.md](1.0/apps/worker1.5/INDEX.md)
9
10
  - **togadesk** (TOGa Desk) — 8 doc(s) → [1.0/apps/togadesk/INDEX.md](1.0/apps/togadesk/INDEX.md)
10
11
  - **togaview** (TOGa View) — 6 doc(s) → [1.0/apps/togaview/INDEX.md](1.0/apps/togaview/INDEX.md)
11
12
  - **webhook** (Webhook) — 1 doc(s) → [1.0/apps/webhook/INDEX.md](1.0/apps/webhook/INDEX.md)
@@ -3,6 +3,7 @@
3
3
  | Doc | Framework | Summary | Files |
4
4
  |-----|-----------|---------|-------|
5
5
  | [Compass ASN → ItemFulfillment Auto-Creation](features/asn-to-item-fulfillment.md) | 2.0 | For Compass USA, posting an AdvanceShippingNotice (ASN) auto-creates the ItemFulfillment (IF) on the upstream SalesOrder. | _underscore/Model/Compass/AdvanceShippingNotice.php, _underscore/Model/Compass/PurchaseOrder.php, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client_Compass/2026-06-11 - AsnItemTrackingNumberAcl.sql, dbchanges2/Client_Compass/2026-06-15b - BackfillSA132781ItemFulfillmentTracking.sql, dbchanges2/Client_Compass/2026-06-16 - CleanupSA132763CrossLineTracking.sql, dbchanges2/Client_Compass/2026-06-16b - CleanupSA132743CrossLineTracking.sql, dbchanges2/Client_Compass/2026-06-16c - BackfillSA132763C40QYUCTracking.sql, dbchanges2/Client_Compass/2026-06-18a - CleanupSA132898DuplicateTracking.sql, dbchanges2/Client_Compass/2026-06-18b - CleanupSA132881DuplicateTracking.sql, dbchanges2/Client_Compass/2026-07-02a - FixSA133377TrackingSerialAndDuplicateIF.sql |
6
+ | [Cost Centers — Unit Locations, numeric-only policy](features/cost-centers.md) | 2.0 | A Compass "cost center" — the value a user picks in commerce and that lands on an order — is **not** a `CostCenters` row. | toga2-commerce/src/pages/Cart/api/CartApi.ts, worker1.5/crons/toga2/compass/import_locations.php, _underscore/Model/Compass/SalesOrder.php, api2/Component/Api/V2/V2.php, dbchanges2/Client_Compass/2026-07-06 - RemoveNonNumericCostCenters.sql |
6
7
  | [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 |
7
8
  | [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 |
8
9
  | [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, library/app/client/compass.php |
@@ -0,0 +1,115 @@
1
+ ---
2
+ title: Cost Centers — Unit Locations, numeric-only policy
3
+ framework: "2.0"
4
+ project: _Underscore
5
+ client: compass-usa
6
+ type: client-feature
7
+ status: active
8
+ updated: 2026-07-06
9
+ owners: [bala]
10
+ files:
11
+ - toga2-commerce/src/pages/Cart/api/CartApi.ts
12
+ - worker1.5/crons/toga2/compass/import_locations.php
13
+ - _underscore/Model/Compass/SalesOrder.php
14
+ - api2/Component/Api/V2/V2.php
15
+ - dbchanges2/Client_Compass/2026-07-06 - RemoveNonNumericCostCenters.sql
16
+ related:
17
+ - ../profile.md
18
+ - ../../../2.0/apps/toga2-commerce/features/cart-page-config-architecture.md
19
+ ---
20
+
21
+ ## Summary
22
+ A Compass "cost center" — the value a user picks in commerce and that lands on an order — is
23
+ **not** a `CostCenters` row. In `Client_Compass` it is a **Unit-level Location**
24
+ (`locationTypeId = 1`) identified by its **`c_erpSystemEntityId`** custom field. The
25
+ `CostCenters` table (and the `Users_CostCenters` / `Locations_CostCenters` bridges,
26
+ `SalesOrders.costCenterId`, `Users.defaultCostCenterId`) are **empty / vestigial** for Compass
27
+ and unused. As of **2026-07-06**, Compass policy is **numeric-only cost centers**: users may only
28
+ select cost centers whose `c_erpSystemEntityId` is all digits, all existing non-numeric ones are
29
+ soft-deactivated, and the import will never re-create or re-activate a non-numeric one.
30
+
31
+ This is US Compass only (`Client_Compass`). Compass Canada is explicitly out of scope.
32
+
33
+ ## How it works
34
+
35
+ ### What a cost center actually is
36
+ - A cost center = a **Unit Location** in `Client_Compass.Locations` (`locationTypeId = 1`),
37
+ keyed by the custom field **`c_erpSystemEntityId`**.
38
+ - `c_erpEntityId` is a **different** field on the Unit row (the unit id) — do not confuse the
39
+ two. At checkout the chosen cost-center value is written to **`SalesOrders.c_erpEntityId`** as a
40
+ **plain string, not a foreign key**. `_underscore/Model/Compass/SalesOrder.php` exposes a
41
+ `_costCenter` computed field.
42
+ - The `CostCenters` table is empty for Compass; nothing reads
43
+ `Users_CostCenters` / `Locations_CostCenters` / `SalesOrders.costCenterId` /
44
+ `Users.defaultCostCenterId`.
45
+
46
+ ### The commerce dropdown
47
+ - Built by **`fetchCostCenter()`** in
48
+ `toga2-commerce/src/pages/Cart/api/CartApi.ts`, which calls
49
+ `GET /locations` filtered on `c_erpSystemEntityId LIKE %search% AND isActive = 1`, and displays
50
+ each as `"{c_erpSystemEntityId} - {name}"`.
51
+ - It funnels **both** the cart checkout and the New-User form, so a single filter in
52
+ `fetchCostCenter` covers both entry points.
53
+ - **api2 does no cost-center validation** — the FE is the only selection gate.
54
+
55
+ ### Where the values come from (import)
56
+ - `worker1.5/crons/toga2/compass/import_locations.php` reads an SFTP file and sets
57
+ `c_erpSystemEntityId` on Unit rows from **column 16**.
58
+ - Repeated imports have massively **duplicated** cost-center rows (~730× per value).
59
+
60
+ ### Numeric-only enforcement (2026-07-06) — three layers
61
+ 1. **Front-end selection block** — in `fetchCostCenter`, on the **search path**
62
+ (`useSearchOptions === true`), returned locations are filtered to numeric-only cost centers
63
+ with `/^[0-9]+$/` on `c_erpSystemEntityId.trim()`. The non-search / display path is left
64
+ untouched (so an already-saved value still renders). Done client-side because api2 rejects a
65
+ server-side numeric filter (see gotcha) and api2 was out of scope.
66
+ 2. **Data cleanup (one-time, reversible)** —
67
+ `dbchanges2/Client_Compass/2026-07-06 - RemoveNonNumericCostCenters.sql` runs
68
+ `UPDATE Locations SET isActive = 0` for every active row whose `c_erpSystemEntityId` is
69
+ non-empty and does **not** match `^[0-9]+$`. **Soft delete (isActive=0), not a hard delete.**
70
+ ~401,719 active rows across 1,185 distinct non-numeric codes. They then drop out of the
71
+ commerce lookup automatically via its existing `isActive = 1` filter.
72
+ 3. **Import durability guard** — in `import_locations.php`, in **both** Unit branches
73
+ (new-create and existing-update), after `$isActiveValue` is computed it is forced to `0` when
74
+ the cost center is non-empty and not `ctype_digit`, so future imports never re-activate or
75
+ create active non-numeric cost centers.
76
+
77
+ ## Gotchas
78
+ - **api2 cannot do a server-side numeric filter.** The V2 query-string where-parser
79
+ (`api2/Component/Api/V2/V2.php` → `parseOptionsWhere`) **whitelists operators and rejects
80
+ `regexp` with a 500**. Any numeric/regex filtering must happen client-side (or via a new
81
+ operator in api2, which was out of scope here).
82
+ - **Two fields, easy to swap.** `c_erpSystemEntityId` is the cost center (what users pick);
83
+ `c_erpEntityId` is the unit id and the value that orders record on
84
+ `SalesOrders.c_erpEntityId`.
85
+ - **Second, possibly-live copy of the import cron not yet guarded.** A second copy exists at
86
+ `worker/crons/toga2/compass/DOA_Scripts/import_locations.php` (appears disabled / "DOA"). It
87
+ did **not** receive the numeric guard — **confirm whether it is live** before trusting the
88
+ guard to be complete.
89
+ - Non-numeric cost centers include both number+alphabet combos (e.g. `10007A`, `224GT`) and
90
+ letters-only codes (e.g. `EAGLE`, `TAMU`). All are retired in favor of numeric-only.
91
+
92
+ ## Safety verification (before deactivation, prod Client_Compass)
93
+ Deactivation was proven safe against prod data:
94
+ - **0** users (active or inactive, via `Users.locationId`), **0** sales orders / SO items /
95
+ purchase orders / item fulfillments / item receipts / transfer orders / inventory adjustments /
96
+ tickets / contacts / child locations reference these non-numeric Unit locations.
97
+ - Only **1,180** `Locations_Addresses` links point at them (harmless, left intact).
98
+ - Only **2** sales orders ever used a non-numeric cost-center value (stored as string on
99
+ `SalesOrders.c_erpEntityId`, unaffected by deactivating the Location).
100
+ - **0** active users have a non-numeric `c_erpEntityId`, so no cost-center display goes blank.
101
+ - Proven end-to-end in dev-sandbox: after the migration, active non-numeric rows = **0** (all
102
+ 1,185 codes incl. the 725 number+alphabet combos) while pure-numeric stayed untouched at
103
+ **440,005** active rows.
104
+
105
+ ## Scope constraints (from the developer)
106
+ - Do **not** change anything in `api2`.
107
+ - Do **not** hard-delete — use `isActive = 0` (reversible).
108
+ - **US Compass only** (`Client_Compass`); Compass Canada is out of scope.
109
+
110
+ ## Change history
111
+ - 2026-07-06 — Established numeric-only cost-center policy across three layers: FE `fetchCostCenter`
112
+ search-path filter (`/^[0-9]+$/`), one-time `RemoveNonNumericCostCenters.sql` soft-deactivation
113
+ (~401,719 rows / 1,185 codes), and an `import_locations.php` guard forcing `isActive=0` on
114
+ non-`ctype_digit` cost centers in both Unit branches. Documented that a Compass cost center is a
115
+ Unit Location keyed by `c_erpSystemEntityId` (not the vestigial `CostCenters` table). (bala)
@@ -8,16 +8,18 @@ apps:
8
8
  - toga25-supply
9
9
  - toga2-commerce
10
10
  - worker
11
+ - worker1.5
11
12
  - dbchanges2
12
13
  project: _Underscore
13
14
  client: compass-usa
14
15
  type: profile
15
16
  status: active
16
- updated: 2026-06-30
17
+ updated: 2026-07-06
17
18
  owners: [jcardinal, bala, tcox]
18
19
  files: []
19
20
  related:
20
21
  - features/asn-to-item-fulfillment.md
22
+ - features/cost-centers.md
21
23
  - ../../2.0/apps/toga2-commerce/features/expedited-shipping-gating.md
22
24
  - ../../2.0/apps/_underscore/features/item-fulfillment-stage-lifecycle-and-order-status.md
23
25
  ---
@@ -34,7 +36,9 @@ separate, related client (see its own profile).
34
36
  - **2.0:** `_underscore` backend, prod schema `Client_Compass` (worker link `db_compass`).
35
37
  Client-specific model overrides live under `_underscore/Model/Compass/`.
36
38
  - **1.0:** worker crons under `worker/crons/toga2/compass/` handle email-based imports and
37
- notifications.
39
+ notifications. A separate **`worker1.5`** repo (also App_/1.0-style) runs the SFTP location
40
+ import (`worker1.5/crons/toga2/compass/import_locations.php`) that seeds Unit Locations /
41
+ cost centers.
38
42
  - Storefront: compass.togacommerce.com / compass.togahub.com. The storefront app repo is
39
43
  **`toga2-commerce`** (2.0, consumes api2).
40
44
 
@@ -56,6 +60,9 @@ separate, related client (see its own profile).
56
60
  ## Key features (this client)
57
61
  - [Compass ASN → ItemFulfillment Auto-Creation](features/asn-to-item-fulfillment.md) — the
58
62
  `_Model_Compass_AdvanceShippingNotice::postPost` handler.
63
+ - [Cost Centers (Unit Locations, numeric-only)](features/cost-centers.md) — what a Compass
64
+ "cost center" actually is (a Unit Location keyed by `c_erpSystemEntityId`), and the
65
+ numeric-only selection/import/data policy (2026-07-06).
59
66
 
60
67
  ## Notes
61
68
  - **Order status is shipped-only (2026-06-30).** Compass imports all IF stages
@@ -41,6 +41,15 @@
41
41
  "role": "app",
42
42
  "dependsOn": []
43
43
  },
44
+ {
45
+ "repo": "worker1.5",
46
+ "project": "Worker 1.5",
47
+ "framework": "1.0",
48
+ "role": "app",
49
+ "dependsOn": [
50
+ "library"
51
+ ]
52
+ },
44
53
  {
45
54
  "repo": "toga2-supply",
46
55
  "project": "TOGa Supply",
@@ -0,0 +1,80 @@
1
+ ---
2
+ type: session
3
+ slug: talos-transcripts
4
+ title: Talos transcript ingestion — cross-account creds, KB registry, admin UI edits
5
+ author: jcardinal
6
+ repos: [worker2, tools, dbchanges2]
7
+ framework: "both"
8
+ client: shared
9
+ status: active
10
+ created: 2026-07-07
11
+ updated: 2026-07-07
12
+ ---
13
+
14
+ # Session: talos-transcripts
15
+ **Date:** 2026-07-07
16
+ **Project/Repo:** worker2 + tools + dbchanges2 (both 1.0 and 2.0)
17
+ **Task:** Harden and extend the Talos meeting-transcript → Bedrock knowledge-base ingestion pipeline (worker2) and its Tools (1.0) "Talos Knowledge Base" admin UI — fix cross-account S3 credentials, populate the KB registry from Bedrock, add move/edit doc features, refine AI classification, and fix a MySQL timeout on long transcripts.
18
+
19
+ ---
20
+
21
+ ## What WORKED
22
+ <!-- Include specific file paths and evidence -->
23
+ - **Cross-account S3 credential split (worker2).** `toga-private` (raw transcripts, us-west-2) and `togaiq` (approved/archive KB bucket, us-east-1) are in DIFFERENT AWS accounts; no single key writes both. Fixed by reading per-bucket credentials: `s3Client()`/`getS3Client()` from `[teams]` (`s3_access_key_id`/`s3_secret_access_key`), `getTalosS3Client()`/`getBedrockClient()` from `[talos]`. Added those keys to `worker2/Config/production.ini`. Reprocessor then succeeded uploading to togaiq. Files: `worker2/Worker/Team/Transcripts.php`, `worker2/Config/production.ini`.
24
+ - **Archive step get+put instead of cross-account CopyObject.** `CopyObject` cannot span accounts — was failing `AccessDenied`. Process() step 8 now reads with `rawS3` and writes with `talosS3`. Confirmed working in reprocessor output.
25
+ - **Tools app togaiq write access.** `App_Talos_S3::client()` now prefers a `[talos]` config section (the togaiq-account key), falling back to `[aws]`, then SDK default chain. Added `[talos]` to `tools/config.production.ini` (and `config.alpha.ini`). Move/delete/edit on the KB browser now work. Files: `tools/_/app/talos/s3.php`, `tools/config.production.ini`, `tools/config.alpha.ini`.
26
+ - **Worker-job enqueue from Tools.** Added `[worker]` (worker2 prod SQS queue url/region) and `[aws]` (main-account key for SQS SendMessage) to `tools/config.production.ini`; `[database_toga2core]` was already present. `App_Worker::enqueue` now queues `SyncKb` re-sync jobs successfully.
27
+ - **KB registry sync from Bedrock.** New action `_Worker_Team_Transcripts::SyncKnowledgeBases(bool $apply=true)` + helper `listAllKnowledgeBases()` list all `development-team-*` Bedrock KBs and upsert into `Team.KnowledgeBases`. New CLI `worker2/bin/sync-knowledge-bases.php --dry-run`. User ran it; table went from 2 rows (general, office-depot) to the full KB set including `elite`. Confirmed via `SELECT slug FROM KnowledgeBases`.
28
+ - **Move-document feature (Tools).** `App_Talos_S3::moveApprovedDocument` (get+put copy of .txt + sidecar, rewrites sidecar `metadataAttributes.client.value.stringValue`, deletes originals) + `copyWithinBucket`/`putObjectBody` helpers; `move` action in post.php; move icon → small centered dialog in get.php. Working end-to-end.
29
+ - **Edit title + contents (Tools).** Pencil icon (text docs only) → edit mode: title text box, Find & Replace tool (ported from `test/team/talos/kb_processor.php`), contents textarea, Save/Cancel top-right. `update` action + `App_Talos_S3::sanitizeTitle`/`updateApprovedDocument` (rewrites body; renames to `YYYY-MM-DD - {title}.txt` preserving date; moves+updates sidecar filename attr; enqueues SyncKb). Backdrop-click disabled while editing. All four files lint clean.
30
+ - **Classification: meeting title now passed to AI.** Process() parses date+title up front and passes `meetingTitle` into `callAICleaningAPI`, surfaced as a `MEETING TITLE:` block; instruction prioritizes it. Fixed short Elite transcripts that were falling to `general`.
31
+ - **Sequential dual re-sync on move.** `SyncKb` now accepts comma-separated slugs and syncs each sequentially with `KB_SYNC_DELAY_SECONDS` spacing; move enqueues one `SyncKb("source,dest")` job. Fixes only-destination-synced race (Bedrock allows one in-flight ingestion per KB).
32
+ - **Last-modified timezone.** `App_Talos_S3::listApproved` converts S3 UTC `LastModified` to `America/Chicago` before formatting `n/j/y g:i A`; sort key stays UTC ISO-8601.
33
+ - **/capture run** published 2 UPDATE docs to `_main` (talos-transcript-ingestion.md, talos-kb-documents-admin.md). Validate OK.
34
+
35
+ ## What did NOT work — DO NOT RETRY THESE
36
+ <!-- Exact failure reasons — do not vague-ify -->
37
+ - **Setting env vars `AWS_ACCESS_KEY_ID=... php bin/reprocess-transcripts.php`** to switch credentials: NO EFFECT. The code passes credentials explicitly to the S3Client constructor from `_Config`, which overrides the SDK env-var/default chain. Error stayed `User: arn:aws:iam::502614707982:user/jcardinal ... not authorized`.
38
+ - **Granting the `jcardinal` IAM user S3 perms + using the toga-private-account key for togaiq:** still `AccessDenied` on togaiq. That key belongs to the toga-private account; togaiq is a SEPARATE AWS account. IAM user policy alone can't grant cross-account; and this key simply is not the togaiq key.
39
+ - **Switching move from CopyObject to get+put did NOT fix the tools AccessDenied by itself** — because the tools `[aws]` key was STILL the toga-private-account key, which can read togaiq cross-account but not write. Root cause was the credential, not the operation. (get+put is still retained and correct.)
40
+ - **Two parallel `SyncKb` jobs (one per KB) on move:** only the destination KB actually synced. Bedrock allows one in-flight ingestion per KB and the independent workers raced with no ordering/spacing. Replaced with a single sequential job.
41
+ - **Relying on post-AI `setStatus` writes for long transcripts:** fails with MySQL error 2006 "MySQL server has gone away" — the up-to-600s AI HTTP call leaves the DB connection idle past `wait_timeout`, so every write after it (cleaned/uploaded/archived/synced) dies. Do NOT put status writes after the AI call.
42
+
43
+ ## Not tried yet (candidates for next session)
44
+ - **DB reconnect/ping after the AI call** as an alternative that would let `kbSlug`/`approvedKey`/`archiveKey` be persisted to the ledger (currently dropped). User chose the "set status before AI" route instead; reconnect remains an option if ledger detail is wanted.
45
+ - **Rotating the pre-existing leaked credentials** (toga-private + togaiq AWS keys, aegra/talos API key) in `worker2/Config/production.ini` and the old `test/team/talos/kb_processor.ini`. Standing separate track.
46
+ - **Moving the two already-processed Elite transcripts** (currently in `general`/`toga-technology`) into `elite` via the Tools move button, and reprocessing to confirm new classification.
47
+ - **Wiring `[talos]` into `tools/config.production.ini` for other environments** if the browser is used outside production (only production + alpha have it).
48
+ - **Cron already added** for KB registry sync; verify it fires after deploy.
49
+
50
+ ## Current file state
51
+ | File | Status | Notes |
52
+ |------|--------|-------|
53
+ | worker2/Worker/Team/Transcripts.php | Modified | Per-bucket S3 creds; archive get+put; SyncKnowledgeBases+listAllKnowledgeBases; SyncKb multi-slug sequential; title→AI; customer-over-company + general-apps→general classification; status set to 'synced' BEFORE AI call, post-AI status writes removed. Lint clean. |
54
+ | worker2/Config/production.ini | Modified | `[teams]` gained s3_access_key_id/secret (toga-private key); `[talos]` gained s3_access_key_id/secret (togaiq key). |
55
+ | worker2/bin/sync-knowledge-bases.php | Created | CLI wrapper for SyncKnowledgeBases; `--dry-run`. |
56
+ | tools/_/app/talos/s3.php | Modified | client() prefers [talos]; copyWithinBucket/putObjectBody; moveApprovedDocument; sanitizeTitle/updateApprovedDocument; listApproved UTC→Central; verbose AWS error messages. |
57
+ | tools/mvc/talos/kb-documents/post.php | Modified | Added move + update actions; move enqueues single SyncKb("src,dest"). |
58
+ | tools/mvc/talos/kb-documents/get.php | Modified | Move dialog + edit modal (title box, Find&Replace, textarea, Save/Cancel). |
59
+ | tools/config.production.ini | Modified | Added [talos], [worker], [aws] sections. |
60
+ | tools/config.alpha.ini | Modified | Added [talos] section. |
61
+ | dbchanges2/Core/2026-07-02a - Teams KnowledgeBases sync cron.sql | Created | Daily 05:00 CT cron for Team/Transcripts/SyncKnowledgeBases. Depends on 2026-05-14 maxExecutionTime migration. |
62
+ | dbchanges2/Team/2026-07-02a - TranscriptPromptTemplate exclude personal notes.sql | Created | REPLACE() adds rule to exclude personal/social content + no "Personal Notes" section. |
63
+
64
+ ## Decisions made
65
+ - **Per-bucket credentials, not one shared key.** togaiq and toga-private are separate AWS accounts; `[teams]`=toga-private, `[talos]`=togaiq, `[aws]`=main/SQS. Rejected: single key (impossible cross-account), instance role (prod role lacks togaiq write).
66
+ - **App_Talos_S3 gets its own `[talos]` credentials** rather than changing the app-wide `[aws]` key (which other tools use for us-west-2/toga-private). Precedence: [talos] → [aws] → SDK default.
67
+ - **Bedrock is source of truth for the KB list; `Team.KnowledgeBases` is a cache/allowlist** synced by `SyncKnowledgeBases` (insert-only for new, refresh bedrockKbId for existing, never delete/deactivate) + daily cron.
68
+ - **Single sequential `SyncKb` job for moves**, not two parallel jobs — avoids concurrent Bedrock ingestion per KB and guarantees both sync.
69
+ - **Classification rules (in code `$slugInstruction`, not the DB cleaning prompt):** title-priority; customer-over-company (toga-technology never wins over a real customer); general application/engineering work → `general`, `toga-technology` reserved for company-itself meetings; else `general`.
70
+ - **Prompt edits via surgical `REPLACE()` migration**, preserving `{{PLACEHOLDERS}}` and UI edits, no-op if not found. Rejected: full-text overwrite (would clobber UI edits).
71
+ - **Set ledger status to 'synced' BEFORE the AI call** and drop all post-AI status writes. Accepted trade-off: ledger loses kbSlug/approvedKey/archiveKey detail, and a post-AI failure leaves the row 'synced' (not retried by Scan). Chosen explicitly by the developer over a DB-reconnect approach.
72
+
73
+ ## Blockers
74
+ none — all changes are code/config complete and lint clean; remaining work is deploy + verify.
75
+
76
+ ## Exact next step
77
+ > Deploy worker2 (Transcripts.php + production.ini) and re-run `ENVIRONMENT=production php bin/reprocess-transcripts.php --limit=1` on a LONG transcript to confirm the MySQL error 2006 ("server has gone away") is gone and the row is marked `synced`. Then apply the two new dbchanges2 migrations (Core KB-sync cron + Team prompt personal-notes exclusion) and deploy the tools changes.
78
+
79
+ ---
80
+ _Saved by /session-save on 2026-07-07_
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.276",
3
+ "version": "1.0.278",
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",