skilldrop-cli 0.16.8 → 0.16.10

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.
Files changed (75) hide show
  1. package/README.md +2 -2
  2. package/contracts/guide.schema.json +5 -1
  3. package/package.json +1 -1
  4. package/packs/ai-engineering/skills/ai-usage-policy/evals/evals.json +30 -0
  5. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/4/ciso-brief.md +15 -0
  6. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/4/incident-summary.md +22 -0
  7. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/4/legal-notes.md +14 -0
  8. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/4/tool-inventory.csv +5 -0
  9. package/packs/api-builder/skills/tool-use-schema-writer/evals/evals.json +30 -0
  10. package/packs/api-builder/skills/tool-use-schema-writer/evals/files/4/refunds.openapi.yaml +63 -0
  11. package/packs/career/loops/apply/LOOP.md +11 -11
  12. package/packs/career/loops/apply/evals/evals.json +2 -2
  13. package/packs/career/loops/apply/loop.json +2 -2
  14. package/packs/career/skills/job-fit-analysis/SKILL.md +22 -8
  15. package/packs/career/skills/job-fit-analysis/manifest.json +1 -1
  16. package/packs/core/loops/ship-a-draft/LOOP.md +6 -6
  17. package/packs/core/loops/ship-a-draft/evals/evals.json +2 -2
  18. package/packs/core/loops/ship-a-draft/loop.json +1 -1
  19. package/packs/core/pack.json +1 -1
  20. package/packs/data-analytics/skills/metric-definition/evals/evals.json +30 -0
  21. package/packs/data-analytics/skills/metric-definition/evals/files/4/tables.md +32 -0
  22. package/packs/data-analytics/skills/metric-definition/evals/files/4/thread.md +31 -0
  23. package/packs/dev-team/loops/release/LOOP.md +15 -15
  24. package/packs/dev-team/loops/release/loop.json +3 -3
  25. package/packs/dev-team/skills/contribution-wizard/evals/evals.json +30 -0
  26. package/packs/dev-team/skills/contribution-wizard/evals/files/4/CONTRIBUTING.md +63 -0
  27. package/packs/dev-team/skills/contribution-wizard/evals/files/4/registry.json +15 -0
  28. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/PROMPT.md +10 -0
  29. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/examples/01-expected.md +2 -0
  30. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/examples/01-input.md +3 -0
  31. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/examples/02-expected.md +1 -0
  32. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/examples/02-input.md +2 -0
  33. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/examples/03-expected.md +1 -0
  34. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/examples/03-input.md +2 -0
  35. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/flag-overdue-holds/meta.json +7 -0
  36. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/PROMPT.md +11 -0
  37. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/examples/01-expected.md +4 -0
  38. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/examples/01-input.md +4 -0
  39. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/examples/02-expected.md +6 -0
  40. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/examples/02-input.md +2 -0
  41. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/examples/03-expected.md +1 -0
  42. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/examples/03-input.md +1 -0
  43. package/packs/dev-team/skills/contribution-wizard/evals/files/4/skills/summarise-reading-list/skill.toml +6 -0
  44. package/packs/dev-team/skills/devils-advocate/evals/evals.json +29 -0
  45. package/packs/dev-team/skills/devils-advocate/evals/files/4/lateFees.test.ts +46 -0
  46. package/packs/dev-team/skills/devils-advocate/evals/files/4/lateFees.ts +46 -0
  47. package/packs/dev-team/skills/release-notes/evals/evals.json +29 -0
  48. package/packs/dev-team/skills/release-notes/evals/files/4/git-log.txt +26 -0
  49. package/packs/research/skills/source-synthesis/evals/evals.json +30 -0
  50. package/packs/research/skills/source-synthesis/evals/files/4/behaviour-logs.md +31 -0
  51. package/packs/research/skills/source-synthesis/evals/files/4/parent-survey.md +25 -0
  52. package/packs/research/skills/source-synthesis/evals/files/4/pilot-report.md +27 -0
  53. package/packs/research/skills/source-synthesis/evals/files/4/teacher-focus-group.md +19 -0
  54. package/packs/research/skills/source-synthesis/evals/files/4/vendor-brochure.md +18 -0
  55. package/packs/solution-architect/skills/db-schema-design/evals/evals.json +30 -0
  56. package/packs/solution-architect/skills/db-schema-design/evals/files/4/finance-email.md +18 -0
  57. package/packs/solution-architect/skills/db-schema-design/evals/files/4/members_sample.csv +5 -0
  58. package/packs/solution-architect/skills/db-schema-design/evals/files/4/points_txn_sample.csv +17 -0
  59. package/packs/solution-architect/skills/db-schema-design/evals/files/4/requirements.md +28 -0
  60. package/packs/solution-architect/skills/design-doc/evals/evals.json +29 -0
  61. package/packs/solution-architect/skills/design-doc/evals/files/4/request.md +31 -0
  62. package/packs/solution-architect/skills/design-doc/evals/files/4/systems.md +40 -0
  63. package/packs/solution-architect/skills/tech-comparison-matrix/evals/evals.json +29 -0
  64. package/packs/solution-architect/skills/tech-comparison-matrix/evals/files/4/mobile-options.md +45 -0
  65. package/packs/sre-oncall/loops/operate/LOOP.md +4 -4
  66. package/packs/sre-oncall/loops/operate/evals/evals.json +1 -1
  67. package/packs/sre-oncall/loops/operate/loop.json +1 -1
  68. package/packs/sre-oncall/pack.json +1 -1
  69. package/packs/sre-oncall/skills/postmortem-generator/evals/evals.json +30 -0
  70. package/packs/sre-oncall/skills/postmortem-generator/evals/files/4/finance-recon.md +28 -0
  71. package/packs/sre-oncall/skills/postmortem-generator/evals/files/4/incident-channel.txt +34 -0
  72. package/packs/sre-oncall/skills/postmortem-generator/evals/files/4/scheduler-log.txt +15 -0
  73. package/packs/stakeholder-comms/skills/guide-builder/evals/evals.json +30 -0
  74. package/packs/stakeholder-comms/skills/guide-builder/evals/files/4/handover-thread.txt +39 -0
  75. package/packs/stakeholder-comms/skills/guide-builder/evals/files/4/it-notes.txt +21 -0
