toga-ai 1.0.319 → 1.0.321

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.
@@ -7,6 +7,6 @@
7
7
  | [Tools MVC — Routing, CSRF & App_Database Access Patterns](features/mvc-data-access-patterns.md) | The load-bearing 1.0 (`App_`) framework conventions a developer needs when adding a page to the Tools app — URL routing, CSRF, and DB access through `App_Databa | tools/_/app/nav.php, tools/mvc/get.php |
8
8
  | [Tools Persona-Gated Navigation (App_Nav)](features/persona-gated-navigation.md) | `App_Nav` is the Tools app's two-level, **persona-gated** navigation. | tools/_/app/nav.php, tools/mvc/get.php |
9
9
  | [Tools SAML SSO Consumer & Persona-Gated Auth (App_Auth)](features/saml-sso-auth.md) | `App_Auth` is the Tools app's authentication layer: it consumes the SAML gateway `?saml=` handoff (see the 2.0 SAML downstream integration contract), establishe | tools/_/app/auth.php, tools/mvc/sso/initiate/get.php, tools/mvc/sso/get.php, tools/mvc/login/get.php, tools/mvc/login/post.php, tools/mvc/logout/get.php, tools/mvc/get.php, tools/config.production.ini, tools/config.local.ini |
10
- | [Talos Knowledge Base Admin UI (KB Documents + Vocabulary)](features/talos-kb-documents-admin.md) | A Tools (1.0) admin UI to browse/fix the Talos knowledge-base documents and manage the transcript-cleanup vocabulary — without a deploy. | tools/mvc/talos/kb-documents/get.php, tools/mvc/talos/kb-documents/post.php, tools/mvc/talos/vocabulary/get.php, tools/mvc/talos/vocabulary/post.php, tools/_/app/talos/s3.php, tools/_/app/worker.php, tools/_/app/nav.php, tools/config.production.ini, tools/config.alpha.ini |
10
+ | [Talos Knowledge Base Admin UI (KB Documents + Vocabulary)](features/talos-kb-documents-admin.md) | A Tools (1.0) admin UI to browse/fix the Talos knowledge-base documents and manage the transcript-cleanup vocabulary — without a deploy. | tools/mvc/talos/kb-documents/get.php, tools/mvc/talos/kb-documents/post.php, tools/mvc/talos/knowledge-bases/get.php, tools/mvc/talos/knowledge-bases/post.php, tools/mvc/talos/vocabulary/get.php, tools/mvc/talos/vocabulary/post.php, tools/_/app/talos/s3.php, tools/_/app/talos/bedrock.php, tools/_/app/pg.php, tools/_/app/worker.php, tools/_/app/nav.php, tools/config.production.ini, tools/config.alpha.ini, tools/.platform/httpd/conf.d/timeouts.conf, tools/.platform/hooks/prebuild/01-install-php-pgsql.sh, tools/.platform/hooks/postdeploy/01-restart-php.sh |
11
11
  | [Talos Pricing UI (Onboarding, Dashboard, Benchmarks, Cost Factors + Estimator)](features/talos-pricing-ui.md) | The 1.0 (tools app) face of the **Talos Pricing Platform** — a "Talos Pricing" nav folder with four pages plus a client-side estimate engine. | tools/_/app/nav.php, tools/_/app/talos/estimator.php, tools/mvc/talos/onboarding/get.php, tools/mvc/talos/onboarding/post.php, tools/mvc/talos/pricing/get.php, tools/mvc/talos/benchmarks/get.php, tools/mvc/talos/factors/get.php, tools/mvc/talos/factors/post.php, tools/assets/css/style.css |
12
12
  | [Deploying Tools to Elastic Beanstalk (PHP 8.5 / Amazon Linux 2023)](workflows/deploy-to-elastic-beanstalk-al2023.md) | How the **Tools** 1.0 app boots on Elastic Beanstalk running `PHP 8.5 on 64bit Amazon Linux 2023/4.13.1 (aarch64)`. | tools/.ebextensions/004_http_to_https.config, tools/.ebextensions/006_mount-s3fs.config, tools/.ebextensions/007_setup_export_cache_folders.config, tools/.ebextensions/008_setup_ldap.config, tools/.ebextensions/009_setup_phpini.config, tools/.ebextensions/020_setup_git_libraries.config, tools/.ebextensions/050_register_instance_to_shared_application_load_balancer.config, tools/ebs/git.json |
@@ -6,18 +6,25 @@ project: Tools
6
6
  client: shared
7
7
  type: feature
8
8
  status: active
9
- updated: 2026-07-09
9
+ updated: 2026-07-13
10
10
  owners: [jcardinal]
11
11
  files:
12
12
  - tools/mvc/talos/kb-documents/get.php
13
13
  - tools/mvc/talos/kb-documents/post.php
14
+ - tools/mvc/talos/knowledge-bases/get.php
15
+ - tools/mvc/talos/knowledge-bases/post.php
14
16
  - tools/mvc/talos/vocabulary/get.php
15
17
  - tools/mvc/talos/vocabulary/post.php
16
18
  - tools/_/app/talos/s3.php
19
+ - tools/_/app/talos/bedrock.php
20
+ - tools/_/app/pg.php
17
21
  - tools/_/app/worker.php
18
22
  - tools/_/app/nav.php
19
23
  - tools/config.production.ini
20
24
  - tools/config.alpha.ini
25
+ - tools/.platform/httpd/conf.d/timeouts.conf
26
+ - tools/.platform/hooks/prebuild/01-install-php-pgsql.sh
27
+ - tools/.platform/hooks/postdeploy/01-restart-php.sh
21
28
  related:
22
29
  - ./mvc-data-access-patterns.md
23
30
  - ./persona-gated-navigation.md
@@ -31,7 +38,8 @@ A Tools (1.0) admin UI to browse/fix the Talos knowledge-base documents and mana
31
38
  transcript-cleanup vocabulary — without a deploy. It is the human front-end to the worker2
32
39
  [Talos Transcript Ingestion](../../../2.0/apps/worker2/features/talos-transcript-ingestion.md)
33
40
  pipeline. A new **"Talos Knowledge Base"** nav group (personas *Development Team* / *TOGa
34
- Technology*) exposes two pages.
41
+ Technology*) exposes the pages below. **"Knowledge Bases"** is registered as the **first**
42
+ action in the `talos-kb` nav group (above "KB Documents") and inherits the group's personas.
35
43
 
36
44
  ## Pages
37
45
 
@@ -73,6 +81,53 @@ so they displayed **double-encoded** (e.g. "Grand & Toy"). `vocabulary/post.
73
81
  `html_entity_decode()`s values on save so the DB stores **raw** text; `vocabulary/get.php`
