toga-ai 1.0.901 → 1.0.902
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.
- package/knowledge/1.0/apps/test/INDEX.md +1 -1
- package/knowledge/1.0/apps/test/features/talos-kb-pipeline.md +7 -4
- package/knowledge/1.0/apps/togadesk/architecture.md +2 -2
- package/knowledge/1.0/apps/togadesk/features/email-to-ticket-intake.md +5 -2
- package/knowledge/1.0/apps/togadesk/features/ticket-lifecycle.md +5 -2
- package/knowledge/1.0/apps/tools/INDEX.md +1 -0
- package/knowledge/1.0/apps/tools/architecture.md +1 -0
- package/knowledge/1.0/apps/tools/features/central-ids.md +38 -0
- package/knowledge/1.0/apps/tools/features/clickup-sprint-dashboard.md +5 -2
- package/knowledge/1.0/apps/tools/features/developer-tools.md +3 -1
- package/knowledge/2.0/apps/_underscore/INDEX.md +1 -1
- package/knowledge/2.0/apps/_underscore/features/apirequest-json-content-type.md +5 -2
- package/knowledge/2.0/apps/_underscore/features/sales-order-denial-reason.md +5 -2
- package/knowledge/2.0/apps/_underscore/features/togaiq-gateway-client.md +10 -7
- package/knowledge/2.0/apps/api2/INDEX.md +1 -1
- package/knowledge/2.0/apps/api2/features/environment-variable-drives-underscore-branch.md +5 -2
- package/knowledge/2.0/apps/api2/features/record-scripts.md +7 -4
- package/knowledge/2.0/apps/api2/features/sprint-dashboard-api.md +7 -4
- package/knowledge/2.0/apps/dbchanges2/architecture.md +5 -4
- package/knowledge/2.0/apps/talos/INDEX.md +6 -6
- package/knowledge/2.0/apps/talos/architecture.md +7 -5
- package/knowledge/2.0/apps/talos/features/aegra-api.md +6 -3
- package/knowledge/2.0/apps/talos/features/chat-frontend.md +7 -4
- package/knowledge/2.0/apps/talos/features/deployment.md +7 -4
- package/knowledge/2.0/apps/talos/features/mcp-servers.md +5 -2
- package/knowledge/2.0/apps/talos/features/observability.md +7 -4
- package/knowledge/2.0/apps/talos/features/pricing-cogs-model.md +6 -3
- package/knowledge/2.0/apps/talos/features/talos-agent.md +5 -2
- package/knowledge/2.0/apps/talos-backend/INDEX.md +2 -2
- package/knowledge/2.0/apps/talos-backend/workflows/toga-supply-client-onboarding.md +8 -5
- package/knowledge/2.0/apps/toga-blox/features/talos-assistant.md +6 -3
- package/knowledge/2.0/apps/toga25-desk/INDEX.md +5 -0
- package/knowledge/2.0/apps/toga25-desk/architecture.md +22 -0
- package/knowledge/2.0/apps/toga25-iq/INDEX.md +5 -0
- package/knowledge/2.0/apps/toga25-iq/architecture.md +22 -0
- package/knowledge/2.0/apps/worker2/INDEX.md +2 -2
- package/knowledge/2.0/apps/worker2/features/committed-secrets-and-config-debt.md +5 -2
- package/knowledge/2.0/apps/worker2/features/talos-meeting-notes-integration.md +7 -4
- package/knowledge/2.0/apps/worker2/features/talos-transcript-ingestion.md +6 -3
- package/knowledge/2.0/apps/worker2/features/team-sprint-management.md +12 -9
- package/knowledge/2.0/standards/framework-rules.md +1 -1
- package/knowledge/INDEX.md +5 -3
- package/knowledge/clients/compass-canada/features/french-order-email-localization.md +9 -6
- package/knowledge/clients/true/profile.md +1 -1
- package/knowledge/registry.json +16 -2
- package/knowledge/standalone/apps/claude/workflows/mcp-tool-usage.md +6 -2
- package/package.json +1 -1
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
| [@goagilant.com → @togatech.com Email-Domain Migration (1.0 + 2.0)](features/goagilant-to-togatech-email-migration.md) | Reference + safe-rename technique for the @goagilant.com → @togatech.com email-domain migration across 1.0 + 2.0: the per-env email-column blast-radius map and |
|
|
14
14
|
| [Static (no-DB) Regression Harness for 1.0 Logic + Source Drift Guard](features/static-no-db-regression-harness.md) | Technique for unit-testing 1.0 logic statically (no DB, no bootstrap) via `App_Database::sqlEscape()` being pure str_replace, plus a source-drift guard for mirr |
|
|
15
15
|
| [TableView Builder (2.0 TableViews SQL generator)](features/tableview-builder.md) | Standalone tool that turns a plain SQL SELECT into 2.0 TableViews/TableViewFields/TableViewJoins INSERTs (review-first output); open to generate TableView metad |
|
|
16
|
-
| [Talos Knowledge Base Pipeline (Uploader + Processor)](features/talos-kb-pipeline.md) | Two-script web tooling (kb_uploader + kb_processor) feeding the TOGa Talos
|
|
16
|
+
| [Talos Knowledge Base Pipeline (Uploader + Processor)](features/talos-kb-pipeline.md) | Two-script web tooling (kb_uploader + kb_processor) feeding the TOGa Talos AI knowledge bases via S3 → AWS Bedrock; open for the S3 layout, approve/sync flow, o |
|
|
17
17
|
| [TOGa 2.0 Client Onboarding SQL Generator](features/toga2-client-onboarding-sql.md) | 1.0 App_ script generating 2.0 client-onboarding SQL (Core inserts + client-DB Apis/Apis_Roles); superseded by the browser wizard; open for the insert-generatio |
|
|
18
18
|
| [TOGa 2.0 Client Onboarding Wizard (local tool)](features/toga2-onboarding-wizard.md) | Local browser wizard automating 2.0 client onboarding end-to-end (generates all onboarding SQL + consolidates dbchanges2 loose SQL); local-only, renders secrets |
|
|
19
19
|
| [TOGa 2.0 User Cross-Client Access SQL Generator](features/toga2-user-cross-client-access-sql.md) | 1.0 App_ script generating SQL to grant an existing 2.0 user cross-client access (Users_Roles grants); open when granting a home-client user into another client |
|
|
@@ -6,7 +6,7 @@ project: Test
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: [jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- test/team/talos/kb_uploader.php
|
|
@@ -16,11 +16,11 @@ related:
|
|
|
16
16
|
- ../architecture.md
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
-
Two-script web tooling (kb_uploader + kb_processor) feeding the TOGa Talos
|
|
19
|
+
Two-script web tooling (kb_uploader + kb_processor) feeding the TOGa Talos AI knowledge bases via S3 → AWS Bedrock; open for the S3 layout, approve/sync flow, or the plaintext-credentials security issue.
|
|
20
20
|
|
|
21
21
|
## Summary
|
|
22
22
|
|
|
23
|
-
`team/talos/` holds the two-script web tooling that feeds the **TOGa Talos**
|
|
23
|
+
`team/talos/` holds the two-script web tooling that feeds the **TOGa Talos** AI knowledge bases. Content flows through S3 folders and ends up in **AWS Bedrock** knowledge bases, which back the internal AI agent that answers developer questions.
|
|
24
24
|
|
|
25
25
|
- **`kb_uploader.php`** — the *intake* page. A user pastes a meeting transcript or uploads a document; it lands in the S3 `upload/` folder of a chosen knowledge base.
|
|
26
26
|
- **`kb_processor.php`** — the *review/approve* console. A reviewer cleans transcripts (AI + automated text rules), approves files into the `approved/` folder, writes a Bedrock metadata sidecar, archives the raw source, and triggers a Bedrock ingestion (sync) job.
|
|
@@ -67,7 +67,7 @@ The page lists everything in every KB's `upload/` folder, split into **meetings*
|
|
|
67
67
|
|
|
68
68
|
#### Transcript cleaning (`prepare_transcript`)
|
|
69
69
|
|
|
70
|
-
1. **AI cleaning** — `callAICleaningAPI()` POSTs to `AI_API_ENDPOINT` (the TOGa
|
|
70
|
+
1. **AI cleaning** — `callAICleaningAPI()` POSTs to `AI_API_ENDPOINT` (the TOGa Talos AI service, model `AI_MODEL_ID`, Bedrock Claude Haiku 4.5) with an `output_schema` requesting a single `knowledge_doc` string. The lengthy `AI_SYSTEM_PROMPT` enforces a strict lossless plain-text format (OVERVIEW + topical sections, verbatim code blocks, PascalCase tables / camelCase columns). Retries twice with backoff on network errors and HTTP 429/5xx.
|
|
71
71
|
2. **Automated cleaning** — `applyAutomatedCleaning()` strips markdown artifacts (backticks, `> ` quoting, `# ` headings), normalizes blank lines around headings/lists, removes `:contentReference[...]` markers, and applies the `REPLACEMENTS[...]` map from the ini (mishear corrections, e.g. `Talus → Talos`). Replacement keys support `:c` (case-sensitive) and `:w` (whole-word) flags.
|
|
72
72
|
3. For meeting files, a `YYYY-MM-DD - Title` header is prepended.
|
|
73
73
|
|
|
@@ -94,6 +94,9 @@ Shared by both scripts via `parse_ini_file(..., true)`. Sections: AWS creds/regi
|
|
|
94
94
|
- **Filename convention is load-bearing**: the `YYYY-MM-DD - Name.txt` pattern is the only thing that distinguishes a meeting (gets AI cleaning) from a document (copied as-is).
|
|
95
95
|
- Batch sync state lives in `$_SESSION['sync_progress']` and is driven by front-end polling (`sync_next_kb`), one KB per request with a `KB_SYNC_DELAY_SECONDS` pause between.
|
|
96
96
|
|
|
97
|
+
## Change history
|
|
98
|
+
- 2026-09-25 — renamed product references from "TOGa IQ" to "TOGa Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
99
|
+
|
|
97
100
|
## Related
|
|
98
101
|
|
|
99
102
|
- [Test architecture](../architecture.md)
|
|
@@ -6,7 +6,7 @@ project: TOGa Desk
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: architecture
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["mhammontree", "jcardinal"]
|
|
11
11
|
files:
|
|
12
12
|
- desk/index.php
|
|
@@ -87,7 +87,7 @@ Crons live at the **repo root** (`crons/`), bootstrapped via the library framewo
|
|
|
87
87
|
- `monitoring.php` — `Monitoring::runAll()` host/port checks + up/down alerts.
|
|
88
88
|
- `pipe.php` — postfix stdin push variant; `general.php` — stub.
|
|
89
89
|
|
|
90
|
-
External integrations: **Talos
|
|
90
|
+
External integrations: **Talos** AI (ticket summaries / improved replies), **Syncro** PSA status push (when `tickets.referenceId='SYNCRO'`), **S3** (`asifiles`, `App_Cloud::copyFileToS3()`), **Sentry** (client-side JS), **PHPMailer** SMTP, and **NetSuite** customer id captured on SMB contracts. The `controllers/actions/toga/` and `controllers/data/toga/` subsystems bridge to the **TOGA** database (inventory items/levels/orders, SMB contracts, customer renewals).
|
|
91
91
|
|
|
92
92
|
## System topology
|
|
93
93
|
| System | Serves | DB connections |
|
|
@@ -6,7 +6,7 @@ project: TOGa Desk
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["jcardinal", "dfranks", "mhammontree"]
|
|
11
11
|
files:
|
|
12
12
|
- crons/tickets.php
|
|
@@ -37,7 +37,7 @@ TOGa Desk ingests support email into tickets through a cron-driven IMAP poller (
|
|
|
37
37
|
2. **Poll:** connect to `outlook.office365.com:993` INBOX and loop for ~22 minutes (header comment suggests running every ~30 min), processing each message then deleting it.
|
|
38
38
|
3. **Parse & route (`emailToTicket()`):** extract from/to/cc/subject/body (with encoding fixes); match an existing ticket via `In-Reply-To` + `Message-ID` headers and **plus-addressing** (`support+<ticketnum>@…`). Matched ⇒ `addReply()`; otherwise ⇒ `add()`.
|
|
39
39
|
- **Noise suppression (before any ticket/attachment is created):** both feeders drop known automated no-noise mail via the shared helper `Ticket::isSuppressedNoiseEmail(?string $from, ?string $subject): bool` (static, in `class.ticket.php`). It returns true only when the sender matches `/^no-?reply@/` **AND** the subject starts with `staples po ` — both required so a real person is never blocked, and the sender check is **domain-agnostic** (matches `noreply@togatech.com` / `noreply@goagilant.com` and survives future sender-domain flips; the Staples PO alert sender flipped `goagilant.com → togatech.com` on 2026-06-02). Wired into BOTH intake feeders: `crons/tickets.php` adds it as one more `&&`-clause in the existing IMAP intake guard (alongside the delivery-status / `MAILER-DAEMON` / Compass auto-reply filters); `crons/pipe.php` uses it as an early guard-and-`exit(0)` right after the `$from`/`$subject` parse. Each feeder logs a "suppressed" line. (TRUE-79975 — ~815 such alerts since Jun 2024, ~704 of them landing in the dept-1 "Support Desk" catch-all and being closed by hand.)
|
|
40
|
-
4. **Side effects:** auto-create a user when the sender domain maps to an existing client; assign to a department via the department email lookup; save attachments locally then push to **S3** (`App_Cloud::copyFileToS3()`, bucket `asifiles`); optionally generate Talos
|
|
40
|
+
4. **Side effects:** auto-create a user when the sender domain maps to an existing client; assign to a department via the department email lookup; save attachments locally then push to **S3** (`App_Cloud::copyFileToS3()`, bucket `asifiles`); optionally generate Talos summaries.
|
|
41
41
|
5. **Post-pass:** `Ticket::processRules()` (escalation) and `Ticket::autoClose()` (SLA auto-close) run after the mailbox sweep.
|
|
42
42
|
|
|
43
43
|
### Data model
|
|
@@ -76,6 +76,9 @@ Ruled out as user-creation sources (do not re-chase):
|
|
|
76
76
|
- Attachments are deleted locally immediately after the S3 upload with **no retry** if S3 fails.
|
|
77
77
|
- **`adminid` clobber on reply routing:** after `emailToTicket()` sets `$data['adminid']` from the FROM address (~line 1407), an asset lookup (~line 1437-1442) overwrites it with the replying user's asset's assigned admin. On a matched-ticket reply this makes a user's email look like a staff reply in `addReply()` (`isAdminReply=true`), so `Awaiting User` etc. never transition. The asset-derived adminid is for NEW-ticket auto-assign in `add()`, not reply classification. See the ticket-lifecycle doc.
|
|
78
78
|
|
|
79
|
+
## Change history
|
|
80
|
+
- 2026-09-25 — renamed product reference from "TogaIQ" to "Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
81
|
+
|
|
79
82
|
## Related
|
|
80
83
|
- [TOGa Desk architecture](../architecture.md)
|
|
81
84
|
- [Ticket lifecycle](ticket-lifecycle.md)
|
|
@@ -6,7 +6,7 @@ project: TOGa Desk
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["mhammontree", "dfranks"]
|
|
11
11
|
files:
|
|
12
12
|
- desk/includes/classes/class.ticket.php
|
|
@@ -60,7 +60,7 @@ When the caller supplies no status, a `switch ($ticket['status'])` decides. Patt
|
|
|
60
60
|
- **`origin` is the reliable "reply came from outside Desk" signal.** The in-app agent reply path (`addReply.php` → `addReply($_POST)`) carries **no `origin` key**, whereas `emailToTicket()` sets `tickets.origin = 'EMAIL'` and togaview sets `'TOGAVIEW'` on new tickets. Absence of `origin` on a reply identifies an in-app agent reply; presence identifies an external reply. This is the safe hook for any "external reply → status" logic.
|
|
61
61
|
- Special case: an admin replying to their OWN ticket is treated as a user reply.
|
|
62
62
|
- Auto-assign on first staff reply requires the role perm `allowAutoAssign` via profiles/profile_departments.
|
|
63
|
-
- Side integrations on reply: Syncro status push (`referenceId='SYNCRO'`), Talos AI summaries
|
|
63
|
+
- Side integrations on reply: Syncro status push (`referenceId='SYNCRO'`), Talos AI summaries, merged-ticket fan-out (replies propagate to child tickets).
|
|
64
64
|
|
|
65
65
|
### Data model
|
|
66
66
|
- `TOGaDeskSupport.tickets` — `clientid`, `customerid` (TOGA `Customers.id`, drives MSP portal visibility), `departmentid`, `email`, `status`. **No closed-date column.**
|
|
@@ -75,6 +75,9 @@ When the caller supplies no status, a `switch ($ticket['status'])` decides. Patt
|
|
|
75
75
|
- **Cross-app DB coupling:** togadesk and togaview share the `TOGaDeskSupport` database (`tickets`, `tickets_replies`, `tickets_history`, `people`), so a reply/status behavior change on either side is visible to both immediately. togaview cannot load Desk's `class.ticket.php`, so its writes go through the `App_Model_TogaDesk_*` models (`TicketReply`, `TicketsHistory`, `Ticket`) — any shared status logic must account for the portal path never instantiating `Ticket`.
|
|
76
76
|
- Legacy `togadesk/includes/class.ticket.php` has active email-reopen logic; the live `desk/includes` version has it commented out — email replies never set status to "Reopened" via `emailToTicket()`.
|
|
77
77
|
|
|
78
|
+
## Change history
|
|
79
|
+
- 2026-09-25 — renamed product reference from "TogaIQ" to "Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
80
|
+
|
|
78
81
|
## Related
|
|
79
82
|
- [SMB contract editing](smb-contract-editing.md)
|
|
80
83
|
- [TOGa View MSP dashboard](../../togaview/features/msp-dashboard.md)
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
| Doc | Summary |
|
|
4
4
|
|-----|---------|
|
|
5
5
|
| [Tools (1.0 Internal-Tools App) Architecture](architecture.md) | Standalone 1.0 (App_) internal-tools app (Client_True staff personas, SAML `?saml=` auth, folder-based MVC); open for boot/session model, adding a tool, wall-di |
|
|
6
|
+
| [Tools — Central IDs (next Core.Records / Core.RecordFields id)](features/central-ids.md) | Tools page `/developers/central-ids` — source of truth for the next team-reserved `Core.Records` / `Core.RecordFields` id; open to take an id before writing dbc |
|
|
6
7
|
| [/clickup/aliases — ClickUp Label-Alias Admin (Tools → 2.0 Team schema)](features/clickup-label-aliases-admin.md) | Human side of the NetSuite→ClickUp Stakeholders/End-Customer labels at `/clickup/aliases`: point an unresolved company name at a ClickUp option in `Team.ClickUp |
|
|
7
8
|
| [Developer Dashboard (ClickUp Sprint, tools /developer)](features/clickup-sprint-dashboard.md) | Native ClickUp sprint dashboard in the 1.0 tools app at `/developer` (TV wall display), reading the Team DB via `/v2/sprints/*`; open for the data engine, the C |
|
|
8
9
|
| [CloudFront Client Setup](features/cloudfront-client-setup.md) | SSO-gated Tools admin at `/devops/cloudfront-clients` that onboards a client onto CloudFront + Route 53 across multiple AWS accounts in one run; open for the to |
|
|
@@ -31,6 +31,7 @@ related:
|
|
|
31
31
|
- ./features/saml-sso-auth.md
|
|
32
32
|
- ./features/persona-gated-navigation.md
|
|
33
33
|
- ./features/developer-tools.md
|
|
34
|
+
- ./features/central-ids.md
|
|
34
35
|
- ./features/multi-client-sql.md
|
|
35
36
|
- ./features/oneuptime-monitor-status-panel.md
|
|
36
37
|
- ./features/github-audit.md
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tools — Central IDs (next Core.Records / Core.RecordFields id)
|
|
3
|
+
framework: "1.0"
|
|
4
|
+
repo: tools
|
|
5
|
+
project: Tools
|
|
6
|
+
client: shared
|
|
7
|
+
type: feature
|
|
8
|
+
status: active
|
|
9
|
+
updated: 2026-09-25
|
|
10
|
+
owners: [jcardinal]
|
|
11
|
+
files:
|
|
12
|
+
- tools/_/app/developers/centralids.php
|
|
13
|
+
- tools/mvc/developers/central-ids/get.php
|
|
14
|
+
- tools/mvc/developers/central-ids/post.php
|
|
15
|
+
- tools/_/app/nav.php
|
|
16
|
+
related:
|
|
17
|
+
- ../architecture.md
|
|
18
|
+
- ./developer-tools.md
|
|
19
|
+
- ./persona-gated-navigation.md
|
|
20
|
+
- ../../../../2.0/apps/dbchanges2/architecture.md
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
Tools page `/developers/central-ids` — source of truth for the next team-reserved `Core.Records` / `Core.RecordFields` id; open to take an id before writing dbchanges2 SQL, or to change the tool's compare-and-set rules.
|
|
24
|
+
|
|
25
|
+
## Summary
|
|
26
|
+
Replaces tracking next central ids in the developer chat. Branches hold hardcoded ids for weeks, so AUTO_INCREMENT/MAX(id) cannot be trusted. **Take the id here before writing SQL.**
|
|
27
|
+
|
|
28
|
+
## How it works
|
|
29
|
+
- Storage: prod `Core.Parameters` (`id`, `uuid` char36 unique, `key` varchar64 unique, `value` varchar255), keys `NEXT_CORE_RECORDS_ID`, `NEXT_CORE_RECORD_FIELDS_ID`. Read via config `[database_toga2core]` (link `db_toga2core`; tools is prod-only).
|
|
30
|
+
- Access: Developers folder, **Development Team** persona only — hardcoded `requireAuth` in `get.php` + `post.php`, narrowed in `nav.php`.
|
|
31
|
+
- UI: one card per key showing stored value + table's current `MAX(id)`; number box + Save; "Take 1" saves shown value + 1.
|
|
32
|
+
- `App_Developers_CentralIds`: `all()`, `set($key, $newValue, $expected)`. `post.php` actions `load`, `set`.
|
|
33
|
+
- Save rules: refused if value <= `MAX(id)` of the tracked table or > INT UNSIGNED max. Compare-and-set: `UPDATE ... WHERE value = expected`; missing row → `INSERT IGNORE` with `App_String::generateUuidV4()`. Loser of a race gets "someone changed this value". Table names only from hardcoded `KEYS` const. Each change `error_log`'d with user uuid.
|
|
34
|
+
- First Save creates the Parameters row — no dbchanges2 file needed.
|
|
35
|
+
|
|
36
|
+
## Gotchas
|
|
37
|
+
- Cannot detect an id used without taking it here first (accepted limit) — team practice: take in tool, then write SQL.
|
|
38
|
+
- 2026-09-25: neither key existed in prod yet; prod MAX(id) was Records 364, RecordFields 2633.
|
|
@@ -6,7 +6,7 @@ project: Tools
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: [kyalamarthi, jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- tools/_/app/clickup/sprint.php
|
|
@@ -34,7 +34,7 @@ Native ClickUp sprint dashboard in the 1.0 tools app at `/developer` (TV wall di
|
|
|
34
34
|
|
|
35
35
|
## Summary
|
|
36
36
|
|
|
37
|
-
A native **ClickUp sprint dashboard** in the 1.0 `tools` app at route `/developer` (the **"Developer Dashboard"**, renamed from `/clickup/react` / "Clickup" — see the rename note below), built for a wall-mounted **TV display** ("TOGa
|
|
37
|
+
A native **ClickUp sprint dashboard** in the 1.0 `tools` app at route `/developer` (the **"Developer Dashboard"**, renamed from `/clickup/react` / "Clickup" — see the rename note below), built for a wall-mounted **TV display** ("TOGa Talos" internal sprint metrics). It replaces a standalone Node/Express prototype from a prior session, folding the dashboard into `tools` so it runs on the existing App\_ framework + SSO with no separate service.
|
|
38
38
|
|
|
39
39
|
The page is now a **two-column split**: this sprint board at 75%, and an operational **monitor status column** filling the rest — documented separately in [OneUptime Monitor Status Panel](./oneuptime-monitor-status-panel.md). The sprint board itself was left byte-for-byte unchanged when that landed (its component was renamed `SprintBoard` and wrapped in a two-line `Dashboard`).
|
|
40
40
|
|
|
@@ -104,6 +104,9 @@ Registered under the **"Dashboard"** nav folder as `['label'=>'Developer','route
|
|
|
104
104
|
- **`crypto.randomUUID()` crashes the page to a black screen on a non-secure origin.** The page stamps a per-request `transactionId` header with `crypto.randomUUID()`, which exists **only in a secure context**; over plain HTTP by hostname/LAN IP it is `undefined` and throws before React mounts. Guarded by a `transactionId()` helper (randomUUID → getRandomValues v4 → non-crypto id). Full write-up in [the monitor panel doc](./oneuptime-monitor-status-panel.md).
|
|
105
105
|
- **The old Power BI embed page (`mvc/clickup/dashboard/get.php`) keeps ~6 fixed colour literals on purpose — do NOT theme them.** Its card/frame colour `#0b1020` is matched to the embedded Power BI report canvas so nothing flashes white while the iframe loads. Themed surfaces there would reintroduce the flash in one theme or the other. Everything else on the page was tokenised for the app-wide theme — see [App-Wide Colour Theme](./theme-light-dark.md).
|
|
106
106
|
|
|
107
|
+
## Change history
|
|
108
|
+
- 2026-09-25 — renamed product reference from "TOGa IQ" to "TOGa Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
109
|
+
|
|
107
110
|
## Related
|
|
108
111
|
- [OneUptime Monitor Status Panel](./oneuptime-monitor-status-panel.md)
|
|
109
112
|
- [Persona-gated navigation](./persona-gated-navigation.md)
|
|
@@ -6,7 +6,7 @@ project: Tools
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: [jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- tools/mvc/developers/uuid/get.php
|
|
@@ -16,6 +16,7 @@ related:
|
|
|
16
16
|
- ../architecture.md
|
|
17
17
|
- ./persona-gated-navigation.md
|
|
18
18
|
- ./mvc-data-access-patterns.md
|
|
19
|
+
- ./central-ids.md
|
|
19
20
|
---
|
|
20
21
|
|
|
21
22
|
Tools "Developers" folder — the Generate UUID and Generate Password tools (reference example of the one-tool-per-`mvc/<route>/get.php` pattern); open for the generators or the bcrypt 72-byte gotcha.
|
|
@@ -42,3 +43,4 @@ The first two tools shipped in the Tools app, both under the **Developers** fold
|
|
|
42
43
|
- [Tools architecture](../architecture.md)
|
|
43
44
|
- [Persona-gated navigation](./persona-gated-navigation.md)
|
|
44
45
|
- [Tools MVC — data-access patterns](./mvc-data-access-patterns.md)
|
|
46
|
+
- [Central IDs](./central-ids.md) — next Core.Records / RecordFields id
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
| [Surface Resolver (_Model_Core_Surface::resolve — replaces Page::meta)](features/surface-resolver.md) | Runtime for the platform Surface UI layer (`_Model_Core_Surface::resolve`/`metaGroup`, replaces `Page::meta`); open for surface resolution, the override cascade |
|
|
57
57
|
| [Table-View Hyperlink Columns (meta → ACL → computed URL → render)](features/tableview-hyperlink-columns.md) | How a 2.0 table-view column renders its value as a clickable link (`hyperlinkRecordFieldId` → ACL field-read → computed URL → render); open when a configured hy |
|
|
58
58
|
| [TableView joins (TableViewJoins → SQL) — aliasing, chained multi-hop joins, ACL](features/tableview-joins.md) | How `TableViewJoins` rows become a view's join SQL — aliasing, chained multi-hop joins, ACL gating, and the three ways a view breaks; open before adding/rebasin |
|
|
59
|
-
| [
|
|
59
|
+
| [Talos Gateway Client (_Component_Api_Togaiq) — AI generate/translate from 2.0](features/togaiq-gateway-client.md) | The 2.0 client for the Talos AI gateway (`_Component_Api_Togaiq`); open to call an LLM (generate/translate) from a 2.0 model/interceptor, or to debug "translati |
|
|
60
60
|
| [Tracking-Number Bridge Migration (ASN / Item Fulfillment / Item Receipt)](features/tracking-number-bridges.md) | How tracking numbers moved from scalar FK columns to `*_TrackingNumbers` bridge tables across ASN/IF/IR; open before writing/reading tracking, choosing which br |
|
|
61
61
|
| [Units for Items for Purchase Orders — Data Structure](features/units-for-items-for-purchase-orders.md) | How unit (serialized inventory) data links to sales-order/purchase-order line items behind the `units-for-items-for-purchase-orders` view; open when units don't |
|
|
62
62
|
| [Users.email is a login identity — the forgot-password chain and tenant routing that depend on it](features/user-email-as-identity-and-password-reset.md) | Why `Users.email` in 2.0 is a login identity + tenant-routing key (forgot-password takeover primitive, domain routing); open before building any UI/job that edi |
|
|
@@ -6,7 +6,7 @@ project: _Underscore
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["jcardinal", "ajean", "rgirish", "kyalamarthi"]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/ApiRequest.php
|
|
@@ -152,8 +152,11 @@ case-insensitive scan of already-set headers, so a caller-supplied `Content-Type
|
|
|
152
152
|
- **`Logs.Api` is 1.4M+ rows and `source` is NOT indexed.** Any diagnostic query must be bounded by
|
|
153
153
|
`dtStamp` (indexed) or it times out — `WHERE source = '…'` alone will not return.
|
|
154
154
|
|
|
155
|
+
## Change history
|
|
156
|
+
- 2026-09-25 — renamed product reference from "TogaIQ" to "Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
157
|
+
|
|
155
158
|
## Related
|
|
156
159
|
- [OneUptime worker2 monitoring](../../worker2/features/oneuptime-worker2-monitoring.md)
|
|
157
160
|
- [Creating Worker Actions](../../worker2/features/creating-worker-actions.md)
|
|
158
161
|
- [Talos transcript ingestion](../../worker2/features/talos-transcript-ingestion.md)
|
|
159
|
-
- [
|
|
162
|
+
- [Talos gateway client](togaiq-gateway-client.md)
|
|
@@ -6,7 +6,7 @@ project: _Underscore
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: [apeterson, tcox]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Model/Client/ApprovalDecision.php
|
|
@@ -69,7 +69,7 @@ Nothing on the write path needs changing.
|
|
|
69
69
|
### Who reads it today — the rejection email, and only the rejection email
|
|
70
70
|
|
|
71
71
|
Both consumers read `$payload->note` and fall back to `SELECT note FROM ApprovalDecisions WHERE uuid = …` when the payload does not carry it.
|
|
72
|
-
- **Compass USA + Compass Canada** — `_Model_Compass_ApprovalDecision::sendRejectionEmailToUser()` → `buildRejectionNoteHtml()` (~L493, ~L904, ~L934). Canada machine-translates EN↔FR through
|
|
72
|
+
- **Compass USA + Compass Canada** — `_Model_Compass_ApprovalDecision::sendRejectionEmailToUser()` → `buildRejectionNoteHtml()` (~L493, ~L904, ~L934). Canada machine-translates EN↔FR through Talos; **US passes the note through verbatim** because the client gate fails closed (see the "Compass US is deliberately excluded from the rejection-note translation" gotcha in [approval-decision-flow](../../../clients/compass-usa/features/approval-decision-flow.md)).
|
|
73
73
|
- **Quad** — `_Model_Quad_ApprovalDecision::handleApprovalDecision()` sends `TEMPLATE_REQUEST_DENIED` with a `{note}` token. **Quad does not extend the Compass parent** — a separate implementation, so a change to the Compass rejection-note path does not reach Quad and vice versa.
|
|
74
74
|
|
|
75
75
|
**No other reader exists in any deployed environment.** `toga2-commerce` still renders nothing; the `toga25-supply` banner + timeline exist only on the unmerged `TRUE-80850` branches (+ the `client-sandbox` seeds).
|
|
@@ -158,6 +158,9 @@ Verified on `client-sandbox` 2026-08-31: banner + read-only timeline render for
|
|
|
158
158
|
- **`salesOrderNotes` is not the denial reason.** The commerce OrderDetails view renders `salesOrderNotes` (request/shipping/delegate note types on a different table). Reading that code and concluding "the note is already displayed" is the trap.
|
|
159
159
|
- **"Canceled" does not mean "denied."** ~1% of Compass canceled orders have no denial behind them. Anything keyed on `_status in ["canceled"]` must tolerate a missing decision/note.
|
|
160
160
|
|
|
161
|
+
## Change history
|
|
162
|
+
- 2026-09-25 — renamed product reference from "TogaIQ" to "Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
163
|
+
|
|
161
164
|
## Related
|
|
162
165
|
- [Compass Approval-Decision Flow](../../../clients/compass-usa/features/approval-decision-flow.md)
|
|
163
166
|
- [MR/MA order approval and status](../../../clients/compass-usa/features/mr-ma-order-approval-and-status.md)
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "
|
|
2
|
+
title: "Talos Gateway Client (_Component_Api_Togaiq) — AI generate/translate from 2.0"
|
|
3
3
|
framework: "2.0"
|
|
4
4
|
repo: _underscore
|
|
5
5
|
project: _Underscore
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["bala"]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Component/Api/Togaiq/Togaiq.php
|
|
@@ -20,11 +20,11 @@ related:
|
|
|
20
20
|
- ../../../clients/compass-canada/features/french-order-email-localization.md
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
The 2.0 client for the
|
|
23
|
+
The 2.0 client for the Talos AI gateway (`_Component_Api_Togaiq`); open to call an LLM (generate/translate) from a 2.0 model/interceptor, or to debug "translation returned nothing".
|
|
24
24
|
|
|
25
25
|
## Summary
|
|
26
26
|
|
|
27
|
-
`_Component_Api_Togaiq` is the 2.0 framework's client for the **
|
|
27
|
+
`_Component_Api_Togaiq` is the 2.0 framework's client for the **Talos** AI gateway. It POSTs to `<backend_url>/api/ai/generate` and returns the model's structured output, so any 2.0 model/interceptor can call an LLM without hand-rolling curl. Its first consumer is the Compass Canada rejection-note translation.
|
|
28
28
|
|
|
29
29
|
It is an ordinary sibling of the other `Component/Api/*` clients (`Clickup`, `Elite`, `Hubspot`, `Netsuite`, `Startech`, `Toga`, `Wje`) — an abstract class of static methods built on `new _ApiRequest(..., _ApiRequest::ENCODE__JSON)`. Follow that shape for any new gateway.
|
|
30
30
|
|
|
@@ -39,8 +39,8 @@ Two design rules here exist because of real failures and should survive any rewr
|
|
|
39
39
|
|
|
40
40
|
- `isConfigured(): bool` — true iff `resolveBackendKey()` is non-empty. **Key only.**
|
|
41
41
|
- `resolveBackendKey()` / `resolveModel()` / `buildGenerateUrl()` — read the `[talos]` config group (`backend_key`, `backend_url`, `model`).
|
|
42
|
-
- `send(string $method, array $payload): array` — the transport. Sets `accept`, `content-type: application/json` and the **`X-API-Key`** header, `setTimeout(12)`, throws on a transport failure (distinguishing `responseCode === 0` = "never reached
|
|
43
|
-
- `translateText(string $text, string $targetLanguageName, ?string $context = null): ?string` — the only high-level helper today. Returns **`null`** (never a throw) when the text is empty,
|
|
42
|
+
- `send(string $method, array $payload): array` — the transport. Sets `accept`, `content-type: application/json` and the **`X-API-Key`** header, `setTimeout(12)`, throws on a transport failure (distinguishing `responseCode === 0` = "never reached Talos" from a cURL error mid-flight) and on any non-200/201, then normalizes `_ApiRequest`'s `stdClass` response into an **array**.
|
|
43
|
+
- `translateText(string $text, string $targetLanguageName, ?string $context = null): ?string` — the only high-level helper today. Returns **`null`** (never a throw) when the text is empty, Talos is unconfigured, or the response carries no translation, so a caller can always keep the words it already had.
|
|
44
44
|
|
|
45
45
|
Constants worth knowing: `CONFIG_GROUP__TALOS = 'talos'`, `DEFAULT__BACKEND_URL = 'https://api.togaiq.com'`, `DEFAULT__MODEL = 'bedrock/amazon.nova-pro-v1:0'`, `ROUTE__AI_GENERATE = '/api/ai/generate'`, `TIMEOUT_SECONDS__INTERACTIVE = 12`, `TEMPERATURE__TRANSLATION = 0.1`, `MAX_TOKENS__TRANSLATION = 1000`.
|
|
46
46
|
|
|
@@ -71,7 +71,7 @@ The hardened prompt (current) states, in order: *"You are a translation engine.
|
|
|
71
71
|
| `backend_url` | no | `https://api.togaiq.com` |
|
|
72
72
|
| `model` | no | `bedrock/amazon.nova-pro-v1:0` |
|
|
73
73
|
|
|
74
|
-
**Credential location only — never copy the value into a doc, a ticket, or a commit.** The
|
|
74
|
+
**Credential location only — never copy the value into a doc, a ticket, or a commit.** The Talos API key lives in the `[talos]` group of `api2/Config/<env>.ini`, and the same key is **also hardcoded** in the 1.0 file `library/app/api/togaiq.php`. That hardcoded copy violates the no-secrets-in-code rule; the key is **due for rotation**, and a rotation must update both places.
|
|
75
75
|
|
|
76
76
|
### Deployment status
|
|
77
77
|
|
|
@@ -85,6 +85,9 @@ Live and working on the **beta** tier (which is the EB environment *named* `api-
|
|
|
85
85
|
- **"It returned nothing" is usually "it was never deployed here."** Before debugging the model, check `Logs_<Client>.Api` for a `direction = 'OUT'` row, and confirm which `_underscore` branch the tier actually cloned — see [api2 Elastic Beanstalk / _underscore clone](../../api2/features/elastic-beanstalk-underscore-clone.md).
|
|
86
86
|
- **The 1.0 `App_Api_TogaIQ` equivalent is NOT reachable from api2.** api2's `include_path` covers `_underscore` only, and the two autoloaders are incompatible. Integration code for 2.0 flows must live here, in `_underscore`.
|
|
87
87
|
|
|
88
|
+
## Change history
|
|
89
|
+
- 2026-09-25 — renamed product references from "TogaIQ" to "Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app); title updated to "Talos Gateway Client" (jcardinal)
|
|
90
|
+
|
|
88
91
|
## Related
|
|
89
92
|
|
|
90
93
|
- [`_ApiRequest` JSON content-type](apirequest-json-content-type.md)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
| [Record Scripts (computed/aggregate /v2 endpoints — the authoring contract)](features/record-scripts.md) | The authoring contract for a Record Script — a `public static` model method that becomes a read-only computed/aggregate `/v2` endpoint (double-nested envelope, |
|
|
18
18
|
| [V2 Request Logging & Where Requests Land (client vs core log DB)](features/request-logging.md) | Where each V2 request lands (client vs core/writer Logs), when it leaves no row at all (PRE-interceptor throw, uncaught fatal), the apiproxy-retry / duplicate-t |
|
|
19
19
|
| [POST + JSON-body args for scripted APIs](features/scripted-api-post-body-args.md) | How the V2 engine runs a Record Script for a POST and lets scripted args arrive in the JSON body (to avoid HTTP 414 on large values); open when a scripted API n |
|
|
20
|
-
| [TOGa
|
|
20
|
+
| [TOGa Talos Sprint Dashboard API (Record Scripts)](features/sprint-dashboard-api.md) | The six api2 Record Scripts on `_Model_Team_Sprint` that serve the internal TOGa Talos sprint dashboard from the `Team` schema; open when consuming/registering |
|
|
21
21
|
| [Surface action-state via the surface=<slug> request option (M2M-safe)](features/surface-meta-option.md) | The opt-in `surface=<slug>` GET option that attaches per-record UI action state under `meta.surface` (never `data`); open when wiring the Surface layer to a scr |
|
|
22
22
|
| [TableView row-filtering via apiWhereClause (options.where grammar, end to end)](features/tableview-apiwhereclause-row-filtering.md) | `TableViews.apiWhereClause` (TEXT, nullable) is the sanctioned, code-free way to restrict or exclude rows from a 2.0 table view. |
|
|
23
23
|
| [TableView field/column metadata (TableViewFields, hidden projected columns)](features/tableview-field-metadata.md) | How a 2.0 table view's columns/order/sort are defined by DB metadata (`TableViews`/`TableViewFields`/`TableViewJoins`), the per-client type override, hidden pro |
|
|
@@ -6,7 +6,7 @@ project: API
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["bala", "mhammontree", "apeterson", "jcardinal", "tcox"]
|
|
11
11
|
files:
|
|
12
12
|
- api2/.ebextensions/git.php
|
|
@@ -109,12 +109,15 @@ So on `api.beta.togahub.com` and `api.dev.sandbox.togahub.com` the code fataled
|
|
|
109
109
|
- **⚠ SECURITY — every `.ebextensions/git.*.json` carries a plaintext GitHub PAT** committed in the repo (used to clone `_underscore`). Pre-existing leak; treat the committed tokens as compromised, rotate, move to EB environment properties / SSM. Do **not** copy the token value anywhere. **Escalated 2026-08-24 — still not rotated, and exposure has WIDENED.** The token is present in **all ~20 per-environment `git.*.json` files**, and an attempted in-place redaction *increased* exposure: BSD `sed` on macOS does not support `\|` alternation, so the command failed in a way that **printed the token value into the session transcript**. Two durable takeaways: (a) rotation is overdue — treat it as an open action item; (b) **do not attempt ad-hoc redaction of a secret with a one-liner** — a failed redaction commonly echoes the value it was meant to hide (GNU-vs-BSD `sed` regex differences make macOS one-liners especially prone). Rotate at the source instead.
|
|
110
110
|
- **Duplicate integration code is the trap this creates.** When the same capability is needed in both tiers it must exist twice (once per framework) — keep the credential/config location documented in both places so a rotation updates both.
|
|
111
111
|
|
|
112
|
+
## Change history
|
|
113
|
+
- 2026-09-25 — renamed product reference from "TogaIQ" to "Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
114
|
+
|
|
112
115
|
## Related
|
|
113
116
|
|
|
114
117
|
- [api2 architecture](../architecture.md)
|
|
115
118
|
- [Environment configuration & provisioning](../workflows/environment-configuration-and-provisioning.md)
|
|
116
119
|
- [CodePipeline / CodeConnections deploy](../workflows/codepipeline-codeconnections-deploy.md)
|
|
117
|
-
- [
|
|
120
|
+
- [Talos gateway client](../../_underscore/features/togaiq-gateway-client.md)
|
|
118
121
|
- [V2 request logging](./request-logging.md)
|
|
119
122
|
- [V2 deadlock retry](./v2-deadlock-retry.md)
|
|
120
123
|
- [Framework branch ahead of schema](../../dbchanges2/workflows/framework-branch-ahead-of-schema.md)
|
|
@@ -6,7 +6,7 @@ project: API
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["kyalamarthi", "mhammontree", "tcox"]
|
|
11
11
|
files:
|
|
12
12
|
- api2/Component/Api/V2/V2.php
|
|
@@ -29,7 +29,7 @@ The authoring contract for a Record Script — a `public static` model method th
|
|
|
29
29
|
|
|
30
30
|
In api2 you almost never write a controller. The generic **/v2 engine** serves models from metadata (Records / RecordFields / ACL rows), so ordinary CRUD is a *data* change, not code. For a payload the metadata CRUD path cannot express — a **computed value, an aggregate, or a purpose-built dashboard tile** — the mechanism is a **Record Script**: a `public static` method on the record's `_Model` whose return value becomes the `/v2` envelope `data`. This is the company-standard way to add a read-only, non-CRUD endpoint. This doc is the **authoring contract** (general pattern + registration). For the POST + JSON-request-body variant, see [POST + JSON-body args for scripted APIs](./scripted-api-post-body-args.md).
|
|
31
31
|
|
|
32
|
-
Motivating example: `_Model_Team_Sprint::committedTile()` — a read-only dashboard tile over the internal TOGa
|
|
32
|
+
Motivating example: `_Model_Team_Sprint::committedTile()` — a read-only dashboard tile over the internal TOGa Talos sprint (`Team` schema) data. **Decision recorded:** internal sprint/dashboard read endpoints are served from **api2 via a Record Script**, not by a bespoke controller or standing the data up inside the talos / TOGa Talos app. Validated by productionizing the whole sprint dashboard into six Record Scripts — see [TOGa Talos Sprint Dashboard API](./sprint-dashboard-api.md). **The model class lives in `_underscore`, not api2** — `_Model_Team_Sprint` is `_underscore/Model/Team/Sprint.php`, pulled in at deploy; api2 has **no `Model/` directory** of its own.
|
|
33
33
|
|
|
34
34
|
## How it works
|
|
35
35
|
|
|
@@ -113,11 +113,14 @@ So for a scripted call, **authorization comes solely from `AclCustomRecordScript
|
|
|
113
113
|
- **`aclDatabase` has no `TEAM`.** A `Team`-schema record registers as `'CORE'`; picking `'CLIENT'` sends the engine looking in the wrong cluster.
|
|
114
114
|
- **⚠ Never hardcode a `Core.RecordScripts` id in a grant — it WILL be renumbered on apply.** Concrete case (verified on production 2026-08-13): `Core/2026-07-15a - CampaignPaylocityJobsRecordScript.sql` wrote the `campaigns`/`jobs` script as **id 25** ("next free; prod max was 24"), and its sibling `Client_True/2026-07-16a - CampaignPaylocityJobsScriptAcl.sql` granted `recordScriptId = 25` — but the row landed as **id 30** in production, so the grants pointed at nothing and a later file (`Client_True/2026-08-05 - CampaignsJobsPublicAcl.sql`) had to re-grant against 30. A grant that references a stale id inserts a row happily and fails **only** at request time as a missing-grant error. Resolve the id by `recordId` + `method` + `route` where the databases allow it, and always verify the actual id in the target environment.
|
|
115
115
|
- **Registration is per-environment and split.** A missing `Core.RecordScripts` row → the route isn't a script (falls through to normal CRUD / 404-shaped behavior); a missing `AclRecordScripts` grant → the caller's roles can't run it. Both rows must exist in every environment the API serves.
|
|
116
|
-
- **The committed-tile definition is intentionally not the sprint-scoring definition.** `committedTile()` uses the **Power BI / current-state** definition of done/committed (`dtDone IS NOT NULL` + `workTypeNow`), which is *deliberately different* from TOGa
|
|
116
|
+
- **The committed-tile definition is intentionally not the sprint-scoring definition.** `committedTile()` uses the **Power BI / current-state** definition of done/committed (`dtDone IS NOT NULL` + `workTypeNow`), which is *deliberately different* from TOGa Talos's canonical sprint scoring (`statusNow IN (STATUS_IN__DONE)` + `workTypeAtLock`). See [Team Sprint Management](../../worker2/features/team-sprint-management.md) before assuming a tile agrees with sprint scores.
|
|
117
|
+
|
|
118
|
+
## Change history
|
|
119
|
+
- 2026-09-25 — renamed product references from "TOGa IQ" to "TOGa Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
117
120
|
|
|
118
121
|
## Related
|
|
119
122
|
|
|
120
|
-
- [TOGa
|
|
123
|
+
- [TOGa Talos Sprint Dashboard API](./sprint-dashboard-api.md) — the concrete six-endpoint set that productionized this contract.
|
|
121
124
|
- [POST + JSON-body args for scripted APIs](./scripted-api-post-body-args.md) — the POST / JSON-request-body variant for large argument values.
|
|
122
125
|
- [api2 architecture](../architecture.md) — the metadata-driven /v2 CRUD engine that Record Scripts extend.
|
|
123
126
|
- [Per-Client Database Connections](../../_underscore/features/per-client-database-connections.md) — why `DB_TEAM` resolves to the core cluster.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: TOGa
|
|
2
|
+
title: TOGa Talos Sprint Dashboard API (Record Scripts)
|
|
3
3
|
framework: "2.0"
|
|
4
4
|
repo: api2
|
|
5
5
|
project: API
|
|
6
6
|
client: shared
|
|
7
7
|
type: feature
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: ["kyalamarthi"]
|
|
11
11
|
files:
|
|
12
12
|
- _underscore/Model/Team/Sprint.php
|
|
@@ -19,11 +19,11 @@ related:
|
|
|
19
19
|
- ../../worker2/features/team-sprint-management.md
|
|
20
20
|
---
|
|
21
21
|
|
|
22
|
-
The six api2 Record Scripts on `_Model_Team_Sprint` that serve the internal TOGa
|
|
22
|
+
The six api2 Record Scripts on `_Model_Team_Sprint` that serve the internal TOGa Talos sprint dashboard from the `Team` schema; open when consuming/registering those endpoints or reconciling current-state vs at-lock scoring.
|
|
23
23
|
|
|
24
24
|
## Summary
|
|
25
25
|
|
|
26
|
-
The internal **TOGa
|
|
26
|
+
The internal **TOGa Talos sprint dashboard** is served in production by **six api2 Record Scripts** on `_Model_Team_Sprint` (`_underscore/Model/Team/Sprint.php`), reading the `Team` schema on the core cluster. This replaced the prior session's local Node/React + Express (mysql2) stand-in — the prototype only proved the metric SQL; this is the real `/v2` path. **No api2 code was written**: the endpoints are the generic `/v2` engine plus the model methods (in `_underscore`) plus metadata rows seeded via dbchanges2. Producer/consumer split: **worker2** (`_Worker_Team_Sprint`) captures ClickUp sprint data into `DB_TEAM`; **api2** serves it read-only through these Record Scripts. The dashboard is internal-only — its `AclRecordScripts` grant is scoped to the **True** (staff) tenant.
|
|
27
27
|
|
|
28
28
|
For the general authoring/registration contract, see [Record Scripts](./record-scripts.md). For the metric definitions, see [Team Sprint Management](../../worker2/features/team-sprint-management.md).
|
|
29
29
|
|
|
@@ -70,6 +70,9 @@ Work-type values in the `Team` schema are stored **UPPERCASE** (`COMMITTED` / `C
|
|
|
70
70
|
- **`_Query` has no bound params** — the `?category=` value is allowlist-mapped to `WORK_TYPE__*` constants; sprint number is `(int)`-cast.
|
|
71
71
|
- Work-type values are stored **UPPERCASE**; source them from `_Model_Team_Task::WORK_TYPE__*`, not mixed-case literals (which only worked via case-insensitive collation).
|
|
72
72
|
|
|
73
|
+
## Change history
|
|
74
|
+
- 2026-09-25 — renamed product references from "TOGa IQ" to "TOGa Talos" (rebrand; TOGa IQ is now the separate `toga25-iq` app) (jcardinal)
|
|
75
|
+
|
|
73
76
|
## Related
|
|
74
77
|
|
|
75
78
|
- [Record Scripts](./record-scripts.md) — the authoring/registration contract.
|
|
@@ -6,7 +6,7 @@ project: Database Changes
|
|
|
6
6
|
client: shared
|
|
7
7
|
type: architecture
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: [jcardinal, mhammontree, bala, ajean]
|
|
11
11
|
files:
|
|
12
12
|
- Core/
|
|
@@ -17,6 +17,7 @@ files:
|
|
|
17
17
|
- _modules/
|
|
18
18
|
related:
|
|
19
19
|
- 2.0/apps/_underscore/architecture.md
|
|
20
|
+
- 1.0/apps/tools/features/central-ids.md
|
|
20
21
|
---
|
|
21
22
|
|
|
22
23
|
The 2.0 SQL change-set repo: folder→database layout, the filename execution contract, and the migration-authoring rules; open for any dbchanges2 schema/data change.
|
|
@@ -131,7 +132,7 @@ Enforced mechanically, not by convention. The `PreToolUse` hook `.claude/hooks/t
|
|
|
131
132
|
|
|
132
133
|
## `Core.Records` / `Core.RecordFields` — the only hardcoded `id`s on the platform
|
|
133
134
|
|
|
134
|
-
These **two tables, and only these two**, have **team-maintained primary keys**. Their `id` values are treated as **stable, platform-wide constants**: the
|
|
135
|
+
These **two tables, and only these two**, have **team-maintained primary keys**. Their `id` values are treated as **stable, platform-wide constants**: the next available value is stored in prod `Core.Parameters` (`NEXT_CORE_RECORDS_ID` / `NEXT_CORE_RECORD_FIELDS_ID`) and managed in **Tools → Developers → Central IDs** (`/developers/central-ids`, see [central-ids](../../../1.0/apps/tools/features/central-ids.md)), and every environment carries the same `id` for the same record/field. Nothing else on the platform may have a hardcoded `id`.
|
|
135
136
|
|
|
136
137
|
This is what makes the *Database isolation* rule practical — it is the reason a `Client_<Tenant>` migration never needs to read `Core` to find a `recordFieldId`.
|
|
137
138
|
|
|
@@ -141,7 +142,7 @@ This is what makes the *Database isolation* rule practical — it is the reason
|
|
|
141
142
|
|
|
142
143
|
```sql
|
|
143
144
|
# Core/2026-07-31a - Add entitlements serviceAddressId field.sql
|
|
144
|
-
# id values 4187, 4188
|
|
145
|
+
# id values 4187, 4188 taken in Tools → Central IDs — do NOT let AUTO_INCREMENT pick.
|
|
145
146
|
INSERT INTO RecordFields (id, uuid, recordId, `field`)
|
|
146
147
|
VALUES (4188, '<pre-generated v4 uuid>', 219, 'serviceAddressId');
|
|
147
148
|
```
|
|
@@ -240,7 +241,7 @@ This lifecycle is automated by a local browser tool — see the [TOGa 2.0 Client
|
|
|
240
241
|
One earlier migration (`Core/2026-05-08 … CronJobs_WorkerCleanup_insert`) used `UUID()` — that is a known violation, not a precedent to copy. First applied correctly in `Core/2026-07-21b - Insert - SprintLockScheduled CronJob.sql`.
|
|
241
242
|
7. **Guard every registration/seed insert with `NOT EXISTS` (or `INSERT IGNORE`).** Rows that register platform behavior — `ApiPayloadInterceptors`, `Core.RecordFields`/`CustomRecordFields`, cron jobs, ACL rows — must be inserted only if not already present. An **unguarded** registration is not merely non-idempotent: on a fresh environment it can run **alongside a second migration that registers the same behavior**, producing a **double registration** (e.g. two interceptor rows for the same record → the interceptor fires twice). A real instance: the Rate WH `prePost` interceptor is registered unguarded in `Client_Rate/2026-07-15 - PreInterceptor.sql` (record 191, `minDepth NULL`); a second guarded registration would have double-fired it. See `clients/rate/features/whole-home-warranty-purchase-guard.md`.
|
|
242
243
|
8. **Never reference a database other than the folder's own target.** No `Core.Table` in a `Client_<Name>/` file, no `Client_X.Table` in a `Core/` file, and **no database qualifier at all** in the fan-out folders (`Client/`, `Logs_Client/`, `_modules/`). These databases are on **separate production clusters**; the query works locally and dies in production. Resolve foreign ids with a hardcoded v4 UUID literal or an in-database slug/natural key, or split the work into one file per database folder. See *Database isolation* above — enforced by the `dbchanges2-cluster-isolation` hook.
|
|
243
|
-
9. **Inserting into `Core.Records` or `Core.RecordFields`? ASK the developer for the next `id
|
|
244
|
+
9. **Inserting into `Core.Records` or `Core.RecordFields`? ASK the developer for the next `id`** (the developer takes it in Tools → Developers → Central IDs — the source of truth; never guess from MAX(id), branches hold unreleased ids). These are the **only two tables on the platform with team-maintained primary keys**. Write the assigned `id` as an explicit literal — **never** let `AUTO_INCREMENT` assign it. Conversely, **always hardcode** these `id`s where they are referenced, including in foreign keys (`recordId`, `recordFieldId`) from other databases. See *`Core.Records` / `Core.RecordFields`* above.
|
|
244
245
|
10. **A fan-out `Client/` file must never reference a `customRecordFieldId` or a client-specific label.** Unlike `Core.RecordFields` ids, `CustomRecordFields` ids are **per-client `AUTO_INCREMENT`** — the same numeric id names a **different field in every client database**. A `Client/` file that hardcodes one silently wires the wrong field for 29 of 30 tenants, and there is no error. The same applies to `ClientCustomRecordFieldSettings` label rows. Move anything touching a custom field into the client's own `Client_<Name>/` file, even when it is "the same change" for several clients. Worked example: the all-clients `inventory_units` table view shipped in `Client/2026-08-11a`, but Elite's four custom columns (`grade`, `chargingBrick`, `chargingCable`, `wipeStatus` via `c_deviceStatus`) and their labels shipped separately in `Client_Elite/`.
|
|
245
246
|
|
|
246
247
|
## Bulk data loads — batch, and stage large sets in a temp table
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# talos (TOGa
|
|
1
|
+
# talos (TOGa Talos) — 2.0 knowledge
|
|
2
2
|
|
|
3
3
|
| Doc | Summary |
|
|
4
4
|
|-----|---------|
|
|
5
|
-
| [TOGa
|
|
5
|
+
| [TOGa Talos (talos) Architecture](architecture.md) | Whole-repo map of TOGa Talos / Aegra (Python AI agent platform); open to understand subsystems, multi-tenancy, or where a component lives. |
|
|
6
6
|
| [aegra-api — Agent Protocol HTTP + Execution Pipeline](features/aegra-api.md) | The FastAPI Agent Protocol server (routers, auth, multi-tenancy, run/streaming pipeline); open when wiring a client to Aegra or debugging runs/SSE/tenancy. |
|
|
7
|
-
| [TOGa
|
|
8
|
-
| [Deployment — Docker, Compose, Entrypoint, External PG/Redis](features/deployment.md) | How TOGa
|
|
7
|
+
| [TOGa Talos Chat Frontend (Next.js) — streaming stack & Aegra wiring](features/chat-frontend.md) | The `talos` repo's browser chat client and reference token-streaming implementation; open when copying Talos streaming into another app (toga25-supply, toga2-de |
|
|
8
|
+
| [Deployment — Docker, Compose, Entrypoint, External PG/Redis](features/deployment.md) | How TOGa Talos / Aegra ships as a single container; open when building the image, running compose, or debugging startup/migration/PG/Redis wiring. |
|
|
9
9
|
| [MCP Servers — clickup-mcp and toga-db-mcp](features/mcp-servers.md) | The two internal FastMCP servers (ClickUp surface + read-only multi-cluster MySQL); open when the agent reads TOGa data, adding a tool, or configuring allowlist |
|
|
10
|
-
| [Observability — Langfuse, OTEL, Prometheus, OneUptime](features/observability.md) | TOGa
|
|
11
|
-
| [Pricing & COGS Model (Talos
|
|
10
|
+
| [Observability — Langfuse, OTEL, Prometheus, OneUptime](features/observability.md) | TOGa Talos's tracing/metrics/uptime stack (Langfuse native, OTEL, Prometheus, OneUptime); open when configuring traces, chasing token double-counts, or wiring e |
|
|
11
|
+
| [Pricing & COGS Model (Talos Pricing Calculator)](features/pricing-cogs-model.md) | Cost basis + pricing methodology for selling Talos chat and voice; open to re-price Talos or understand COGS drivers, token rates, and the band/org-fee model. |
|
|
12
12
|
| [talos_agent — LangGraph ReAct Agent with Plan, BLP, MCP, Canvas](features/talos-agent.md) | The reference LangGraph ReAct agent (graph topology, state, config, tools, MCP, BLP, memory); open when changing agent behavior or adding a tenant capability. |
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: TOGa
|
|
2
|
+
title: TOGa Talos (talos) Architecture
|
|
3
3
|
framework: "2.0"
|
|
4
4
|
repo: talos
|
|
5
|
-
project: TOGa
|
|
5
|
+
project: TOGa Talos
|
|
6
6
|
client: shared
|
|
7
7
|
type: architecture
|
|
8
8
|
status: active
|
|
9
|
-
updated: 2026-09-
|
|
9
|
+
updated: 2026-09-25
|
|
10
10
|
owners: [akhokhani, jcardinal]
|
|
11
11
|
files:
|
|
12
12
|
- talos/libs/aegra-api/src/aegra_api/main.py
|
|
@@ -30,11 +30,13 @@ related:
|
|
|
30
30
|
- ../../1.0/apps/tools/features/talos-pricing-ui.md
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
Whole-repo map of TOGa
|
|
33
|
+
Whole-repo map of TOGa Talos / Aegra (Python AI agent platform); open to understand subsystems, multi-tenancy, or where a component lives.
|
|
34
34
|
|
|
35
35
|
## Summary
|
|
36
36
|
|
|
37
|
-
**TOGa
|
|
37
|
+
**TOGa Talos** = TOGA's AI agent platform. On-disk repo **`talos`** (the "talos backend"). Python/FastAPI implementation of the **Agent Protocol** spec, multi-tenant, with a LangGraph **ReAct agent** as reference agent and internal **MCP servers** for ClickUp and TOGa MySQL clusters.
|
|
38
|
+
|
|
39
|
+
Renamed 2026-09-25: this product was formerly called TOGa IQ; TOGa IQ is now a separate app (`toga25-iq`) that manages the Talos engine.
|
|
38
40
|
|
|
39
41
|
No PHP dependency (unlike `_underscore`, `api2`, `worker2`). Self-contained Python product; consumes TOGa data read-only via `toga-db-mcp`. Lives under `2.0/apps/talos/` because its consumers are 2.0-era apps (TOGa Hub, TOGa View) and TogaHub auth.
|
|
40
42
|
|