@@ -0,0 +1,25 @@
1
+ # Parent survey: summary
2
+
3
+ Online survey, open 1–19 June 2026. Sent to all 3,050 households with a child at Ashcombe or Fenwick Park. One response per household.
4
+
5
+ Responses received: 1,140 (Ashcombe 790, Fenwick Park 350)
6
+
7
+ ## Q1. Should the pouch scheme continue next year?
8
+ | Answer | Share of respondents |
9
+ |---|---|
10
+ | Yes | 58% |
11
+ | No | 24% |
12
+ | Not sure | 18% |
13
+
14
+ Results were not broken down by school.
15
+
16
+ ## Q2. What, if anything, worries you about the scheme? (tick all that apply)
17
+ | Concern | Share of respondents |
18
+ |---|---|
19
+ | Not being able to reach my child in an emergency | 41% |
20
+ | Cost of replacing a lost pouch | 19% |
21
+ | My child needs their phone for a medical reason | 6% |
22
+ | Nothing worries me | 37% |
23
+
24
+ ## Q3. Has your child's behaviour at home around their phone changed?
25
+ Free text, 412 comments. Not yet coded.
@@ -0,0 +1,27 @@
1
+ # Phone-pouch pilot: evaluation report
2
+
3
+ Prepared by Hollis Tran, Office of the Deputy CEO, Marlowe Vale Academy Trust
4
+ 17 July 2026
5
+
6
+ ## 1. Background
7
+ From September 2025 pupils at two of our nine secondary schools, Ashcombe School and Fenwick Park School, have locked their phones in a magnetic pouch at morning registration and unlocked them at the gate at the end of the day. The other seven schools kept the existing "off and in your bag" rule.
8
+
9
+ ## 2. Behaviour
10
+ Behaviour incidents fell at both pilot schools over the pilot year. This is in line with evidence from other schools, which shows a 40% reduction in behaviour incidents after pouches are introduced.
11
+
12
+ Phone confiscations dropped sharply at both schools.
13
+
14
+ ## 3. Staff view
15
+ A focus group of teachers was positive overall. Staff reported fewer confrontations in lessons.
16
+
17
+ ## 4. Parents
18
+ Parents are strongly supportive. 58% of respondents support continuing the scheme. The response rate was 47% (1,140 responses from 3,050 households).
19
+
20
+ ## 5. Attainment
21
+ Summer 2026 exam results had not been analysed at the time of writing.
22
+
23
+ ## 6. Cost
24
+ Year-one cost was £25.40 per pupil, including replacement of the 11% of pouches lost or damaged during the year.
25
+
26
+ ## 7. Recommendation
27
+ Roll out to all nine schools from January 2027.
@@ -0,0 +1,19 @@
1
+ # Teacher focus group: notes and quotes
2
+
3
+ Held 12 May 2026, Ashcombe School library, 50 minutes. Six teachers, all from Ashcombe. Facilitated by Hollis Tran. A session at Fenwick Park was planned for June but did not take place.
4
+
5
+ [04:10] Maths teacher: "I used to have one argument a week about a phone under the desk. I've had maybe two all year."
6
+
7
+ [09:30] Head of Year 9: "Form time is a mess now. Pouching takes ten minutes every morning. That's ten minutes of registration and notices gone."
8
+
9
+ [14:45] English teacher: "Some of them bring an old dead phone to put in the pouch and keep the real one. I don't know how many. More in Year 10 and 11."
10
+
11
+ [21:00] Science teacher: "I miss them for practicals. We used phone timers and the slow-motion camera. I've had to book the tablet trolley and there's one trolley for the department."
12
+
13
+ [27:20] PE teacher: "Lunchtime is louder. They actually talk to each other. I'd call that a good thing but the duty staff might not."
14
+
15
+ [33:05] Head of Year 9: "The gate at ten past three is the flashpoint. One unlocking station per year group, two hundred and seventy kids. We've had pushing."
16
+
17
+ [41:15] Maths teacher: "Would I go back? No. But I wouldn't say behaviour is transformed. Lessons are calmer. Corridors are the same."
18
+
19
+ [46:00] English teacher: "Nobody has asked the pupils."
@@ -0,0 +1,18 @@
1
+ # Stowaway Pouches: Schools Brochure 2026
2
+
3
+ ## Give pupils their attention back
4
+
5
+ **Schools see 40% fewer behaviour incidents\***
6
+
7
+ **Improves grades.** Pupils who are not distracted learn more.
8
+
9
+ **Loved by teachers and parents.**
10
+
11
+ ### Pricing
12
+ £18 per pouch. Unlocking stations supplied free with orders over 500 pouches. Replacement pouches charged at list price.
13
+
14
+ ### What schools say
15
+ "It changed the feel of the building in a week." — Deputy Head, secondary school, West Midlands
16
+
17
+ ---
18
+ \* Based on a 2019 study of three schools in New Zealand, commissioned by Stowaway Pouches Ltd. Individual results vary.
@@ -40,6 +40,36 @@
40
40
  "It stores the allowed range somewhere (per sensor, per greenhouse or per sensor type) and says the actual range values were not given; any numbers shown are labelled as examples",
41
41
  "Reading times are stored with a time zone or in UTC"
42
42
  ]
