toga-ai 1.0.52 → 1.0.54
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/CONVENTIONS.md
CHANGED
|
@@ -24,10 +24,10 @@ knowledge/
|
|
|
24
24
|
├── registry.json # repo ↔ project ↔ framework ↔ role ↔ dependsOn
|
|
25
25
|
├── INDEX.md # auto-generated master index
|
|
26
26
|
├── 1.0/
|
|
27
|
-
│ ├── apps/<repo>/architecture.md + features/*.md
|
|
27
|
+
│ ├── apps/<repo>/architecture.md + features/*.md + workflows/*.md
|
|
28
28
|
│ └── standards/*.md # 1.0 coding standards (App_)
|
|
29
29
|
├── 2.0/
|
|
30
|
-
│ ├── apps/<repo>/architecture.md + features/*.md
|
|
30
|
+
│ ├── apps/<repo>/architecture.md + features/*.md + workflows/*.md
|
|
31
31
|
│ └── standards/*.md # 2.0 coding standards (_underscore)
|
|
32
32
|
└── clients/<client>/
|
|
33
33
|
├── profile.md
|
|
@@ -83,13 +83,33 @@ declares the files it covers, so the doc indexes into the code.
|
|
|
83
83
|
|
|
84
84
|
## Document types
|
|
85
85
|
|
|
86
|
+
The knowledge base is organized by **subject** (a capability, a process, a component), never
|
|
87
|
+
by session or ticket. `capture` assigns the type — **developers never classify.**
|
|
88
|
+
|
|
86
89
|
- **architecture** — how a repo/framework works overall (one per repo). _Elevated._
|
|
87
|
-
- **feature** — a
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
- **feature** — a capability anchored to specific code in a repo (a model, a class, a set of
|
|
91
|
+
files). Its template carries a **How it works** section, so the *process* of a feature lives
|
|
92
|
+
inside the feature doc — most features contain a process, and that does not make them a
|
|
93
|
+
workflow. Lives in `apps/<repo>/features/`.
|
|
94
|
+
- **workflow** — a standalone, multi-step process that **no single capability owns**; it spans
|
|
95
|
+
systems/actors/time. Two homes: operational/system processes in `apps/<repo>/workflows/`
|
|
96
|
+
(e.g. a deploy or reconciliation procedure), and client business processes in
|
|
97
|
+
`clients/<client>/workflows/`.
|
|
98
|
+
- **client-feature** — a client's customization/override of a shared feature; links back to
|
|
99
|
+
the shared `apps/<repo>/features/<base>.md`.
|
|
91
100
|
- **standard** — a coding standard for a framework. _Elevated._
|
|
92
101
|
|
|
102
|
+
**Choosing the type (capture's rule — default to feature):**
|
|
103
|
+
- "Can I point at one capability/model/class that *is* this?" → **feature** (its process goes
|
|
104
|
+
in the *How it works* section).
|
|
105
|
+
- "Is this a sequence of steps spanning systems/actors that is a *procedure*, not a thing?" →
|
|
106
|
+
**workflow.**
|
|
107
|
+
- When in doubt → **feature.** Defaulting prevents workflow-file sprawl.
|
|
108
|
+
|
|
109
|
+
**Bugs are not a type.** A bug fix's durable lesson attaches as a **gotcha** (or a one-line
|
|
110
|
+
*Change history* entry) on the feature/workflow doc that owns the affected code — never a
|
|
111
|
+
standalone doc. Only a recurring/systemic failure class warrants its own record, case by case.
|
|
112
|
+
|
|
93
113
|
_Elevated_ docs (architecture, standard) are senior-owned; `capture` flags any change
|
|
94
114
|
to them with ⚠ so the developer knows what they're approving.
|
|
95
115
|
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
| Doc | Framework | Summary | Files |
|
|
4
4
|
|-----|-----------|---------|-------|
|
|
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 |
|
|
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, api2/Component/Api/Cxml/Cxml.php, dbchanges2/Client_Compass/2026-06-11 - AsnItemTrackingNumberAcl.sql |
|
|
6
6
|
| [Compass: Item Fulfillments for Sales Order Items TableView (tracking via bridge)](features/item-fulfillment-tracking-tableview.md) | 2.0 | The Compass TableView `item-fulfillments-for-sales-order-items` (`TableViews.id = 13` in Client_Compass) was rebuilt as part of the tracking-number bridge migra | dbchanges2/Client_Compass/2026-06-10 - ItemFulfillmentsForSalesOrderItemsTableView.sql |
|
|
7
7
|
| [Compass USA](profile.md) | 2.0 | Compass USA is a TOGA client running a multi-tier supply-chain commerce operation. | |
|
|
@@ -5,10 +5,12 @@ project: _Underscore
|
|
|
5
5
|
client: compass-usa
|
|
6
6
|
type: client-feature
|
|
7
7
|
status: active
|
|
8
|
-
updated: 2026-06-
|
|
8
|
+
updated: 2026-06-11
|
|
9
9
|
owners: [jcardinal]
|
|
10
10
|
files:
|
|
11
11
|
- _underscore/Model/Compass/AdvanceShippingNotice.php
|
|
12
|
+
- api2/Component/Api/Cxml/Cxml.php
|
|
13
|
+
- dbchanges2/Client_Compass/2026-06-11 - AsnItemTrackingNumberAcl.sql
|
|
12
14
|
related:
|
|
13
15
|
- ../../../2.0/apps/_underscore/features/recursive-item-fulfillments.md
|
|
14
16
|
---
|
|
@@ -21,41 +23,81 @@ IFIUs for serialized units, and IF packages for tracking. ASNs arrive two ways:
|
|
|
21
23
|
**cXML** (direct V2 API) and the worker email cron
|
|
22
24
|
`3b_import_strategic_systems_advance_shipping_notices.php`.
|
|
23
25
|
|
|
26
|
+
Tracking numbers are propagated across **every** ASN and IF granularity (see *Tracking number
|
|
27
|
+
propagation* below), so a single ShipNotice tracking number lands at the header, item, and
|
|
28
|
+
unit level on both sides — not just on one unit.
|
|
29
|
+
|
|
24
30
|
## Key files / entry points
|
|
31
|
+
- `api2/Component/Api/Cxml/Cxml.php` — the cXML `ShipNoticeRequest` translator that builds
|
|
32
|
+
the `/advance-shipping-notices` POST payload.
|
|
25
33
|
- `_underscore/Model/Compass/AdvanceShippingNotice.php` — `postPost(&$api, &$payload)`.
|
|
26
34
|
- Fires only when the Compass ASN `ApiPayloadInterceptors` rows exist (interceptor is DB-driven).
|
|
35
|
+
- `Model/Compass/Usa/` and `Model/Compass/Canada/` ASN classes are **empty subclasses** that
|
|
36
|
+
inherit `postPost` from `_Model_Compass_AdvanceShippingNotice` — edit the parent.
|
|
27
37
|
|
|
28
38
|
## How it works
|
|
29
39
|
1. Read ASN → resolve PO → SO via `SalesOrders_PurchaseOrders`; skip if no SO.
|
|
30
40
|
2. Select ASN items whose SOI still has unfulfilled qty (`SOI.quantity > SUM(IFI.quantity)`).
|
|
31
41
|
3. Reuse the IF if one already exists with the SO number, else POST a new IF.
|
|
32
|
-
4. Per ASN item: POST an IFI (qty = ASN item qty)
|
|
33
|
-
|
|
34
|
-
|
|
42
|
+
4. Per ASN item: POST an IFI (qty = ASN item qty); then copy that ASN item's tracking numbers
|
|
43
|
+
(`AdvanceShippingNoticeItems_TrackingNumbers`) onto the IF item via
|
|
44
|
+
`POST /item-fulfillment-item-tracking-numbers` → `ItemFulfillmentItems_TrackingNumbers`.
|
|
45
|
+
5. Per ASN unit: if it has a Unit (serialized) → POST an IFIU (carrying unit tracking); if it
|
|
46
|
+
is tracking-only (`unitId IS NULL`) → collect its tracking number for an IF package instead.
|
|
35
47
|
6. Create one IF package per unique tracking number (header-level tracking merged with
|
|
36
48
|
tracking-only ASN-unit tracking, deduped by tracking-number uuid).
|
|
37
49
|
|
|
50
|
+
## Tracking number propagation
|
|
51
|
+
The cXML translator maps each `ShipControl` block's tracking number to a line via its
|
|
52
|
+
`LineNumber` Extrinsic (it iterates **all** ShipControls and **all** ShipNoticeItems, not just
|
|
53
|
+
`[0]`), then attaches the number at every level. End state for a cXML ShipNotice:
|
|
54
|
+
|
|
55
|
+
| Table | Populated by |
|
|
56
|
+
|---|---|
|
|
57
|
+
| `AdvanceShippingNotices_TrackingNumbers` | cXML payload (ASN header) |
|
|
58
|
+
| `AdvanceShippingNoticeItems_TrackingNumbers` | cXML payload (matched line's item) |
|
|
59
|
+
| `AdvanceShippingNoticeItemUnits_TrackingNumbers` | cXML payload (tracking-only unit) |
|
|
60
|
+
| `ItemFulfillments_TrackingNumbers` | `postPost` IF package |
|
|
61
|
+
| `ItemFulfillmentItems_TrackingNumbers` | `postPost` (copies ASN-item tracking) |
|
|
62
|
+
| `ItemFulfillmentItemUnits_TrackingNumbers` | `postPost` — **only when serialized units exist** |
|
|
63
|
+
|
|
64
|
+
Fix-forward only (decided 2026-06-11): applies to new ShipNotices; existing records are not
|
|
65
|
+
backfilled.
|
|
66
|
+
|
|
38
67
|
## Data model
|
|
39
68
|
- `AdvanceShippingNoticeUnits.unitId` is nullable (tracking-only units have NULL).
|
|
40
69
|
- `ItemFulfillmentItemUnits.unitId` is **NOT NULL** — a tracking-only unit can never be an
|
|
41
|
-
IFIU; its tracking belongs on an `ItemFulfillmentPackage`.
|
|
42
|
-
|
|
43
|
-
|
|
70
|
+
IFIU; its tracking belongs on an `ItemFulfillmentPackage` / `ItemFulfillments_TrackingNumbers`.
|
|
71
|
+
So for a tracking-only ShipNotice (no serialized units, the Office Depot norm) the IFIU
|
|
72
|
+
bridge legitimately stays empty — there are no IF item units to attach to.
|
|
73
|
+
- Tracking bridge Records (Core): ASN = 216 (unit) / 217 (item) / 218 (header);
|
|
74
|
+
IF = 317 (header) / 318 (item) / 319 (unit). All six are registered inherent children of
|
|
75
|
+
their parents, so the nested payload keys are accepted with no metadata migration.
|
|
44
76
|
|
|
45
77
|
## Client variations
|
|
46
78
|
Compass USA handler (`Model/Compass/`), extending `_Model_Client_AdvanceShippingNotice`.
|
|
47
|
-
Compass Canada (`Model/Compass/Canada/`) is a separate sub-client.
|
|
79
|
+
Compass Canada (`Model/Compass/Canada/`) is a separate sub-client. The Compass cXML API
|
|
80
|
+
(Core `ClientApiIdentities` identity `153531108`, clientId 2) holds roles 1 and 3.
|
|
48
81
|
|
|
49
82
|
## Gotchas / known issues
|
|
83
|
+
- **Record 217 ACL gap (fixed 2026-06-11):** `AdvanceShippingNoticeItems_TrackingNumbers`
|
|
84
|
+
(Record 217) had **zero** `AclRecordPermissions` and its `advanceShippingNoticeItemId`
|
|
85
|
+
(RecordField 1440) / `trackingNumberId` (1441) fields had **zero** `AclFieldPermissions`,
|
|
86
|
+
so ASN-item-level tracking POSTs were rejected (`EZ-1`). `dbchanges2/Client_Compass/2026-06-11
|
|
87
|
+
- AsnItemTrackingNumberAcl.sql` grants role 3 CRUD + role 7 read at the record level and
|
|
88
|
+
roles 1/3/4 writable at the field level, mirroring sibling Record 216. **This SQL must be
|
|
89
|
+
executed against the Compass DB before the cXML change works end-to-end.**
|
|
50
90
|
- **Tracking-only ASN units (the majority — ~56k of ~101k in prod):** before 2026-06-08 the
|
|
51
91
|
IFIU query used `INNER JOIN Units`, silently dropping NULL-`unitId` rows, so cXML shipments
|
|
52
92
|
produced an IF + IFI with **no IFIU and no package — tracking was lost**. Fixed: `LEFT
|
|
53
93
|
OUTER JOIN Units` + route tracking-only units to IF packages. Historical records (e.g.
|
|
54
|
-
SO SA132502 / IF 66997) are **not backfilled** — fix-forward only
|
|
55
|
-
still an open decision.
|
|
94
|
+
SO SA132502 / IF 66997) are **not backfilled** — fix-forward only.
|
|
56
95
|
- Interceptor is **DB-driven**: `postPost` does nothing without the Compass
|
|
57
96
|
`ApiPayloadInterceptors` rows in that env.
|
|
58
97
|
- The IF is named after the SO number; an already-existing IF with that number is reused.
|
|
98
|
+
- **cXML SQL-injection hardening (2026-06-11):** the `ShipNoticeRequest` path interpolated the
|
|
99
|
+
cXML `Sender` Identity / SharedSecret and the OrderReference `orderID` (purchase order
|
|
100
|
+
number) straight into queries. These are now passed through `_Database::escape()`.
|
|
59
101
|
- Separate latent bug in the 1.0 worker: the Strategic Systems cron's no-serials branch
|
|
60
102
|
builds `$itemLevelTrackingNumbers` but never attaches it to the ASN payload.
|
|
61
103
|
|
package/package.json
CHANGED
package/skills/capture/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: capture
|
|
3
|
-
description: End-of-session knowledge writer for TOGA Technology projects. Run this at the END of a coding session to record what you worked on into the team `claude` knowledge base. It figures out what changed this session, matches it against existing knowledge, and proposes create/update/retire changes for one-tap approval — then writes them, keeping registry.json, frontmatter, and INDEX files consistent. Trigger whenever the user says "capture", "wrap up", "save my work to the knowledge base", "I'm done — record this", or
|
|
3
|
+
description: End-of-session knowledge writer for TOGA Technology projects. Run this at the END of a coding session to record what you worked on into the team `claude` knowledge base. It figures out what changed this session, matches it against existing knowledge, and proposes create/update/retire changes for one-tap approval — then writes them, keeping registry.json, frontmatter, and INDEX files consistent. Run at the END of EVERY session — not only for finished features but also for small bug fixes and "I just changed the way something works"; capture decides what is durable (usually a small UPDATE to an existing doc, sometimes a NO-OP). Trigger whenever the user says "capture", "wrap up", "save my work to the knowledge base", "I'm done — record this", or ends a session.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Capture — record this session's work into the team knowledge base
|
|
@@ -110,9 +110,38 @@ node "<TEAM_REPO>/knowledge.js" search --framework=<fw> --repo=<repo> --file=<to
|
|
|
110
110
|
node "<TEAM_REPO>/knowledge.js" search --framework=<fw> --repo=<repo> --q=<keywords>
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
Classify each item as **CREATE** (no doc yet), **UPDATE** (a doc exists and needs new
|
|
114
|
-
|
|
115
|
-
something now removed or obsolete).
|
|
113
|
+
Classify each item as **CREATE** (no doc yet), **UPDATE** (a doc exists and needs new content /
|
|
114
|
+
a new `files:` entry / a gotcha / a *Change history* line), **DEPRECATE/DELETE** (the doc
|
|
115
|
+
describes something now removed or obsolete), or **NO-OP** (nothing durable — see below).
|
|
116
|
+
|
|
117
|
+
### Always run; capture decides what (if anything) is durable
|
|
118
|
+
|
|
119
|
+
`/capture` runs at the end of **every** session — including small bug fixes and "I just changed
|
|
120
|
+
the way something works," not only finished features. The KB is organized by **subject** (a
|
|
121
|
+
capability, a process, a component), **not** by session or ticket, so capturing small work is
|
|
122
|
+
safe: it almost always **UPDATES one existing subject doc**, and rarely creates one.
|
|
123
|
+
|
|
124
|
+
**Guardrails against pollution (enforce these):**
|
|
125
|
+
- **One doc per subject** — never one per change, bug, or ticket.
|
|
126
|
+
- **Bias UPDATE over CREATE** — always search for an owning doc first; CREATE only when no
|
|
127
|
+
subject doc exists. A small "how it works" change UPDATES the feature's *How it works* section
|
|
128
|
+
and adds a dated one-line *Change history* entry, in place — it does not spawn a new file.
|
|
129
|
+
- **Relevance test** — for every candidate write ask: *"Will a teammate six months from now act
|
|
130
|
+
differently because this is written?"* If no → **NO-OP**.
|
|
131
|
+
- **NO-OP is a blessed, first-class outcome.** If nothing rises to durable knowledge (typo,
|
|
132
|
+
formatting, a fix obvious from the code), write nothing and report: "Nothing here is durable
|
|
133
|
+
team knowledge — KB unchanged." Never manufacture a doc to justify the run.
|
|
134
|
+
|
|
135
|
+
**Type assignment (you assign it — developers never classify; default to feature):**
|
|
136
|
+
- Anchored to one capability/model/class? → **feature** (its process → the *How it works* section).
|
|
137
|
+
- A standalone multi-step process no single capability owns? → **workflow**
|
|
138
|
+
(`apps/<repo>/workflows/` for operational/system processes; `clients/<client>/workflows/` for
|
|
139
|
+
client business processes).
|
|
140
|
+
- A client's override of a shared feature? → **client-feature**.
|
|
141
|
+
- A reversible team-wide rule/decision? → **standard** (⚠ elevated).
|
|
142
|
+
- A bug's durable lesson? → a **gotcha** or *Change history* line on the doc that owns the
|
|
143
|
+
affected code — **never its own doc.**
|
|
144
|
+
- When in doubt → **feature.**
|
|
116
145
|
|
|
117
146
|
## Step 4 — Build the proposal (one-tap approval)
|
|
118
147
|
|
|
@@ -217,27 +246,36 @@ How behavior differs per client (or "none — uniform").
|
|
|
217
246
|
## Gotchas / known issues
|
|
218
247
|
The non-obvious things future-you will trip on.
|
|
219
248
|
|
|
249
|
+
## Change history
|
|
250
|
+
Dated one-liners, newest first — notable behavior changes only. Keep it terse; this is not a
|
|
251
|
+
git log. Cap at ~10 entries; fold older ones away.
|
|
252
|
+
- YYYY-MM-DD — <what changed and why> (<author>)
|
|
253
|
+
|
|
220
254
|
## Related docs
|
|
221
255
|
Links.
|
|
222
256
|
```
|
|
223
257
|
|
|
224
|
-
### workflow (client business
|
|
258
|
+
### workflow (a standalone process — operational OR client business)
|
|
259
|
+
Two homes: `apps/<repo>/workflows/` for operational/system processes (set `repo`,
|
|
260
|
+
`client: shared`); `clients/<client>/workflows/` for client business processes (set the
|
|
261
|
+
`client` slug, omit `repo`).
|
|
225
262
|
```markdown
|
|
226
263
|
---
|
|
227
264
|
title: <Workflow Name>
|
|
228
265
|
framework: "<1.0|2.0>"
|
|
266
|
+
repo: <repo> # for apps/<repo>/workflows/; omit for a pure client workflow
|
|
229
267
|
project: <Project>
|
|
230
|
-
client: <client-slug>
|
|
268
|
+
client: <shared|client-slug>
|
|
231
269
|
type: workflow
|
|
232
270
|
status: active
|
|
233
271
|
updated: <YYYY-MM-DD>
|
|
234
272
|
owners: ["<AUTHOR_USERNAME>"] # from Step 1b — never empty
|
|
235
|
-
files: []
|
|
273
|
+
files: [] # source files the process touches, if any
|
|
236
274
|
related: []
|
|
237
275
|
---
|
|
238
276
|
|
|
239
277
|
## Summary
|
|
240
|
-
The
|
|
278
|
+
The process, who/what it serves, and what triggers it.
|
|
241
279
|
|
|
242
280
|
## Steps
|
|
243
281
|
1. …
|
|
@@ -247,6 +285,10 @@ Apps/repos, integrations, data.
|
|
|
247
285
|
|
|
248
286
|
## Edge cases & escalation
|
|
249
287
|
What can go wrong and who handles it.
|
|
288
|
+
|
|
289
|
+
## Change history
|
|
290
|
+
Dated one-liners, newest first. Keep terse; cap at ~10.
|
|
291
|
+
- YYYY-MM-DD — <what changed and why> (<author>)
|
|
250
292
|
```
|
|
251
293
|
|
|
252
294
|
### architecture (one per repo) — ⚠ ELEVATED
|