74
82
  already escapes once at display. Do not re-add encoding on save.
75
83
 
84
+ ### `/talos/knowledge-bases` — KB list + inline rename
85
+
86
+ The list/admin page (`get.php`) for Talos knowledge bases. Unlike KB Documents (whose KB
87
+ list is derived from **live S3 folders**), this page's list comes from the
88
+ **`Team.KnowledgeBases` MySQL table** (via `db_team`) — the two are distinct sources of
89
+ truth. Columns: Slug, Name, Bedrock KB ID, Created On (`dtCreated`, converted UTC→
90
+ America/Chicago). **Name is the only editable field** and is edited **in place** (Edit→Save);
91
+ there is **no delete option**. Server strings are escaped before `innerHTML` (XSS guard).
92
+
93
+ Rename posts `action=rename` → `UPDATE Team.KnowledgeBases SET name WHERE slug` (`db_team`),
94
+ preceded by an **existence SELECT** so a stale slug reports **"not found"** instead of a
95
+ false success.
96
+
97
+ ### `POST /talos/knowledge-bases` — create a new KB (synchronous provisioning)
98
+
99
+ Admin action that provisions a brand-new Talos knowledge base end to end in **one
100
+ synchronous request**: creates the S3 prefix, creates the Bedrock KB and **waits for it to
101
+ reach `ACTIVE`**, creates the Bedrock data source (`MANAGED_KNOWLEDGE_BASE_CONNECTOR`), and
102
+ inserts rows across **5 systems with no shared transaction**: `Team.KnowledgeBases` (`db_team`,
103
+ Team MySQL cluster), `Client_True.VectorIndexes` (`db_true`, **Client MySQL cluster** — not the
104
+ Team cluster), and 2 Talos **Postgres** rows (`public.knowledge_bases` +
105
+ `public.assistant_knowledge_bases`, the latter linking a hard-coded assistant id). Step order:
106
+ validate name (≤255) + derive slug via **`App_Talos_S3::slugify()`** (kebab-case, `iconv` ASCII
107
+ translit; rejects a duplicate slug — `slug` is UNIQUE); create 3 S3 folder markers
108
+ `development-team/{slug}/{approved,archive,upload}/` via **`App_Talos_S3::putFolderMarker()`**;
109
+ create the Bedrock KB and wait for `ACTIVE`; create the data source; then the DB inserts. This flow
110
+ **stays synchronous by design** — moving it to worker2/SQS async was explicitly rejected;
111
+ the fix path is to raise timeouts, never to background the work.
112
+
113
+ The handler is **best-effort with no rollback**: on a mid-flow failure it stops and returns
114
+ a `steps[]` report **without tearing down** already-created AWS resources (see Gotchas —
115
+ orphaned KB).
116
+
117
+ **`App_Talos_Bedrock`** (`_/app/talos/bedrock.php`) — Bedrock Agent client:
118
+ - `waitForKnowledgeBaseActive()` polls `getKnowledgeBase` every `WAIT_INTERVAL_SECONDS` (3s)
119
+ up to **`WAIT_MAX_SECONDS` = 300** (raised from 90; MANAGED KBs were observed taking ~3 min
120
+ to leave `CREATING`). Exits immediately on `ACTIVE`/`FAILED`, so fast activations are
121
+ unaffected. 300s sits well under the 900s Apache/PHP ceiling.
122
+ - `createDataSource()` — `connectorParameters` for `managedKnowledgeBaseConnectorConfiguration`
123
+ is a **`Document` shape (free-form JSON)** in the AWS PHP SDK model and **must be passed as a
124
+ native PHP array** so the SDK serializes a JSON *object*. Passing a pre-`json_encode()`d
125
+ **string** fails `ValidationException "Invalid connector parameters format"`. Working object
126
+ shape (matches the craftex data source):
127
+ `{type:S3, filterConfiguration:{maxFileSizeInMegaBytes:"500",
128
+ inclusionPrefixes:["development-team/{slug}/approved/"]}, connectionConfiguration:{bucketName:togaiq,
129
+ bucketOwnerAccountId:654654170868, bucketArn:arn:aws:s3:::togaiq}, aclEnabled:false, version:"1"}`.
130
+
76
131
  ## Helpers