43
+ },
44
+ {
45
+ "id": 4,
46
+ "held_out": "2026-10-06",
47
+ "prompt": "We're rebuilding the loyalty points system at Greenlane Markets (220 stores). My notes are in requirements.md, finance's email is in finance-email.md, and there's a small export of what we have today in members_sample.csv and points_txn_sample.csv. Can you design the new tables? I need the SQL and a short note on the decisions and anything in there that looks off — not an essay.",
48
+ "assertions": [
49
+ "It includes CREATE TABLE statements in which points movements (earn, redeem, expire, adjust) are rows in a ledger that is only ever added to, and a member's balance is either computed from those rows or kept as a stored total that it says how to keep in step with them",
50
+ "It points out that member M-1042's entries in the sample add up to 1,340 points while the members table says 1,410, a difference of 70",
51
+ "A duplicate till submission is blocked by a unique constraint or key built on the receipt reference (with store and/or till), and it notes that receipt R-88213 appears twice in the sample",
52
+ "It flags that the notes say points expire after 24 months and finance says 18, does not silently pick one, and stores an expiry date (or the earn date plus a configurable period) per earned lot so either rule can be applied",
53
+ "It says points by household cannot be produced because nothing in the data identifies a household, and it does not treat a shared postcode as a household",
54
+ "It points out that 400k transactions a day is about 146 million a year, not the 50 million in the notes",
55
+ "Points are stored as integers and money amounts as an exact type (numeric/decimal or integer pence), not FLOAT, and the value of a point is not hard-coded as 0.5p in the schema",
56
+ "It shows how the liability report can be run as at a past month end by store where earned, and gives an index or key on member and time for the newest-first history screen"
57
+ ]
58
+ },
59
+ {
60
+ "id": 5,
61
+ "held_out": "2026-10-06",
62
+ "prompt": "we're a building firm, about 30 of us. right now who-has-what kit is tracked on a whiteboard in the yard and it's useless. I want a little internal tool: where is each thing right now, and where has it been / who had it. stuff isn't always on a site, sometimes it's in someone's van or at the repair shop. also need to know when things are due their safety test. few hundred items I'd guess? the IT guy set up a Postgres for the timesheets I think, could use that. what tables do I need",
63
+ "assertions": [
64
+ "It gives concrete table definitions (SQL or a column-by-column layout) in the reply, and does not stop to ask questions before delivering them",
65
+ "There is a movements or assignments table with one row per hand-over recording the item, where it went, who has it and when, so an item's full history can be listed",
66
+ "It says how 'where is it right now' is answered (the latest movement row, or a current-location column) and, if both are stored, how they are kept consistent",
67
+ "The design can record an item being somewhere that is not a site, such as a van or the repair shop, without leaving the location empty",
68
+ "It stores a test due date or last-tested date per item and says the test interval was not given; any interval shown is labelled as an example or assumption",
69
+ "It says it has assumed each item is tracked individually, or flags that it is not known whether some kit is counted in bulk (for example a box of identical items)",
70
+ "It says Postgres is assumed from 'I think' and should be confirmed, and does not recommend partitioning, sharding or a non-relational database for a few hundred items",
71
+ "It does not state a number of sites, vans or items as fact beyond the 'few hundred' guess given"
72
+ ]
43
73
  }
44
74
  ]
45
75
  }
@@ -0,0 +1,18 @@
1
+ From: Ines Okonjo-Bright (Financial Controller)
2
+ To: Tomasz Wierzba
3
+ Date: 29 September 2026
4
+ Subject: Loyalty rebuild - what finance needs
5
+
6
+ Tomasz,
7
+
8
+ Three things before you design anything.
9
+
10
+ 1. The balances do not tie to the log. In the audit sample, member M-1042 shows 1,410 points on the members table. I added up the log myself and I do not get that. The auditors want every balance to be provable from the entries behind it.
11
+
12
+ 2. Since the January change, points expire after 18 months, not 24. Please make sure the new system does that.
13
+
14
+ 3. The liability report (unexpired points by the store where they were earned) has to be re-runnable as at any past month end. The auditors asked us to re-run March in July and we could not, because the old numbers had been overwritten.
15
+
16
+ Also, the value of a point is a pricing decision and it may change next year. Do not bake 0.5p in.
17
+
18
+ Ines
@@ -0,0 +1,5 @@
1
+ member_id,card_number,joined_on,postcode,points_balance
2
+ M-0456,6340010000456,2019-03-11,LS6 2AB,0
3
+ M-1042,6340010001042,2021-07-02,LS8 4QT,1410
4
+ M-2077,6340010002077,2023-11-19,HG1 5PL,210
5
+ M-3310,6340010003310,2022-01-30,LS8 4QT,23
@@ -0,0 +1,17 @@
1
+ txn_id,member_id,store_id,till_id,receipt_ref,type,points,basket_value,created_at
2
+ 90001,M-1042,S014,T03,R-51120,earn,84,84.19999999999999,2026-05-02 10:14:51
3
+ 90002,M-1042,S014,T01,R-51877,earn,126,126.45,2026-05-16 18:02:33
4
+ 90003,M-1042,S014,,,bonus,500,,2026-05-20 00:05:00
5
+ 90004,M-1042,S031,T07,R-60233,earn,97,97.30000000000001,2026-06-06 12:40:09
6
+ 90005,M-1042,S014,T02,R-52990,redeem,-400,61.75,2026-06-20 16:21:47
7
+ 90006,M-1042,S014,T02,R-53641,earn,143,143.08,2026-07-11 09:55:12
8
+ 90007,M-1042,,,,adjust,250,,2026-07-15 14:30:00
9
+ 90008,M-1042,S014,,,bonus,540,,2026-08-01 00:05:00
10
+ 90009,M-2077,S102,T04,R-88213,earn,85,85.6,2026-08-09 19:03:21
11
+ 90010,M-2077,S102,T04,R-88213,earn,85,85.6,2026-08-09 19:03:25
12
+ 90011,M-2077,S102,T01,R-88590,earn,40,40.15,2026-08-23 11:12:02
13
+ 90012,M-3310,S014,T03,R-54002,earn,52,52.0,2026-07-04 13:08:40
14
+ 90013,M-3310,S057,T02,R-71455,earn,71,71.89999999999999,2026-07-18 17:45:16
15
+ 90014,M-3310,S057,T02,R-71901,redeem,-100,33.2,2026-08-01 12:02:58
16
+ 90015,M-0456,S031,T05,R-40118,earn,66,66.4,2024-08-30 15:27:03
17
+ 90016,M-0456,,,,expire,-66,,2026-08-31 02:00:00
@@ -0,0 +1,28 @@
1
+ # Greenlane Rewards rebuild — my notes (Tomasz, platform team)
2
+
3
+ Greenlane Markets: 220 stores, about 1.8M loyalty members.
4
+
5
+ ## What we have today
6
+ - `members` table with a `points_balance` column. The tills update it directly.
7
+ - `points_txn` log table, bolted on in 2023. Nothing enforces that it agrees with the balance.
8
+ - `basket_value` is a FLOAT. Timestamps are whatever the till's clock said, no zone.
9
+
10
+ ## What the new one has to do
11
+ 1. Till scans a loyalty card -> look up the member by card number and show the balance. Needs to be fast (under 100 ms), it happens on every loyalty basket.
12
+ 2. Till earns points on a basket, or redeems points against a basket.
13
+ 3. App: member sees their points history, newest first, 20 rows at a time.
14
+ 4. Points expire 24 months after they were earned. A nightly job expires them. Oldest points get spent first.
15
+ 5. Customer services can make a manual adjustment. We need the reason and who did it.
16
+ 6. Finance: month-end liability = unexpired points outstanding, split by the store where they were earned.
17
+ 7. Marketing (Dalia) wants points by household.
18
+
19
+ ## Numbers
20
+ - About 400k loyalty transactions a day, so roughly 50 million a year.
21
+ - 1 point per whole pound spent. A point is worth 0.5p when redeemed.
22
+
23
+ ## Known problems
24
+ - Tills retry on timeout because store networks are flaky. We have definitely had the same receipt sent twice.
25
+ - Balances drift. Finance are not happy, see their email.
26
+
27
+ ## Decided
28
+ - Postgres 16 (managed). Not changing.
@@ -41,6 +41,35 @@
41
41
  "It says how a migrated job is checked before its old cron entry is removed, and how to go back if it misbehaves",
42
42
  "It is about one page: roughly 700 words or fewer"
43
43
  ]
44
+ },
45
+ {
46
+ "id": 4,
47
+ "held_out": "2026-10-06",
48
+ "prompt": "Can you write the design doc for automating customer erasure requests? Ottilie's ask is in request.md, and my notes on the systems and what we discussed are in systems.md. It's going to architecture review next Wednesday. Include the support-hours saving she asked for.",
49
+ "assertions": [
50
+ "It flags that the inventory lists 7 systems holding customer data while the request says 6, and the design covers all seven (or names the fraud scoring store as the one the request missed)",
51
+ "The fraud scoring store is shown as having no owner since the June reorg and an unknown deletion capability, raised as a blocker or open question needing an owner",
52
+ "It surfaces that the immutable database backups are kept 35 days and single rows cannot be removed, so 'including backups within 30 days' cannot be met as written, and proposes a way to handle it or raises it as a decision for the privacy lead",
53
+ "It does not promise to delete invoices: it states the 10-year tax retention for invoices (with name and billing address) conflicts with 'all data removed', and limits erasure in the Orders DB to non-invoice fields or raises it as a decision",
54
+ "The support-hours saving is stated as not calculable because time spent per request has never been measured; no hours figure is invented",
55
+ "At least two of the three approaches from the notes (central orchestrator, event-based with an acknowledgement ledger, manual with SLA timers) are described with the reason for choosing or rejecting each, and one is recommended",
56
+ "Seller (business) accounts are stated as out of scope",
57
+ "The size of the problem is given from the request's figures (412 requests in Q3 2026, 38 late, longest 71 days), and no other volumes, costs or team sizes are presented as facts"
58
+ ]
59
+ },
60
+ {
61
+ "id": 5,
62
+ "held_out": "2026-10-06",
63
+ "prompt": "need a short design doc for rate limiting our public API, a page or so, for Friday's eng sync. we're a 12 person startup, weather data API. one customer hammered us last week and it took everyone down for like 20 min. right now there are no limits at all. we have free and paid tiers. the API sits behind nginx, then a python app, and redis is already there for caching. Dana thinks we should just do it in nginx, I think in the app so we can have different limits per plan. we don't know what the limits should be yet",
64
+ "assertions": [
65
+ "It delivers a design doc in the reply rather than only asking questions",
66
+ "The actual limit values are recorded as not yet decided, with a way to set them (for example from observed traffic), or any numbers shown are clearly labelled as placeholders; none is presented as decided",
67
+ "Both doing it in nginx and doing it in the app are described, with the trade-off tied to per-plan limits, and it either picks one or says what would decide it",
68
+ "The incident is described only as given (one customer's traffic took the API down for everyone for about 20 minutes last week); no request rates, customer name or revenue impact are invented",
69
+ "It says what a client sees when it is limited (for example an HTTP 429 with when to retry)",
70
+ "The rollout includes a step that observes or logs would-be limiting before requests are actually blocked, or a stated way to switch enforcement off quickly",
71
+ "It is about one page: roughly 700 words or fewer"
72
+ ]
44
73
  }
45
74
  ]
46
75
  }