77
132
 
78
133
  - **`App_Talos_S3`** (`_/app/talos/s3.php`) — S3 client; list KB slugs; list/count approved
@@ -85,6 +140,13 @@ already escapes once at display. Do not re-add encoding on save.
85
140
  the SDK default chain — because `App_Talos_S3` only ever talks to **togaiq**, so it needs the
86
141
  togaiq-account key (the tools `[aws]` key is the toga-private key, which can cross-account *read*
87
142
  togaiq but not *write* it).
143
+ - **`App_Pg`** (`_/app/pg.php`) — a **tools-only** minimal PDO `pgsql` wrapper for the Talos
144
+ Postgres DB (host `writer.talos.database.togahub.com:5432`, db `tenant_true`, user
145
+ `talosadmin`). Deliberately **not** added to the shared 1.0 `library` (the App_ framework has
146
+ no Postgres support). The password is **read from the existing `[database_team]` config
147
+ section** (shared with the MySQL DBs) — **no new secret introduced**. `execute()` uses real
148
+ PDO prepared statements (bound params). If the `pdo_pgsql` extension is missing it returns
149
+ `ok=false` with a generic message (detail goes only to `error_log`, never to the client).
88
150
  - **`App_Worker::enqueue()`** (`_/app/worker.php`) — inserts a `Core.WorkerJobs` row and sends
89
151
  the `{"workerJobId": id}` SQS message, so a 1.0 app can enqueue worker2 jobs. Requires the