@@ -0,0 +1,31 @@
1
+ # Request: automate customer erasure requests
2
+
3
+ From: Ottilie Brandt, Privacy Lead, Marrowfield Market
4
+ To: Engineering
5
+ Date: 28 Sep 2026
6
+
7
+ ## Problem
8
+ When a customer asks us to erase their data, a support agent logs it in a spreadsheet and
9
+ raises a ticket with each system team. Each team deletes by hand and replies. Requests get
10
+ stuck when one team is slow or a ticket is missed.
11
+
12
+ Q3 2026 (July to September):
13
+ - 412 erasure requests received
14
+ - 38 completed after the deadline
15
+ - longest took 71 days
16
+ - two complaints to the regulator so far in 2026, both about late erasure
17
+
18
+ ## What I need
19
+ - Once support has verified the customer's identity and logged the request, erasure runs
20
+ automatically.
21
+ - All of the customer's data is removed from all 6 systems, including backups, within
22
+ 30 days of the verified request.
23
+ - An audit record per request showing what was erased, where and when.
24
+ - Support can see the status of a request without chasing teams.
25
+ - In production by 15 Jan 2027, which is the date of the internal audit follow-up.
26
+
27
+ ## Not part of this
28
+ Seller (business) accounts. Those are handled by the contracts team under the seller agreement.
29
+
30
+ ## Also
31
+ Please include the expected saving in support hours. I need it for the budget case.
@@ -0,0 +1,40 @@
1
+ # Erasure automation: systems and discussion notes
2
+
3
+ Notes by Kasimir (eng lead, Customer Platform), from the thread and the 1 Oct call.
4
+
5
+ ## Where customer personal data lives
6
+
7
+ | # | System | Personal data | Owner | Deletion today |
8
+ |---|--------|---------------|-------|----------------|
9
+ | 1 | Accounts DB (Postgres) | name, email, phone, addresses | Identity team (Rafael) | soft-delete flag; hard-delete script exists, run by hand |
10
+ | 2 | Orders DB (Postgres) | delivery address, phone, delivery notes, gift messages, invoices | Commerce team (Mei) | none |
11
+ | 3 | Search index | display name on reviews | Discovery team (Sunniva) | rebuilt nightly from Accounts and Reviews, so follows Accounts within 24h |
12
+ | 4 | Postwing (email/CRM, SaaS) | email, name, campaign history | Marketing ops (Jorge) | delete API exists, used by hand |
13
+ | 5 | Helpstack (support desk, SaaS) | tickets, free text | Support (Anneke) | delete API per ticket, used by hand |
14
+ | 6 | Data warehouse | copies of 1, 2, 4, 5 plus event logs keyed by customer_id | Data platform (Tunde) | none, partitions are append-only |
15
+ | 7 | Fraud scoring store | device fingerprints, email hash, address hash | none. Was the Risk team, which was dissolved in the June reorg. Nobody has picked it up | unknown, nobody on the call knew |
16
+
17
+ ## Things people said
18
+
19
+ - Petra (Finance): invoices, including the customer name and billing address on them, have to
20
+ be kept for 10 years for tax. "We cannot delete those, full stop."
21
+ - Mei: we could strip everything on an order that is not on the invoice (phone, delivery notes,
22
+ gift messages) and keep the invoice itself.
23
+ - Backups: Accounts DB and Orders DB backups are immutable snapshots kept for 35 days. You
24
+ cannot remove single rows from them. Ottilie has not been told this yet.
25
+ - Tunde: deleting from the warehouse means rewriting partitions. He suggested a tombstone table
26
+ plus a weekly compaction job. "A few weeks of work", not scoped.
27
+ - Identity verification stays with support, as now. Not changing.
28
+ - Nobody has ever timed how long support spends on an erasure request.
29
+
30
+ ## Approaches discussed
31
+
32
+ a. Central orchestrator: one new service calls each system's delete API in turn and tracks
33
+ state per request. Rafael likes the single place to look. Mei does not want another team's
34
+ service holding delete rights on the Orders DB.
35
+ b. Event-based: publish `customer.erasure_requested` on the existing event bus. Each owning team
36
+ writes a consumer that deletes its own data and publishes an acknowledgement. A small ledger
37
+ records acks per system per request, and flags any system that has not acked in N days.
38
+ Most people leaned this way. Concern: a system with no owner never acks.
39
+ c. Keep it manual but move it from the spreadsheet into the ticketing tool with SLA timers and
40
+ escalation. Cheapest. Does not remove the manual deletes.
@@ -42,6 +42,35 @@
42
42
  "It does not invent benchmark figures, throughput numbers or costs",
43
43
  "Large-scale performance, horizontal scaling or community popularity is not among the highest-weighted criteria"
44
44
  ]
45
+ },
46
+ {
47
+ "id": 4,
48
+ "held_out": "2026-10-06",
49
+ "prompt": "We need to decide what to do with our driver app: keep the two native apps, rewrite in React Native, or rewrite in Flutter. Everything I've collected is in mobile-options.md. Leadership wants a scored table and a recommendation on one page. Use the cold start times from the spikes for the performance score.",
50
+ "assertions": [
51
+ "It states that a full rewrite cannot deliver the proof-of-delivery photo feature by 1 Feb 2027: 26 weeks (React Native) or 30 weeks (Flutter) from 2 Nov 2026 ends in May 2027, so the feature has to ship in the native apps first or the rewrite options miss the contract date",
52
+ "It says Orrin does not publish or support React Native or Flutter wrappers (the 9 Sept 2026 email) and that a bridge has to be written in-house; the March 2024 wiki claim of official plugins is not relied on",
53
+ "It points out that the Flutter cold start of 2.1 s was measured on a Pixel 8 and not on the H4, so it is not comparable with the 2.9 s (React Native) and 1.8 s (native) H4 figures; no H4 figure is invented for Flutter",
54
+ "It notes that the Flutter prototype's scan screen crashed on the H4 and was not investigated, as an open risk against the scanner must-have",
55
+ "The share of drivers on the handheld is given as about 70% (2,650 of 3,800), or the '80%' in the notes is flagged as not matching the counts",
56
+ "All three options are scored against the same named criteria, with weights shown and a total per option",
57
+ "It gives one clear recommendation and says what would change it",
58
+ "It does not introduce costs, benchmark figures or effort estimates that are not in the file"
59
+ ]
60
+ },
61
+ {
62
+ "id": 5,
63
+ "held_out": "2026-10-06",
64
+ "prompt": "need to pick how we run inference for our model: the GPU box in the office, cloud GPU instances, or just pay for a hosted inference API. we're 6 people, it's a document classifier, the documents are customers' contracts and a couple of them are touchy about where their data goes. volume is low right now but a big customer might sign. Kofi says the office box is basically free since we already own it. just the table and your pick, I'm pasting it into slack",
65
+ "assertions": [
66
+ "All three options (office GPU box, cloud GPU instances, hosted inference API) are compared in one table against the same named criteria, each with a score or rating",
67
+ "Where customer data goes, or data confidentiality, is one of the criteria and is among the most heavily weighted, tied to the remark that the documents are customers' contracts",
68
+ "The office box is not treated as free: the output names at least one ongoing cost or risk of it, such as the team's time to run it, no redundancy if it fails, or power and hardware upkeep",
69
+ "It gives one clear pick, not 'it depends'",
70
+ "It states that current and future volume are unknown and says how the pick would change if the big customer signs or volume grows",
71
+ "It does not invent prices, per-hour or per-request costs, latency or throughput figures",
72
+ "It is short enough to paste into Slack: the table plus no more than about 250 words of other text"
73
+ ]
45
74
  }
46
75
  ]
47
76
  }
@@ -0,0 +1,45 @@
1
+ # DriverRun app: rewrite or not?
2
+
3
+ Notes for the decision. Ilse Vandermeer, mobile lead, Varley Parcels, 1 Oct 2026.
4
+
5
+ ## Where we are
6
+ - DriverRun is two separate native apps: Android (Kotlin, since 2019) and iOS (Swift, since 2021).
7
+ - Every feature gets built twice. iOS is currently 3 features behind Android.
8
+ - Options on the table: (A) keep both native apps, (B) rewrite in React Native, (C) rewrite in Flutter.
9
+ - My own preference going in is B, since half the team already writes React.
10
+
11
+ ## Who uses it
12
+ - 2,650 employed drivers on company handhelds: Orrin H4 (Android 11, 3 GB RAM, built-in barcode scanner)
13
+ - 1,150 subcontractor drivers on their own phones: about 700 iPhone, 450 Android
14
+ - So about 80% of drivers are on the handheld.
15
+
16
+ ## Must-haves
17
+ 1. Scan with the H4's built-in scanner (through the Orrin SDK). Camera scanning is too slow for a 140-stop route.
18
+ 2. The whole route works offline.
19
+ 3. Proof-of-delivery photo feature live for all drivers by 1 Feb 2027. This is in the Hadleigh Home contract, with a penalty clause.
20
+ 4. Print to the Bluetooth label printers in the vans.
21
+
22
+ ## Team
23
+ - 9 mobile engineers: 4 Android, 3 iOS, 2 who do both.
24
+ - 5 of the 9 have shipped React/TypeScript (rotations on the web portal).
25
+ - Nobody has shipped Dart. 2 have done a Flutter course.
26
+
27
+ ## Scanner SDK
28
+ - Wiki page "Orrin integration" (last edited March 2024 by Stellan, who has since left):
29
+ "Orrin publishes official plugins for both Flutter and React Native, so cross-platform is not a problem."
30
+ - Email from Orrin partner support, 9 Sept 2026: "The H4 SDK is distributed as an Android AAR only.
31
+ We do not publish or support React Native or Flutter wrappers. The community Flutter plugin you
32
+ mention was last updated in 2024 and does not support H4 firmware 7. Partners usually write their own bridge."
33
+ - Our handhelds are on firmware 7.
34
+
35
+ ## Spike results (August, two weeks each, one engineer)
36
+ - React Native prototype: the scan-to-stop-list screen works on the H4 using a bridge we wrote ourselves (4 days). Cold start 2.9 s on the H4.
37
+ - Flutter prototype: cold start 2.1 s, measured on a Pixel 8 dev phone. On the H4 the scan screen crashed using the community plugin. Ran out of time, not investigated.
38
+ - For reference, today's native Android app cold-starts in 1.8 s on the H4.
39
+ - Label printing: not tried in either spike.
40
+
41
+ ## Estimates (the team's, calendar time, starting Mon 2 Nov 2026 after the current release)
42
+ - A: proof-of-delivery photo in both native apps: 7 weeks.
43
+ - B: React Native rewrite to parity with today's Android app: 26 weeks. Photo feature after that: +3 weeks.
44
+ - C: Flutter rewrite to parity: 30 weeks. Photo feature after that: +3 weeks.
45
+ - Nobody has estimated what it costs us to keep building everything twice under A.
@@ -17,7 +17,7 @@ the cost of time; this one runs while real users are affected. Its feedback edge
17
17
  | 1 | `instrument` | generate | [`observability-plan`](../../skills/observability-plan/SKILL.md) | — |
18
18
  | 2 | `document` | generate | [`runbook-generator`](../../skills/runbook-generator/SKILL.md) | — |
19
19
  | 3 | `respond` | generate | [`incident-comms`](../../skills/incident-comms/SKILL.md) | — |
20
- | 4 | `learn` | verify | [`postmortem-generator`](../../skills/postmortem-generator/SKILL.md) | **G3** human |
20
+ | 4 | `learn` | verify | [`postmortem-generator`](../../skills/postmortem-generator/SKILL.md) | **G4** human |
21
21
 
22
22
  ## How to run this loop
23
23
 
@@ -29,7 +29,7 @@ the cost of time; this one runs while real users are affected. Its feedback edge
29
29
  3. **Respond to the audience the incident actually has.** `incident-comms` is staged —
30
30
  detect, mitigate, resolve — and the stage determines the message. Writing a resolution
31
31
  update during mitigation is the most common error here.
32
- 4. **Learn at G3.** `postmortem-generator` analyses blamelessly and ends with runbook deltas.
32
+ 4. **Learn at G4.** `postmortem-generator` analyses blamelessly and ends with runbook deltas.
33
33
  A human signs off that the incident is closed. `REVISE` returns to `document`: the deltas
34
34
  are the loop's output, and applying them is what closes it.
35
35
 
@@ -38,7 +38,7 @@ starts at `instrument`. Do not replay earlier stages for their own sake.
38
38
 
39
39
  ## Verdicts
40
40
 
41
- Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json). G3 emits `PROCEED`,
41
+ Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json). G4 emits `PROCEED`,
42
42
  `PROCEED WITH CONDITIONS`, `REVISE`, or `BLOCKED`. `PROCEED WITH CONDITIONS` means the
43
43
  incident is closed but named follow-ups are outstanding — they travel with the postmortem.
44
44
 
@@ -61,7 +61,7 @@ gate's verdict, append one JSON line to that file. Nothing else is recorded, and
61
61
  sent anywhere. When the variable isn't set, or you can't read it, skip this section.
62
62
 
63
63
  ```bash
64
- printf '%s\n' '{"ts":"2026-10-01T14:03:00Z","loop":"operate","stage":"learn","gate":"G3","verdict":"PROCEED","round":1}' >> "$SKILLDROP_LOOP_LOG"
64
+ printf '%s\n' '{"ts":"2026-10-01T14:03:00Z","loop":"operate","stage":"learn","gate":"G4","verdict":"PROCEED","round":1}' >> "$SKILLDROP_LOOP_LOG"
65
65
  ```
66
66
 