90
152
  `[worker]` (`queue_url`/`queue_region`) and `[aws]` (main-account key for SQS `SendMessage`)
@@ -100,6 +162,12 @@ already escapes once at display. Do not re-add encoding on save.
100
162
  - **`[aws]`** — main-account key for SQS `SendMessage` (toga-private key; cross-account reads
101
163
  togaiq but cannot write it — that's why `[talos]` exists).
102
164
  - `[database_toga2core]` — writable 2.0 Core (already present).
165
+ - **`pdo_pgsql` PHP extension** must be installed on the tools Elastic Beanstalk environment
166
+ (the create flow writes to Talos Postgres via `App_Pg`). Provided by two `.platform` hooks
167
+ (mirroring worker2's): `hooks/prebuild/01-install-php-pgsql.sh` (installs `php-pgsql`,
168
+ idempotent, **fails the deploy loudly** if `pgsql` won't load) and
169
+ `hooks/postdeploy/01-restart-php.sh` (restarts php-fpm/httpd). **EB runs `.platform/hooks`
170
+ regardless of the git exec bit** — worker2's equivalents are committed `100644`.
103
171
  - Apply the dbchanges2 `Team/2026-06-30a..e` + `Core/2026-06-30a` migrations in order.
104
172
  - Verify the Bedrock KB region / data-source name against the live account (TODOs in code).
105
173
 
@@ -116,11 +184,70 @@ already escapes once at display. Do not re-add encoding on save.
116
184
  within the same bucket; move/edit copy via get+put.
117
185
  - **Move/edit re-sync must be one `SyncKb("source,dest")` job**, not two parallel jobs — Bedrock
118
186
  allows only one in-flight ingestion per KB and parallel syncs race.
187
+ - **KB create is synchronous and long (~minutes).** It must run under a raised timeout — see
188
+ the EB Apache 504 gotcha below. Do **not** re-architect it to worker2/SQS (explicitly
189
+ rejected).
190
+ - **EB AL2023 PHP platform → 60s default proxy timeout → 504.** The tools app runs on Elastic
191
+ Beanstalk PHP 8.5 / Amazon Linux 2023, where **Apache proxies to php-fpm via
192
+ `mod_proxy_fcgi`** and the proxy read timeout defaults to `Timeout` = **60s**. A long
193
+ synchronous request (KB create) returns **504 after exactly 60s**. Raising the **ALB idle
194
+ timeout does not help** (it's upstream of Apache), and PHP `set_time_limit(900)` is
195
+ irrelevant (Apache emits the 504, and on Linux `max_execution_time` does not count time
196
+ blocked in network I/O). Fix: an EB platform Apache drop-in at
197
+ **`.platform/httpd/conf.d/timeouts.conf`** setting `Timeout 900` and **`ProxyTimeout 900`**
198
+ (`ProxyTimeout` is the `mod_proxy_fcgi` read timeout; matches the framework's
199
+ `set_time_limit(900)`). Applied on deploy.
200
+ - **php-fpm `request_terminate_timeout` can still kill the request.** If
201
+ `/etc/php-fpm.d/www.conf`'s `request_terminate_timeout` is ever set to 60 it terminates the
202
+ request regardless of Apache — it must be `0` or `>= 900`.
203
+ - **`get-data-source` echoes `connectorParameters` back as a quoted STRING** even though the
204
+ create input must be a JSON **object** — the GET representation is misleading and does NOT
205
+ indicate the required input shape.
206
+ - **KB create has no rollback → orphaned KB risk.** A failure at the data-source step leaves an
207
+ orphaned Bedrock KB with **no DB rows** (`Team.KnowledgeBases`/`VectorIndexes`/Postgres never
208
+ inserted). Blindly re-running with the same name creates a **duplicate** Bedrock KB (Bedrock
209
+ allows same-name KBs with new ids). After a failed create: either
210
+ `aws bedrock-agent delete-knowledge-base` the orphan and re-run clean, or finish the DB rows
211
+ manually.
212
+ - **Newest KBs use Bedrock's fully-MANAGED type** (`knowledgeBaseConfiguration.type=MANAGED`,
213
+ `managedKnowledgeBaseConfiguration.embeddingModelType=MANAGED`) — **AWS owns the vector store**,
214
+ so there is **no S3 Vectors index, no `embeddingModelArn`, and no `storageConfiguration`** to
215
+ build. Config was replicated from the existing `development-team-craftex` KB. Account
216
+ `654654170868`, region `us-east-1`, execution role `…ForKnowledgeBase_ofl5a`.
217
+ - **KB-list source differs per page.** The new `/talos/knowledge-bases` page lists from
218
+ `Team.KnowledgeBases` (`db_team`); `/talos/kb-documents` lists from live S3 folders. Don't
219
+ assume one reflects the other.
220
+ - **Schemas.** `Team.KnowledgeBases`: `id, uuid`(UNIQUE)`, slug`(UNIQUE)`, name, isGeneral,
221
+ bedrockKbId`(nullable)`, isActive, dtCreated`(datetime default `CURRENT_TIMESTAMP`)`, dtUpdated`.
222
+ `Client_True.VectorIndexes` (Client cluster): `id, uuid`(UNIQUE)`, name, docSlug`(UNIQUE,
223
+ nullable)`, sectionSlug, chunkSlug, description` — create sets `docSlug=sectionSlug=chunkSlug=
224
+ bedrockKbId`.
225
+ - **Not yet run end-to-end in production.** The whole feature is code-complete, `php -l` clean,
226
+ and reviewed, but the create flow has not been exercised in prod pending the `pdo_pgsql`
227
+ deploy plus network/IAM prerequisites (the developer is handling those).
119
228
  - No new secret literals introduced; credentials live in the config sections above (documented by
120
- section/account, never by value).
229
+ section/account, never by value). AWS account id `654654170868`, bucket `togaiq`, and the KB
230
+ execution-role ARN are non-secret resource identifiers.
121
231
 
122
232
  ## Change history
123
233
 
234
+ - 2026-07-13 — Added the **`/talos/knowledge-bases` list + inline-rename page** (`get.php`;
235
+ lists from `Team.KnowledgeBases`, rename-only, no delete, existence-check before update),
236
+ registered first in the `talos-kb` nav group. Added the **`App_Pg`** tools-only PDO `pgsql`
237
+ wrapper (password reused from `[database_team]`; not added to shared library) and the
238
+ **`.platform` pdo_pgsql install/restart hooks**. Documented the create flow's 5-system fan-out
239
+ (incl. `Client_True.VectorIndexes` on the **Client** cluster + 2 Postgres rows), the
240
+ `slugify()`/`putFolderMarker()` helpers, the fully-**MANAGED** Bedrock KB type (AWS-owned vector
241
+ store, no storageConfiguration), and the two DB schemas. Feature is code-complete/reviewed but
242
+ not yet run end-to-end in prod. (jcardinal)
243
+ - 2026-07-13 — Added the **synchronous KB-create flow** (`POST /talos/knowledge-bases`) via new
244
+ `App_Talos_Bedrock` helper. Fixed the **504 at 60s**: EB AL2023 PHP = Apache→php-fpm over
245
+ `mod_proxy_fcgi` with a 60s default proxy read timeout; added
246
+ `.platform/httpd/conf.d/timeouts.conf` (`Timeout 900` + `ProxyTimeout 900`). Raised
247
+ `WAIT_MAX_SECONDS` 90→300 (MANAGED KBs take ~3 min to go `ACTIVE`). Fixed `createDataSource`
248
+ `ValidationException` by passing `connectorParameters` as a native array (`Document` shape),
249
+ not a `json_encode`d string. Documented the no-rollback orphaned-KB caveat and the misleading
250
+ `get-data-source` string echo. Flow stays synchronous (worker2 async rejected). (jcardinal)
124
251
  - 2026-07-09 — Fixed `App_Talos_S3::sanitizeTitle()` to convert `/`,`\` to hyphens (was
125
252
  spaces) so a slashed meeting title no longer creates a stray S3 sub-folder — matches
126
253
  worker2's `filenameSafeTitle()`; `updateApprovedDocument()` already renames the S3 object and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toga-ai",
3
- "version": "1.0.319",
3
+ "version": "1.0.321",
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",