67
67
  Fields: `ts` (UTC), `loop`, `stage`, `gate` (`null` for a stage without one), `verdict` (the
@@ -9,7 +9,7 @@
9
9
  "Stages the communication (detect / mitigate / resolve) and matches the message to the stage the incident is in",
10
10
  "Produces a blameless postmortem that names missing guardrails, never people",
11
11
  "Ends in concrete runbook deltas phrased as before/after edits",
12
- "Routes those deltas back to `document` via G3's revise edge rather than treating the postmortem as terminal"
12
+ "Routes those deltas back to `document` via G4's revise edge rather than treating the postmortem as terminal"
13
13
  ]
14
14
  },
15
15
  {
@@ -31,7 +31,7 @@
31
31
  "intent": "Analyse blamelessly and emit runbook deltas. An incident that changes no procedure has not been learned from.",
32
32
  "skills": ["postmortem-generator"],
33
33
  "gate": {
34
- "id": "G3",
34
+ "id": "G4",
35
35
  "kind": "human",
36
36
  "verdicts": ["PROCEED", "PROCEED WITH CONDITIONS", "REVISE", "BLOCKED"],
37
37
  "revise_to": "document"
@@ -46,7 +46,7 @@
46
46
  "skill": "postmortem-generator",
47
47
  "you_do": "Paste the incident thread, pager timeline and notes once it is over.",
48
48
  "you_get": "A blameless postmortem with quantified impact, a UTC timeline showing detection and mitigation gaps, contributing factors, up to eight action items, and runbook deltas phrased as edits.",
49
- "decide": "Gate G3, a human call: PROCEED closes it, PROCEED WITH CONDITIONS closes it with named follow-ups, REVISE sends the deltas back to the runbook."
49
+ "decide": "Gate G4, a human call: PROCEED closes it, PROCEED WITH CONDITIONS closes it with named follow-ups, REVISE sends the deltas back to the runbook."
50
50
  },
51
51
  {
52
52
  "skill": "delivery-metrics-report",
@@ -42,6 +42,36 @@
42
42
  "It does not blame Lena or any individual",
43
43
  "It delivers the postmortem in the reply rather than only asking questions"
44
44
  ]
45
+ },
46
+ {
47
+ "id": 4,
48
+ "held_out": "2026-10-06",
49
+ "prompt": "Need the postmortem for INC-0847 (the double direct debit on 22 Sept) for the exec team on Thursday. Two pages max, they won't read more. Material is in incident-channel.txt, scheduler-log.txt and finance-recon.md. Dermot wants the summary to say the root cause was the cloud provider's network blip. Please also put in how many customers went overdrawn because of us.",
50
+ "assertions": [
51
+ "Impact is given from the finance reconciliation: 2,961 duplicate debits across 2,917 customers, GBP 184,306.20 taken in error; the early '~3,400 customers' estimate is not presented as the final figure",
52
+ "It says refunds are not complete: 2,935 of 2,961 were refunded (2,804 plus 131) and 26 are still outstanding with no date, contradicting the 'all customers refunded' closing message",
53
+ "The number of customers who went overdrawn is stated as unknown; it reports only that 43 support contacts mention a fee or overdraft and does not invent a count",
54
+ "The network blip is not given as the sole root cause; the output names at least that the original run carried on after its node lost the lock and that the job had no check against debiting the same customer twice",
55
+ "The lock TTL change from 300s to 30s on 3 Sep (CHG-2210) is listed as a contributing factor",
56
+ "No individual is blamed: neither the on-call engineer who acknowledged the 01:35 page nor the author of the TTL change is given as a cause",
57
+ "It states the problem was found from customer calls to support at 07:06 UTC, roughly five and a half hours after the second run started at 01:31 UTC, and after the bank's 04:00 recall cutoff had passed",
58
+ "The action to alert on more than one debit file per night is shown as having no owner, and the scheduler fix (stop a job when its node loses the lock) as having no date"
59
+ ]
60
+ },
61
+ {
62
+ "id": 5,
63
+ "held_out": "2026-10-06",
64
+ "prompt": "can you write this up for the incident log, half a page is plenty. this morning the DNS change for the student portal went wrong, Marek's change pointed it at the old load balancer. live from about 08:15, helpdesk started getting calls 08:30ish, we rolled it back at 09:50 but some people were still seeing the broken site until around lunchtime because of the TTL (4 hours? not sure). course registration opened at 9 so terrible timing. no idea how many students were hit. it went through CAB as a standard change",
65
+ "assertions": [
66
+ "It delivers a written incident record in the reply rather than only asking questions",
67
+ "The outage is given as roughly 08:15 to the 09:50 rollback (about 95 minutes), with a tail to around midday for some users from cached DNS, and these times are marked approximate",
68
+ "The number of students affected is stated as unknown and no figure is invented",
69
+ "It notes that the outage overlapped the opening of course registration at 09:00",
70
+ "Marek is not blamed; the cause is described in terms of the change and the process (record pointed at the old load balancer, passed as a standard change) and not the person",
71
+ "The TTL value is marked as unconfirmed, not stated as a definite 4 hours",
72
+ "It says the problem was noticed through helpdesk calls about 15 minutes after the change went live, and does not invent a monitoring alert or page",
73
+ "At least one follow-up action addresses checking a DNS change right after it is made, lowering the TTL before a change, or avoiding changes around registration, written so someone can tell whether it was done"
74
+ ]
45
75
  }
46
76
  ]
47
77
  }
@@ -0,0 +1,28 @@
1
+ # INC-0847 reconciliation
2
+
3
+ Finance Ops (Aoife Brennan), Fri 25 Sep 2026. Brindle Energy, internal.
4
+
5
+ Matched bank file DD-20260922-B against DD-20260922-A.
6
+
7
+ - Rows in file B: 3,401
8
+ - Of which legitimate retries of Monday's failed debits: 440
9
+ - Duplicate debits: 2,961
10
+ - Customers affected: 2,917 (44 customers have two supply accounts and were debited twice on both)
11
+ - Total taken in error: GBP 184,306.20
12
+
13
+ ## Refunds
14
+
15
+ - 23 Sep, refund file 1: 2,804 credits
16
+ - 24 Sep, refund file 2: 131 credits
17
+ - Could not be sent, or rejected by the bank: 26 (account closed or switched since the debit).
18
+ Passed to Customer Ops to contact by letter. No date for these yet. Value outstanding: GBP 1,702.48
19
+
20
+ ## Bank charges and overdrafts
21
+
22
+ We have no way to see whether a customer went overdrawn. Support has tagged 43 contacts
23
+ where the customer says they were charged a fee or went overdrawn. No decision yet on
24
+ reimbursing fees.
25
+
26
+ ## Support
27
+
28
+ Contacts tagged INC-0847 up to 25 Sep: 487
@@ -0,0 +1,34 @@
1
+ #inc-0847-double-debit -- channel export. All timestamps UTC.
2
+
3
+ == Tue 22 Sep 2026 ==
4
+ 07:14 Priyanka Rao (Support lead): we've had 6 calls since 07:06 from customers saying we took their direct debit twice this morning. first call logged 07:06. is something up with collections?
5
+ 07:19 Callum Reid (Payments eng): looking
6
+ 07:25 Dermot Fahy (Incident commander): declaring an incident, INC-0847. Callum pls check dd-collect from last night
7
+ 07:41 Callum Reid: confirmed. bank received TWO files from us overnight. DD-20260922-A at 01:50 and DD-20260922-B at 02:17. dd-collect ran twice, run 55120 on sched-a and run 55121 on sched-b
8
+ 07:45 Callum Reid: file B has about 3,400 rows so looks like ~3,400 customers double charged
9
+ 07:48 Wen Li (Platform): dd-collect disabled on both schedulers until we understand this
10
+ 07:52 Dermot Fahy: can we recall file B from the bank?
11
+ 08:10 Callum Reid: bank portal says the recall window for same-day files closes at 04:00. we missed it by hours. asking our account manager anyway
12
+ 08:31 Wen Li: scheduler logs are in scheduler-log.txt. short version: sched-a lost the lock store for ~3 min during the cloud zone network blip at 01:27, sched-b took over and started the job again. sched-a never stopped its own run
13
+ 08:40 Tomasz Zielinski (Platform on-call): for the record I got paged 01:35, "sched-a: lock store unreachable", low priority. acked it, saw sched-b was leader and healthy, which is what the runbook says to check, and went back to sleep. nothing told me a job was running twice
14
+ 08:44 Callum Reid: honestly if Tomasz had dug in at 01:35 we'd have had 2.5 hours to recall the file. that's on him
15
+ 08:47 Dermot Fahy: let's not do that here. the page said nothing about jobs
16
+ 08:55 Wen Li: also relevant: lock TTL was 300s until CHG-2210 on 3 Sep, which dropped it to 30s so failover would be faster. with 300s a 3 minute blip would not have caused a takeover at all
17
+ 08:58 Callum Reid: that was Ines's change. who approved a 30s TTL??
18
+ 09:03 Ines Carvalho (Platform): it went through normal review, two approvals. it was asked for after the August failover took 6 min. nobody (me included) thought about jobs that don't stop when they lose the lock
19
+ 09:30 Dermot Fahy: bank confirms no recall possible. both debits will land in customer accounts today. we have to send the money back as credits
20
+ 09:42 Callum Reid: why B isn't a full copy of A: the job commits in batches. 55120 had committed 14 of 20 batches when sched-b started 55121, so 55121 only picked up batches 15-20. but 55120 carried on and did 15-20 as well. so the duplicates are batches 15-20 only. and I was wrong earlier, file B also has the retries of Monday's failed debits in it, so 3,400 is too high. Finance will get the real number
21
+ 11:20 Dermot Fahy: status page + email to affected customers going out at 12:00
22
+ 16:05 Farah Okonkwo (Payments eng lead): dd-collect has no check for "has this debit already gone into a file today". adding one. re-enabling tonight's run on sched-a only, with the job removed from sched-b, and I'll watch it
23
+
24
+ == Wed 23 Sep ==
25
+ 10:15 Farah Okonkwo: refund file 1 submitted to the bank, 2,804 credits
26
+ 10:20 Priyanka Rao: support has had 310 contacts about this so far
27
+
28
+ == Thu 24 Sep ==
29
+ 14:30 Farah Okonkwo: refund file 2 submitted, 131 credits (these needed manual matching)
30
+ 15:02 Dermot Fahy: all customers refunded. closing the incident. actions:
31
+ - dd-collect: skip any debit already included in a file that day (Farah, due 16 Oct)
32
+ - scheduler: a job must stop itself when its node loses the lock (Wen, date TBD)
33
+ - alert when more than one debit file goes to the bank in a night (owner?)
34
+ - revisit lock TTL (Ines, no date)
@@ -0,0 +1,15 @@
1
+ 2026-09-22T01:02:00Z sched-a leader=sched-a job=dd-collect run=55120 START batches=20
2
+ 2026-09-22T01:26:41Z sched-a run=55120 batch 14/20 committed
3
+ 2026-09-22T01:27:09Z sched-a WARN lock store unreachable (timeout)
4
+ 2026-09-22T01:27:39Z lockstore lease holder=sched-a expired (ttl=30s)
5
+ 2026-09-22T01:27:40Z sched-b acquired leadership
6
+ 2026-09-22T01:30:12Z sched-a lock store reachable; leader is sched-b; demoting. running jobs: 1 (not interrupted)
7
+ 2026-09-22T01:31:00Z sched-b job=dd-collect last_status=RUNNING owner=sched-a (not leader) -> treating as orphaned, START run=55121
8
+ 2026-09-22T01:31:02Z sched-b run=55121 resuming from batch 15/20
9
+ 2026-09-22T01:33:20Z alert job-duration-anomaly job=dd-collect -> #batch-alerts (severity=info)
10
+ 2026-09-22T01:35:04Z page LOW "sched-a: lock store unreachable" -> platform on-call, acked 01:36:10
11
+ 2026-09-22T01:49:30Z sched-a run=55120 batch 20/20 committed, DONE
12
+ 2026-09-22T01:50:05Z sched-a run=55120 submitted DD-20260922-A rows=9870
13
+ 2026-09-22T02:16:48Z sched-b run=55121 batch 20/20 committed, DONE
14
+ 2026-09-22T02:17:15Z sched-b run=55121 submitted DD-20260922-B rows=3401
15
+ 2026-09-22T07:48:22Z job=dd-collect disabled on sched-a, sched-b by wli