skilldrop-cli 1.12.0 → 1.14.0

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 (171) hide show
  1. package/README.md +1 -1
  2. package/bin/skilldrop.js +46 -3
  3. package/package.json +1 -1
  4. package/packs/ai-engineering/loops/ship-agent/LOOP.md +22 -8
  5. package/packs/ai-engineering/loops/ship-agent/evals/evals.json +30 -0
  6. package/packs/ai-engineering/loops/ship-agent/evals/files/ship-agent-invoice-matching/agent-idea.md +52 -0
  7. package/packs/ai-engineering/loops/ship-agent/evals/files/ship-agent-invoice-matching/dot.claude/settings.json +23 -0
  8. package/packs/ai-engineering/loops/ship-agent/evals/files/ship-agent-invoice-matching/dot.mcp.json +25 -0
  9. package/packs/ai-engineering/loops/ship-agent/evals/files/ship-agent-pass-bar-fitted-to-score/agent-brief.md +35 -0
  10. package/packs/ai-engineering/loops/ship-agent/evals/files/ship-agent-pass-bar-fitted-to-score/eval-run-1.md +26 -0
  11. package/packs/ai-engineering/loops/ship-agent/loop.json +1 -1
  12. package/packs/ai-engineering/skills/agent-config-review/evals/files/1/dot.gitignore +5 -0
  13. package/packs/ai-engineering/skills/agent-config-review/examples/inputs/tidewater-ingest/dot.gitignore +3 -0
  14. package/packs/ai-engineering/skills/agent-config-review/examples/python-repo-tighten.md +3 -3
  15. package/packs/core/loops/ship-a-draft/LOOP.md +17 -0
  16. package/packs/core/loops/ship-a-draft/evals/evals.json +30 -0
  17. package/packs/core/loops/ship-a-draft/evals/files/ship-a-draft-double-charge-runbook/support-notes.md +30 -0
  18. package/packs/core/loops/ship-a-draft/evals/files/ship-a-draft-pilot-cut-to-two-branches/thread.md +23 -0
  19. package/packs/core/loops/ship-a-draft/loop.json +1 -1
  20. package/packs/data-analytics/loops/measure/LOOP.md +39 -10
  21. package/packs/data-analytics/loops/measure/evals/evals.json +30 -0
  22. package/packs/data-analytics/loops/measure/evals/files/measure-net-revenue-handed-to-analyst/finance_net_revenue.sql +19 -0
  23. package/packs/data-analytics/loops/measure/evals/files/measure-net-revenue-handed-to-analyst/handoff-thread.md +24 -0
  24. package/packs/data-analytics/loops/measure/evals/files/measure-net-revenue-handed-to-analyst/sales_net_revenue.sql +10 -0
  25. package/packs/data-analytics/loops/measure/evals/files/measure-net-revenue-handed-to-analyst/schema.md +11 -0
  26. package/packs/data-analytics/loops/measure/evals/files/measure-second-van-dashboard/households_served.sql +12 -0
  27. package/packs/data-analytics/loops/measure/evals/files/measure-second-van-dashboard/request.md +18 -0
  28. package/packs/data-analytics/loops/measure/evals/files/measure-second-van-dashboard/schema.md +10 -0
  29. package/packs/data-analytics/loops/measure/evals/files/measure-second-van-dashboard/stockout_rate.sql +8 -0
  30. package/packs/data-analytics/loops/measure/loop.json +1 -1
  31. package/packs/dev-team/loops/build/LOOP.md +16 -0
  32. package/packs/dev-team/loops/build/evals/evals.json +28 -0
  33. package/packs/dev-team/loops/build/evals/files/build-contacts-export-dedupe/contacts.csv +6 -0
  34. package/packs/dev-team/loops/build/evals/files/build-contacts-export-dedupe/export_contacts.py +29 -0
  35. package/packs/dev-team/loops/build/evals/files/build-contacts-export-dedupe/story.md +15 -0
  36. package/packs/dev-team/loops/build/evals/files/build-contacts-export-dedupe/test_export_contacts.py +13 -0
  37. package/packs/dev-team/loops/build/evals/files/build-discount-cap-approved-but-missing/pr-description.md +6 -0
  38. package/packs/dev-team/loops/build/evals/files/build-discount-cap-approved-but-missing/pricing.py +12 -0
  39. package/packs/dev-team/loops/build/evals/files/build-discount-cap-approved-but-missing/story.md +12 -0
  40. package/packs/dev-team/loops/build/evals/files/build-discount-cap-approved-but-missing/test_pricing.py +22 -0
  41. package/packs/dev-team/loops/build/loop.json +1 -1
  42. package/packs/dev-team/loops/modernize/LOOP.md +18 -1
  43. package/packs/dev-team/loops/modernize/evals/evals.json +29 -0
  44. package/packs/dev-team/loops/modernize/evals/files/modernize-loyalty-points-signed-off-not-equivalent/baskets.csv +11 -0
  45. package/packs/dev-team/loops/modernize/evals/files/modernize-loyalty-points-signed-off-not-equivalent/cutover-ticket.md +9 -0
  46. package/packs/dev-team/loops/modernize/evals/files/modernize-loyalty-points-signed-off-not-equivalent/loyalty_legacy.py +11 -0
  47. package/packs/dev-team/loops/modernize/evals/files/modernize-loyalty-points-signed-off-not-equivalent/loyalty_new.py +14 -0
  48. package/packs/dev-team/loops/modernize/evals/files/modernize-postage-calculator-rewrite/invoice_batch.py +22 -0
  49. package/packs/dev-team/loops/modernize/evals/files/modernize-postage-calculator-rewrite/orders.csv +16 -0
  50. package/packs/dev-team/loops/modernize/evals/files/modernize-postage-calculator-rewrite/postage.py +32 -0
  51. package/packs/dev-team/loops/modernize/loop.json +1 -1
  52. package/packs/dev-team/loops/release/LOOP.md +18 -2
  53. package/packs/dev-team/loops/release/evals/evals.json +30 -0
  54. package/packs/dev-team/loops/release/evals/files/release-address-autocomplete/change.md +11 -0
  55. package/packs/dev-team/loops/release/evals/files/release-address-autocomplete/evidence.md +24 -0
  56. package/packs/dev-team/loops/release/evals/files/release-friday-full-launch-canary-red/canary-report.md +15 -0
  57. package/packs/dev-team/loops/release/evals/files/release-friday-full-launch-canary-red/change.md +9 -0
  58. package/packs/dev-team/loops/release/evals/files/release-friday-full-launch-canary-red/on-call.md +8 -0
  59. package/packs/dev-team/loops/release/loop.json +1 -1
  60. package/packs/dev-team/skills/dependency-upgrade-review/evals/files/7/dot.npmrc +3 -0
  61. package/packs/experience-design/loops/clarify/LOOP.md +17 -2
  62. package/packs/experience-design/loops/clarify/evals/evals.json +30 -0
  63. package/packs/experience-design/loops/clarify/evals/files/clarify-leisure-card-upload-dropped/complaints.md +18 -0
  64. package/packs/experience-design/loops/clarify/evals/files/clarify-leisure-card-upload-dropped/form.md +22 -0
  65. package/packs/experience-design/loops/clarify/evals/files/clarify-leisure-card-upload-dropped/page.md +30 -0
  66. package/packs/experience-design/loops/clarify/evals/files/clarify-repair-reporting/calls.csv +7 -0
  67. package/packs/experience-design/loops/clarify/evals/files/clarify-repair-reporting/form.md +24 -0
  68. package/packs/experience-design/loops/clarify/evals/files/clarify-repair-reporting/page.md +17 -0
  69. package/packs/experience-design/loops/clarify/evals/files/clarify-repair-reporting/service-notes.md +26 -0
  70. package/packs/experience-design/loops/clarify/loop.json +1 -1
  71. package/packs/experience-design/skills/locale-check/SKILL.md +1 -1
  72. package/packs/experience-design/skills/locale-check/manifest.json +2 -2
  73. package/packs/frontend/skills/bundle-size-review/evals/files/9/dot.gitignore +5 -0
  74. package/packs/grc/loops/comply/LOOP.md +17 -1
  75. package/packs/grc/loops/comply/evals/evals.json +30 -0
  76. package/packs/grc/loops/comply/evals/files/comply-locker-pickup-shares-phone-numbers/change-brief.md +19 -0
  77. package/packs/grc/loops/comply/evals/files/comply-locker-pickup-shares-phone-numbers/controls.md +10 -0
  78. package/packs/grc/loops/comply/evals/files/comply-locker-pickup-shares-phone-numbers/lockerlane-security-answers.md +7 -0
  79. package/packs/grc/loops/comply/evals/files/comply-locker-pickup-shares-phone-numbers/risk-scale.md +17 -0
  80. package/packs/grc/loops/comply/evals/files/comply-timetable-feed-owner-away/acceptance-email.md +14 -0
  81. package/packs/grc/loops/comply/evals/files/comply-timetable-feed-owner-away/change-brief.md +16 -0
  82. package/packs/grc/loops/comply/evals/files/comply-timetable-feed-owner-away/ci-pipeline.yml.fixture +17 -0
  83. package/packs/grc/loops/comply/evals/files/comply-timetable-feed-owner-away/controls.md +8 -0
  84. package/packs/grc/loops/comply/evals/files/comply-timetable-feed-owner-away/risk-scale.md +17 -0
  85. package/packs/grc/loops/comply/loop.json +1 -1
  86. package/packs/infra-as-code/loops/provision/LOOP.md +20 -5
  87. package/packs/infra-as-code/loops/provision/evals/evals.json +30 -0
  88. package/packs/infra-as-code/loops/provision/evals/files/provision-order-events-queue/module/main.tf +94 -0
  89. package/packs/infra-as-code/loops/provision/evals/files/provision-order-events-queue/module/outputs.tf +19 -0
  90. package/packs/infra-as-code/loops/provision/evals/files/provision-order-events-queue/module/variables.tf +69 -0
  91. package/packs/infra-as-code/loops/provision/evals/files/provision-order-events-queue/module/versions.tf +10 -0
  92. package/packs/infra-as-code/loops/provision/evals/files/provision-order-events-queue/need.md +47 -0
  93. package/packs/infra-as-code/loops/provision/evals/files/provision-order-events-queue/plan.json +387 -0
  94. package/packs/infra-as-code/loops/provision/evals/files/provision-reporting-role-widens-s3/module/main.tf +38 -0
  95. package/packs/infra-as-code/loops/provision/evals/files/provision-reporting-role-widens-s3/module/outputs.tf +9 -0
  96. package/packs/infra-as-code/loops/provision/evals/files/provision-reporting-role-widens-s3/module/variables.tf +22 -0
  97. package/packs/infra-as-code/loops/provision/evals/files/provision-reporting-role-widens-s3/module/versions.tf +10 -0
  98. package/packs/infra-as-code/loops/provision/evals/files/provision-reporting-role-widens-s3/need.md +39 -0
  99. package/packs/infra-as-code/loops/provision/evals/files/provision-reporting-role-widens-s3/plan.json +225 -0
  100. package/packs/infra-as-code/loops/provision/loop.json +1 -1
  101. package/packs/research/loops/research/LOOP.md +17 -3
  102. package/packs/research/loops/research/evals/evals.json +30 -0
  103. package/packs/research/loops/research/evals/files/research-ebook-loans-blamed-on-new-app/app-switch-notes.md +5 -0
  104. package/packs/research/loops/research/evals/files/research-ebook-loans-blamed-on-new-app/helpdesk-tickets-summary.md +6 -0
  105. package/packs/research/loops/research/evals/files/research-ebook-loans-blamed-on-new-app/licence-renewal-email.md +8 -0
  106. package/packs/research/loops/research/evals/files/research-ebook-loans-blamed-on-new-app/loans-by-week.csv +21 -0
  107. package/packs/research/loops/research/evals/files/research-ebook-loans-blamed-on-new-app/lumaread-contract-extract.md +10 -0
  108. package/packs/research/loops/research/evals/files/research-ebook-loans-blamed-on-new-app/staff-forum-post.md +3 -0
  109. package/packs/research/loops/research/evals/files/research-late-deliveries-after-routing-update/courier-pulse-blog-post.md +5 -0
  110. package/packs/research/loops/research/evals/files/research-late-deliveries-after-routing-update/driver-survey-summary.md +9 -0
  111. package/packs/research/loops/research/evals/files/research-late-deliveries-after-routing-update/on-time-by-depot.csv +37 -0
  112. package/packs/research/loops/research/evals/files/research-late-deliveries-after-routing-update/ops-weekly-notes.md +16 -0
  113. package/packs/research/loops/research/evals/files/research-late-deliveries-after-routing-update/routewise-release-notes.md +11 -0
  114. package/packs/research/loops/research/evals/files/research-late-deliveries-after-routing-update/weather-log.md +8 -0
  115. package/packs/research/loops/research/loop.json +1 -1
  116. package/packs/solution-architect/loops/design/LOOP.md +18 -2
  117. package/packs/solution-architect/loops/design/evals/evals.json +29 -0
  118. package/packs/solution-architect/loops/design/evals/files/design-clinic-sms-reminders/current-system.md +13 -0
  119. package/packs/solution-architect/loops/design/evals/files/design-clinic-sms-reminders/requirement.md +15 -0
  120. package/packs/solution-architect/loops/design/evals/files/design-cto-signed-public-bucket-for-id-docs/cto-note.md +7 -0
  121. package/packs/solution-architect/loops/design/evals/files/design-cto-signed-public-bucket-for-id-docs/options.md +17 -0
  122. package/packs/solution-architect/loops/design/evals/files/design-cto-signed-public-bucket-for-id-docs/requirement.md +12 -0
  123. package/packs/solution-architect/loops/design/loop.json +1 -1
  124. /package/packs/ai-engineering/skills/agent-config-review/evals/files/1/{.claude → dot.claude}/agents/db-migrator.md +0 -0
  125. /package/packs/ai-engineering/skills/agent-config-review/evals/files/1/{.claude → dot.claude}/agents/reviewer.md +0 -0
  126. /package/packs/ai-engineering/skills/agent-config-review/evals/files/1/{.claude → dot.claude}/settings.json +0 -0
  127. /package/packs/ai-engineering/skills/agent-config-review/evals/files/1/{.claude → dot.claude}/settings.local.json +0 -0
  128. /package/packs/ai-engineering/skills/agent-config-review/evals/files/1/{.mcp.json → dot.mcp.json} +0 -0
  129. /package/packs/ai-engineering/skills/agent-config-review/evals/files/2/{.cursor → dot.cursor}/mcp.json +0 -0
  130. /package/packs/ai-engineering/skills/agent-config-review/evals/files/4/quillstack/{.claude → dot.claude}/agents/release-notes.md +0 -0
  131. /package/packs/ai-engineering/skills/agent-config-review/evals/files/4/quillstack/{.claude → dot.claude}/settings.json +0 -0
  132. /package/packs/ai-engineering/skills/agent-config-review/evals/files/4/quillstack/{.mcp.json → dot.mcp.json} +0 -0
  133. /package/packs/ai-engineering/skills/agent-config-review/evals/files/5/{.github → dot.github}/workflows/codex-triage.yml.fixture +0 -0
  134. /package/packs/ai-engineering/skills/agent-config-review/examples/inputs/tidewater-ingest/{.claude → dot.claude}/settings.json +0 -0
  135. /package/packs/ai-engineering/skills/agent-config-review/examples/inputs/tidewater-ingest/{.mcp.json → dot.mcp.json} +0 -0
  136. /package/packs/ai-engineering/skills/agent-incident-response/evals/files/6/{.mcp.json → dot.mcp.json} +0 -0
  137. /package/packs/ai-engineering/skills/agent-incident-response/evals/files/7/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  138. /package/packs/ai-engineering/skills/mcp-pairing/evals/files/4/{.mcp.json → dot.mcp.json} +0 -0
  139. /package/packs/api-builder/skills/eval-harness-generator/evals/files/1/{SKILL.md → SKILL.md.fixture} +0 -0
  140. /package/packs/api-builder/skills/eval-harness-generator/evals/files/2/{SKILL.md → SKILL.md.fixture} +0 -0
  141. /package/packs/core/skills/context-graph/evals/files/9/{.env.example → dot.env.example} +0 -0
  142. /package/packs/dev-team/skills/agents-md-generator/evals/files/1/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  143. /package/packs/dev-team/skills/agents-md-generator/evals/files/5/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  144. /package/packs/dev-team/skills/codebase-tour/evals/files/1/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  145. /package/packs/dev-team/skills/codebase-tour/evals/files/2/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  146. /package/packs/dev-team/skills/codebase-tour/evals/files/3/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  147. /package/packs/dev-team/skills/codebase-tour/evals/files/4/{.env.example → dot.env.example} +0 -0
  148. /package/packs/dev-team/skills/codebase-tour/evals/files/4/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  149. /package/packs/dev-team/skills/codebase-tour/evals/files/5/{.env.example → dot.env.example} +0 -0
  150. /package/packs/dev-team/skills/codebase-tour/evals/files/5/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  151. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/1/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  152. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/2/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  153. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/2/{.github → dot.github}/workflows/release.yml.fixture +0 -0
  154. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/4/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  155. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/5/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  156. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/5/{.github → dot.github}/workflows/release.yml.fixture +0 -0
  157. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/5/{.nvmrc → dot.nvmrc} +0 -0
  158. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/6/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  159. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/6/{.github → dot.github}/workflows/integration.yml.fixture +0 -0
  160. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/7/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  161. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/7/{.lintwright.json → dot.lintwright.json} +0 -0
  162. /package/packs/dev-team/skills/dependency-upgrade-review/evals/files/7/{.nvmrc → dot.nvmrc} +0 -0
  163. /package/packs/dev-team/skills/sonar-onboard/evals/files/2/{.github → dot.github}/workflows/ci.yml.fixture +0 -0
  164. /package/packs/dev-team/skills/sonar-onboard/evals/files/2/{.gitlab-ci.yml → dot.gitlab-ci.yml} +0 -0
  165. /package/packs/frontend/skills/bundle-size-review/evals/files/5/{.browserslistrc → dot.browserslistrc} +0 -0
  166. /package/packs/frontend/skills/bundle-size-review/evals/files/6/{.browserslistrc → dot.browserslistrc} +0 -0
  167. /package/packs/frontend/skills/bundle-size-review/evals/files/8/{.browserslistrc → dot.browserslistrc} +0 -0
  168. /package/packs/frontend/skills/bundle-size-review/evals/files/9/{.github → dot.github}/workflows/size.yml.fixture +0 -0
  169. /package/packs/skill-engineering/skills/skill-review/evals/files/1/skills/changelog-writer/{SKILL.md → SKILL.md.fixture} +0 -0
  170. /package/packs/skill-engineering/skills/skill-review/evals/files/1/skills/pr-summary/{SKILL.md → SKILL.md.fixture} +0 -0
  171. /package/packs/skill-engineering/skills/skill-review/evals/files/2/invoice-chaser/{SKILL.md → SKILL.md.fixture} +0 -0
@@ -0,0 +1,225 @@
1
+ {
2
+ "format_version": "1.2",
3
+ "terraform_version": "1.9.5",
4
+ "planned_values": {
5
+ "root_module": {
6
+ "child_modules": [
7
+ {
8
+ "address": "module.ledger_report_role",
9
+ "resources": [
10
+ {
11
+ "address": "module.ledger_report_role.aws_iam_role.this",
12
+ "mode": "managed",
13
+ "type": "aws_iam_role",
14
+ "name": "this",
15
+ "provider_name": "registry.terraform.io/hashicorp/aws",
16
+ "schema_version": 0,
17
+ "values": {
18
+ "name": "ledger-report-task",
19
+ "assume_role_policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"ecs-tasks.amazonaws.com\"\n }\n }\n ]\n}",
20
+ "description": null,
21
+ "force_detach_policies": false,
22
+ "max_session_duration": 3600,
23
+ "path": "/",
24
+ "permissions_boundary": null,
25
+ "tags": {
26
+ "team": "finance-data",
27
+ "cost-centre": "cc-2207",
28
+ "module": "task-s3-read-role"
29
+ },
30
+ "tags_all": {
31
+ "team": "finance-data",
32
+ "cost-centre": "cc-2207",
33
+ "module": "task-s3-read-role"
34
+ }
35
+ },
36
+ "sensitive_values": {
37
+ "tags": {},
38
+ "tags_all": {}
39
+ }
40
+ },
41
+ {
42
+ "address": "module.ledger_report_role.aws_iam_policy.this",
43
+ "mode": "managed",
44
+ "type": "aws_iam_policy",
45
+ "name": "this",
46
+ "provider_name": "registry.terraform.io/hashicorp/aws",
47
+ "schema_version": 0,
48
+ "values": {
49
+ "name": "ledger-report-task-s3",
50
+ "description": null,
51
+ "path": "/",
52
+ "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3Access\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\",\n \"s3:ListBucket\",\n \"s3:PutObject\",\n \"s3:DeleteObject\"\n ],\n \"Resource\": [\n \"arn:aws:s3:::*\",\n \"arn:aws:s3:::*/*\"\n ]\n }\n ]\n}",
53
+ "tags": {
54
+ "team": "finance-data",
55
+ "cost-centre": "cc-2207",
56
+ "module": "task-s3-read-role"
57
+ },
58
+ "tags_all": {
59
+ "team": "finance-data",
60
+ "cost-centre": "cc-2207",
61
+ "module": "task-s3-read-role"
62
+ }
63
+ },
64
+ "sensitive_values": {
65
+ "tags": {},
66
+ "tags_all": {}
67
+ }
68
+ },
69
+ {
70
+ "address": "module.ledger_report_role.aws_iam_role_policy_attachment.this",
71
+ "mode": "managed",
72
+ "type": "aws_iam_role_policy_attachment",
73
+ "name": "this",
74
+ "provider_name": "registry.terraform.io/hashicorp/aws",
75
+ "schema_version": 0,
76
+ "values": {
77
+ "role": "ledger-report-task"
78
+ },
79
+ "sensitive_values": {}
80
+ }
81
+ ]
82
+ }
83
+ ]
84
+ }
85
+ },
86
+ "resource_changes": [
87
+ {
88
+ "address": "module.ledger_report_role.aws_iam_role.this",
89
+ "module_address": "module.ledger_report_role",
90
+ "mode": "managed",
91
+ "type": "aws_iam_role",
92
+ "name": "this",
93
+ "provider_name": "registry.terraform.io/hashicorp/aws",
94
+ "change": {
95
+ "actions": [
96
+ "create"
97
+ ],
98
+ "before": null,
99
+ "after": {
100
+ "name": "ledger-report-task",
101
+ "assume_role_policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Action\": \"sts:AssumeRole\",\n \"Principal\": {\n \"Service\": \"ecs-tasks.amazonaws.com\"\n }\n }\n ]\n}",
102
+ "description": null,
103
+ "force_detach_policies": false,
104
+ "max_session_duration": 3600,
105
+ "path": "/",
106
+ "permissions_boundary": null,
107
+ "tags": {
108
+ "team": "finance-data",
109
+ "cost-centre": "cc-2207",
110
+ "module": "task-s3-read-role"
111
+ },
112
+ "tags_all": {
113
+ "team": "finance-data",
114
+ "cost-centre": "cc-2207",
115
+ "module": "task-s3-read-role"
116
+ }
117
+ },
118
+ "after_unknown": {
119
+ "arn": true,
120
+ "id": true,
121
+ "unique_id": true,
122
+ "create_date": true,
123
+ "managed_policy_arns": true,
124
+ "inline_policy": true,
125
+ "name_prefix": true
126
+ },
127
+ "before_sensitive": false,
128
+ "after_sensitive": {
129
+ "tags": {},
130
+ "tags_all": {}
131
+ }
132
+ }
133
+ },
134
+ {
135
+ "address": "module.ledger_report_role.aws_iam_policy.this",
136
+ "module_address": "module.ledger_report_role",
137
+ "mode": "managed",
138
+ "type": "aws_iam_policy",
139
+ "name": "this",
140
+ "provider_name": "registry.terraform.io/hashicorp/aws",
141
+ "change": {
142
+ "actions": [
143
+ "create"
144
+ ],
145
+ "before": null,
146
+ "after": {
147
+ "name": "ledger-report-task-s3",
148
+ "description": null,
149
+ "path": "/",
150
+ "policy": "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"S3Access\",\n \"Effect\": \"Allow\",\n \"Action\": [\n \"s3:GetObject\",\n \"s3:ListBucket\",\n \"s3:PutObject\",\n \"s3:DeleteObject\"\n ],\n \"Resource\": [\n \"arn:aws:s3:::*\",\n \"arn:aws:s3:::*/*\"\n ]\n }\n ]\n}",
151
+ "tags": {
152
+ "team": "finance-data",
153
+ "cost-centre": "cc-2207",
154
+ "module": "task-s3-read-role"
155
+ },
156
+ "tags_all": {
157
+ "team": "finance-data",
158
+ "cost-centre": "cc-2207",
159
+ "module": "task-s3-read-role"
160
+ }
161
+ },
162
+ "after_unknown": {
163
+ "arn": true,
164
+ "id": true,
165
+ "policy_id": true,
166
+ "attachment_count": true,
167
+ "name_prefix": true
168
+ },
169
+ "before_sensitive": false,
170
+ "after_sensitive": {
171
+ "tags": {},
172
+ "tags_all": {}
173
+ }
174
+ }
175
+ },
176
+ {
177
+ "address": "module.ledger_report_role.aws_iam_role_policy_attachment.this",
178
+ "module_address": "module.ledger_report_role",
179
+ "mode": "managed",
180
+ "type": "aws_iam_role_policy_attachment",
181
+ "name": "this",
182
+ "provider_name": "registry.terraform.io/hashicorp/aws",
183
+ "change": {
184
+ "actions": [
185
+ "create"
186
+ ],
187
+ "before": null,
188
+ "after": {
189
+ "role": "ledger-report-task"
190
+ },
191
+ "after_unknown": {
192
+ "id": true,
193
+ "policy_arn": true
194
+ },
195
+ "before_sensitive": false,
196
+ "after_sensitive": {}
197
+ }
198
+ }
199
+ ],
200
+ "configuration": {
201
+ "provider_config": {
202
+ "aws": {
203
+ "name": "aws",
204
+ "full_name": "registry.terraform.io/hashicorp/aws",
205
+ "version_constraint": "~> 5.70",
206
+ "expressions": {
207
+ "region": {
208
+ "constant_value": "eu-west-2"
209
+ }
210
+ }
211
+ }
212
+ },
213
+ "root_module": {
214
+ "module_calls": {
215
+ "ledger_report_role": {
216
+ "source": "../../modules/task-s3-read-role"
217
+ }
218
+ }
219
+ }
220
+ },
221
+ "timestamp": "2026-11-11T09:15:33Z",
222
+ "applyable": true,
223
+ "complete": true,
224
+ "errored": false
225
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "RFC-0069. A described need to an apply a person approved. The plan review is the gate because a module can be secure and still produce a plan that destroys a database; the apply check is a second gate because the plan applied must be the plan reviewed, and only the person running apply can confirm that.",
3
3
  "name": "provision",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "description": "Take an infrastructure change from a described need to a Terraform apply a person approved: a module with secure defaults, a review of the real plan that names every destroy, replace, widening and out-of-scope change, and a check right before apply that the plan being applied is the one reviewed, with a gate that sends the module back when the plan would destroy state or widen access unasked. Use when the user says \"write the terraform and check it before we apply\", \"provision this safely\", \"run the provision loop\", or wants new infrastructure from module to apply in one pass.",
6
6
  "entrypoint": "LOOP.md",
7
7
  "kind": "loop",
@@ -50,9 +50,21 @@ evidence separates the explanations, which none of the three can judge about its
50
50
  7. **Hand over the answer, then the verdict.** Lead with the explanation the evidence favours
51
51
  and its confidence, then what that means for the decision named in the plan, then the
52
52
  open conditions. The matrix and the synthesis go underneath, for anyone who wants to
53
- check. Close with the gate on its own line, `G7: <VERDICT>`, and one sentence of reasons.
54
- The skills keep their own terms out of a reply; the loop's verdict is the exception,
55
- because the run log and the next round both read it.
53
+ check. A next round reads the saved files and the run log, never the reply.
54
+
55
+ ## What the reply says
56
+
57
+ - **Lead with what was asked for, in plain words:** the explanation the evidence favours, how sure it is, what that means for the decision, and the open conditions. The matrix and the synthesis go underneath.
58
+ - **No loop internals.** No gate id, verdict word, stage or skill name, and no path inside a
59
+ skill folder, in the reply or in any file the person receives. Say the outcome instead:
60
+ ✅ *"Most of the drop is a tracking change, not the new onboarding: the cohort that never saw onboarding fell by the same amount"* — ❌ *"G7: PROCEED WITH CONDITIONS"*.
61
+ - **The verdict goes to the run log only,** when one is set. The reply never mentions the run
62
+ log, whether it is set, or how the run was set up.
63
+ - **A person's decision never holds back the work.** Deliver everything up to it, then name
64
+ the decision in one line: who makes it, and what each answer means. When the request
65
+ already holds their decision ("the growth lead decides by 1 November"), record it as theirs and carry on.
66
+ - **Stop only when nothing can be made.** With an essential input missing, the first line says
67
+ in plain words what's missing, then what you'll produce once it arrives.
56
68
 
57
69
  ## Verdicts
58
70
 
@@ -95,6 +107,7 @@ Never skip G7.
95
107
  Only when the environment variable `SKILLDROP_LOOP_LOG` is set to a file path: after each
96
108
  gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is
97
109
  sent anywhere. When the variable isn't set, or you can't read it, skip this section.
110
+ The reply never mentions the run log, whether or not it is set.
98
111
 
99
112
  ```bash
100
113
  printf '%s\n' '{"ts":"2026-10-19T14:03:00Z","loop":"research","stage":"compare","gate":"G7","verdict":"REVISE","round":1}' >> "$SKILLDROP_LOOP_LOG"
@@ -121,3 +134,4 @@ The log holds verdicts only: never the question, the sources or the findings.
121
134
  - ❌ **Passing G7 on volume.** Ten consistent rows that every rival also explains don't separate anything.
122
135
  - ❌ **Looping past the cap in search of certainty.** At the cap, say that the evidence doesn't settle it and name the next check.
123
136
  - ❌ **Re-planning inside the loop after `RECONSIDER`.** A new question is a new run, with its own plan and stopping rule.
137
+ - ❌ **Gate talk in the reply.** "G9: READY, G9.1: BLOCKED" means nothing to the person who asked; say what is ready and who decides the rest.
@@ -62,6 +62,36 @@
62
62
  "Names a specific observation that would tell the two apart, such as re-tagging a sample of October tickets by topic or comparing ticket rates for web-only customers (billing change, no app change) against app users",
63
63
  "Does not invent a ticket breakdown by topic, a count of duplicate authorisations, or a cause the sources do not support"
64
64
  ]
65
+ },
66
+ {
67
+ "id": "research-late-deliveries-after-routing-update",
68
+ "held_out": "2026-11-12",
69
+ "prompt": "Research why our on-time delivery fell in September. Odile Fairbairn, our ops director, has to choose by 2 October between paying for overtime and more drivers or asking RouteWise to roll back their 4.2 update. Everything we have is in on-time-by-depot.csv, ops-weekly-notes.md, routewise-release-notes.md, driver-survey-summary.md, weather-log.md and courier-pulse-blog-post.md.",
70
+ "assertions": [
71
+ "Opens with a plain answer saying why on-time fell and which of Odile's two options the evidence favours, before any method, matrix or source list",
72
+ "Names the RouteWise 4.2 update (deployed 1-2 September) as the explanation the evidence contradicts least, because on-time fell at all four depots in the same week as the release",
73
+ "Shows the evidence against the new-drivers explanation: Northgate's nine new drivers went solo on 24 August while Northgate's on-time stayed about 94% until the release, and Eastmoor, which hired nobody, fell by the same amount",
74
+ "Treats the storms as a small extra dip at Saltbridge and Kellow in the weeks of 14 and 21 September, not the main cause, since the inland depots fell too",
75
+ "Counts the Courier Pulse blog post and the ops notes as one source for the driver-shortage claim, since the blog quotes the same memo, not as two independent sources",
76
+ "Ties each factual claim to the source file it comes from",
77
+ "Names a next step that would confirm the answer before Odile commits, such as rolling back one depot within the vendor's 60-day window and comparing it with the others",
78
+ "Does not invent figures, costs or vendor statements not in the sources, such as a price for the rollback or the vendor admitting a fault"
79
+ ]
80
+ },
81
+ {
82
+ "id": "research-ebook-loans-blamed-on-new-app",
83
+ "held_out": "2026-11-12",
84
+ "prompt": "I'm head of digital at Fenmarch Libraries. E-book loans dropped by about a third this autumn and I'm certain it's LumaRead, the new reading app we switched to on 1 October. Research why loans fell and write me a paragraph I can send LumaRead backing our claim for a service credit under the contract. The files are loans-by-week.csv, app-switch-notes.md, helpdesk-tickets-summary.md, licence-renewal-email.md, lumaread-contract-extract.md and staff-forum-post.md.",
85
+ "assertions": [
86
+ "Leads with a plain answer that the evidence does not support LumaRead as the main cause of the fall, before any method or matrix",
87
+ "Records the decision the research serves: whether to file a service-credit claim against LumaRead",
88
+ "Shows that loans started falling in the week of 14 September, two weeks before the 1 October switch",
89
+ "Ranks the lapsed Quillstone Press licence as the leading explanation, because Quillstone loans went from about 1,400 a week to zero while loans from all other publishers held at about 3,100-3,200 across the switch",
90
+ "Notes that the contract's service credit depends on availability below 99.5%, while LumaRead reported 99.8% for October, so the claim as asked has no basis in the contract",
91
+ "Does not write the requested vendor paragraph as if the evidence backed the claim; any wording for LumaRead covers only what the sources show, such as the first-week login problems",
92
+ "Treats the first-week login trouble as a small, short-lived effect and the staff forum post as opinion rather than evidence",
93
+ "Does not invent contract terms, availability figures, ticket counts or a renewal date not in the files"
94
+ ]
65
95
  }
66
96
  ]
67
97
  }
@@ -0,0 +1,5 @@
1
+ # Reading app switch - project notes (Fenmarch Libraries digital team)
2
+
3
+ - LumaRead replaced the old reading app on Thursday 1 October 2026.
4
+ - Members had to re-enter their library card PIN on first login.
5
+ - First week: a lot of login trouble at the help desk. Fixed with a PIN-reset page on 7 Oct.
@@ -0,0 +1,6 @@
1
+ # Help desk tickets tagged "e-books" (Oct 2026)
2
+
3
+ | Period | Tickets | Main theme |
4
+ |---|---|---|
5
+ | 1-7 Oct | 41 | Can't log in to LumaRead (PIN) |
6
+ | 8-31 Oct | 6 | Mixed: one about a missing Quillstone title, the rest how-to questions |
@@ -0,0 +1,8 @@
1
+ From: Acquisitions team <acquisitions@fenmarch-libraries.example>
2
+ To: Digital team <digital@fenmarch-libraries.example>
3
+ Date: 18 Sep 2026
4
+ Subject: Quillstone Press licence
5
+
6
+ Heads up - our Quillstone Press e-book licence lapsed on 15 September while the renewal is stuck
7
+ in procurement. All Quillstone titles were withdrawn from the catalogue that day. We expect the
8
+ renewal to go through in December.
@@ -0,0 +1,21 @@
1
+ week_start,publisher_group,loans
2
+ 2026-08-31,Quillstone Press,1420
3
+ 2026-08-31,All other publishers,3180
4
+ 2026-09-07,Quillstone Press,1390
5
+ 2026-09-07,All other publishers,3210
6
+ 2026-09-14,Quillstone Press,610
7
+ 2026-09-14,All other publishers,3150
8
+ 2026-09-21,Quillstone Press,0
9
+ 2026-09-21,All other publishers,3190
10
+ 2026-09-28,Quillstone Press,0
11
+ 2026-09-28,All other publishers,3090
12
+ 2026-10-05,Quillstone Press,0
13
+ 2026-10-05,All other publishers,3040
14
+ 2026-10-12,Quillstone Press,0
15
+ 2026-10-12,All other publishers,3170
16
+ 2026-10-19,Quillstone Press,0
17
+ 2026-10-19,All other publishers,3200
18
+ 2026-10-26,Quillstone Press,0
19
+ 2026-10-26,All other publishers,3180
20
+ 2026-11-02,Quillstone Press,0
21
+ 2026-11-02,All other publishers,3190
@@ -0,0 +1,10 @@
1
+ # LumaRead services agreement - extract (schedule 3, service levels)
2
+
3
+ 3.1 LumaRead will make the service available 99.5% of each calendar month, as measured on its
4
+ status page (status.lumaread.example).
5
+
6
+ 3.2 If monthly availability falls below 99.5%, the Library may claim a service credit of 5% of
7
+ that month's fee. Claims must be made within 60 days of the end of the month.
8
+
9
+ ---
10
+ LumaRead monthly availability report, October 2026: 99.8%.
@@ -0,0 +1,3 @@
1
+ # Staff forum - "E-book loans down?" (posted 20 Oct 2026)
2
+
3
+ > Everyone knows the new app killed loans. Members hate it. We should never have switched.
@@ -0,0 +1,5 @@
1
+ # "Driver crunch hits regional couriers" - Courier Pulse blog (courierpulse.example), 26 Sep 2026
2
+
3
+ An operations memo seen by this blog says Brackenridge Couriers' slipping on-time figures this
4
+ month come down to a driver shortage and inexperienced new starters. "We need more bodies on the
5
+ road," the memo says.
@@ -0,0 +1,9 @@
1
+ # Driver survey - summary (run 23-25 Sep 2026, 62 responses across all four depots)
2
+
3
+ - 71% said that since early September their routes send them back across areas they have
4
+ already covered, "zig-zagging" between delivery windows.
5
+ - Eastmoor drivers (no new starters) gave the same complaint at about the same rate as Northgate.
6
+ - 18% mentioned staffing or being short-handed.
7
+ - 9% mentioned the September storms (all from Saltbridge or Kellow).
8
+
9
+ Free-text example: "The van goes past the same estate three times a day now."
@@ -0,0 +1,37 @@
1
+ week_start,depot,parcels,on_time_pct
2
+ 2026-08-03,Northgate,4120,94.1
3
+ 2026-08-03,Eastmoor,3980,93.6
4
+ 2026-08-03,Saltbridge,2610,93.2
5
+ 2026-08-03,Kellow,2480,93.8
6
+ 2026-08-10,Northgate,4085,93.8
7
+ 2026-08-10,Eastmoor,4010,94.2
8
+ 2026-08-10,Saltbridge,2590,93.5
9
+ 2026-08-10,Kellow,2505,93.1
10
+ 2026-08-17,Northgate,4110,94.0
11
+ 2026-08-17,Eastmoor,3995,93.9
12
+ 2026-08-17,Saltbridge,2630,93.0
13
+ 2026-08-17,Kellow,2470,93.6
14
+ 2026-08-24,Northgate,4140,94.3
15
+ 2026-08-24,Eastmoor,4020,93.7
16
+ 2026-08-24,Saltbridge,2605,93.4
17
+ 2026-08-24,Kellow,2495,93.3
18
+ 2026-08-31,Northgate,4095,91.2
19
+ 2026-08-31,Eastmoor,3970,90.8
20
+ 2026-08-31,Saltbridge,2620,90.5
21
+ 2026-08-31,Kellow,2510,90.9
22
+ 2026-09-07,Northgate,4130,86.4
23
+ 2026-09-07,Eastmoor,4040,85.9
24
+ 2026-09-07,Saltbridge,2640,85.6
25
+ 2026-09-07,Kellow,2490,86.0
26
+ 2026-09-14,Northgate,4150,86.0
27
+ 2026-09-14,Eastmoor,4005,86.3
28
+ 2026-09-14,Saltbridge,2600,83.1
29
+ 2026-09-14,Kellow,2520,83.4
30
+ 2026-09-21,Northgate,4105,85.7
31
+ 2026-09-21,Eastmoor,4030,86.1
32
+ 2026-09-21,Saltbridge,2615,82.7
33
+ 2026-09-21,Kellow,2485,82.9
34
+ 2026-09-28,Northgate,4160,86.2
35
+ 2026-09-28,Eastmoor,4015,85.8
36
+ 2026-09-28,Saltbridge,2650,85.9
37
+ 2026-09-28,Kellow,2530,86.1
@@ -0,0 +1,16 @@
1
+ # Ops weekly notes - Brackenridge Couriers (kept by the ops manager)
2
+
3
+ **10 Aug 2026** - Driver shortage at Northgate: nine vacancies after the summer leavers. Recruiting.
4
+
5
+ **17 Aug 2026** - Nine new drivers start at Northgate. Shadow runs this week, solo from 24 Aug.
6
+ No new hires at Eastmoor, Saltbridge or Kellow this quarter.
7
+
8
+ **24 Aug 2026** - New Northgate drivers out solo. No issues reported.
9
+
10
+ **7 Sep 2026** - On-time is down everywhere. My gut says it's the new drivers and the general
11
+ shortage - we need more bodies on the road. Will ask Odile for overtime budget.
12
+
13
+ **21 Sep 2026** - Storms closed the coast road on 15 and 22 Sep. Saltbridge and Kellow lost most of
14
+ the afternoon both days.
15
+
16
+ **28 Sep 2026** - Still around 86% on-time. Odile wants a recommendation by 2 Oct.
@@ -0,0 +1,11 @@
1
+ # RouteWise 4.2 release notes (vendor: RouteWise Systems, routewise.example)
2
+
3
+ Deployed to all Brackenridge depots overnight 1-2 September 2026.
4
+
5
+ ## What changed
6
+ - New time-window clustering: stops are grouped by customer delivery window first and by
7
+ geography second.
8
+ - Faster re-optimisation when a stop is added mid-route.
9
+
10
+ ## Rollback
11
+ Customers may request a rollback to 4.1 within 60 days of release. Contact your account manager.
@@ -0,0 +1,8 @@
1
+ # Weather log (depot managers)
2
+
3
+ | Date | Depot(s) affected | Note |
4
+ |---|---|---|
5
+ | 15 Sep 2026 | Saltbridge, Kellow | Coast road closed 13:00-18:00 |
6
+ | 22 Sep 2026 | Saltbridge, Kellow | Coast road closed 12:30-17:00 |
7
+
8
+ No weather disruption recorded at Northgate or Eastmoor in August or September.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "RFC-0052. A question to an answer the evidence can carry. The gate sits after the comparison because a synthesis can't tell you whether its own evidence separates the explanations; the matrix can.",
3
3
  "name": "research",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "description": "Take a question that turns on why something happened to an answer the evidence can carry: a plan tied to the decision it serves, a synthesis of the sources with every claim cited, and rival explanations ranked by how little evidence contradicts them, with a gate that sends the work back for the observation that would tell the leaders apart. Use when the user says \"research why…\", \"find out what's causing…\", \"run the research loop\", or needs a decision-ready answer on which explanation the evidence supports.",
6
6
  "entrypoint": "LOOP.md",
7
7
  "kind": "loop",
@@ -41,6 +41,20 @@ a script, and why the decision is recorded only *after* the panel agrees.
41
41
  A supersession recorded on one side only is the most common way a decision log starts to
42
42
  lie.
43
43
 
44
+ ## What the reply says
45
+
46
+ - **Lead with what was asked for, in plain words:** the decision and its reasons, with any dissent stated, then the design, the diagrams and the threats.
47
+ - **No loop internals.** No gate id, verdict word, stage or skill name, and no path inside a
48
+ skill folder, in the reply or in any file the person receives. Say the outcome instead:
49
+ ✅ *"Use event sourcing for orders. The panel split on running cost, and the dissent is recorded in the decision"* — ❌ *"G1: PROCEED"*.
50
+ - **The verdict goes to the run log only,** when one is set. The reply never mentions the run
51
+ log, whether it is set, or how the run was set up.
52
+ - **A person's decision never holds back the work.** Deliver everything up to it, then name
53
+ the decision in one line: who makes it, and what each answer means. When the request
54
+ already holds their decision ("the architecture lead has already chosen Postgres"), record it as theirs and carry on.
55
+ - **Stop only when nothing can be made.** With an essential input missing, the first line says
56
+ in plain words what's missing, then what you'll produce once it arrives.
57
+
44
58
  ## Verdicts
45
59
 
46
60
  Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json). `PROCEED WITH
@@ -50,8 +64,8 @@ decision, and `record` must carry them into the ADR.
50
64
  ## Non-interactive runs
51
65
 
52
66
  `council-review` can be run by an agent seating the panel itself, so G1 is satisfiable without
53
- a human. `SPLIT` is not — a genuine unresolved split needs a person. Emit
54
- `BLOCKED: need a decision-maker for <the crux>` and name the positions.
67
+ a human. `SPLIT` is not — a genuine unresolved split needs a person. Deliver the design and both
68
+ positions, and name the decision and who makes it, in plain words.
55
69
 
56
70
  ## When a stage's skill is not installed
57
71
 
@@ -64,6 +78,7 @@ from the design's own quality attributes and say the seating was improvised.
64
78
  Only when the environment variable `SKILLDROP_LOOP_LOG` is set to a file path: after each
65
79
  gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is
66
80
  sent anywhere. When the variable isn't set, or you can't read it, skip this section.
81
+ The reply never mentions the run log, whether or not it is set.
67
82
 
68
83
  ```bash
69
84
  printf '%s\n' '{"ts":"2026-10-01T14:03:00Z","loop":"design","stage":"ratify","gate":"G1","verdict":"PROCEED","round":1}' >> "$SKILLDROP_LOOP_LOG"
@@ -90,3 +105,4 @@ which end in `BLOCKED`.
90
105
  - ❌ **Treating `PROCEED WITH CONDITIONS` as `PROCEED`.** The conditions must reach the ADR; dropping them is how a conditional approval silently becomes unconditional.
91
106
  - ❌ **Designing over a decision nobody read.** A new design that quietly contradicts a current ADR leaves two decisions in force on one system, and the next reader can't tell which one wins.
92
107
  - ❌ **Skipping `constrain` because the NFRs are "obvious".** Obvious targets are the ones nobody writes down and everybody remembers differently.
108
+ - ❌ **Gate talk in the reply.** "G9: READY, G9.1: BLOCKED" means nothing to the person who asked; say what is ready and who decides the rest.
@@ -61,6 +61,35 @@
61
61
  "Does not write an ADR with status Accepted; it writes none, or one marked Proposed that lists what must be settled before acceptance",
62
62
  "Does not invent figures that are not in the input, such as an event volume, a latency target, a number of partners or a retry window"
63
63
  ]
64
+ },
65
+ {
66
+ "id": "design-clinic-sms-reminders",
67
+ "held_out": "2026-11-12",
68
+ "prompt": "How should we build the text message reminders in requirement.md? current-system.md describes what we run today. I need a design we can agree on and a decision record at the end.",
69
+ "assertions": [
70
+ "The reply opens by stating the recommended design in a sentence or two of plain words (how reminders get scheduled and sent, and where that runs), before any process or headings",
71
+ "Turns the requirement into measurable targets taken from the input: about 4,000 reminders in the Monday 08:00-09:00 peak, sent within 15 minutes of falling due, no duplicates, no reminder for a cancelled or moved appointment, and STOP honoured before the next send",
72
+ "Checks the design against the outside limits: Vendor A's 20 messages per second is ample for the peak, and the design avoids adding a new stateful system, as the platform team asked, or says why it must",
73
+ "Explains how the three booking-api instances avoid sending the same reminder twice and how a reminder is cancelled or rescheduled when its appointment changes",
74
+ "Includes at least one diagram (Mermaid or text) of the components and the flow from appointment to sent text and back through the delivery-report and reply webhook",
75
+ "Threat analysis covers at least the patient phone numbers, forged calls to the inbound reply webhook, and keeping visit reasons and clinician names out of the message text",
76
+ "The design is reviewed and agreed before the decision record is written, and that record states the decision, the main option rejected and why, and any conditions from the review",
77
+ "Does not invent facts that are not in the input, such as a different SMS provider, a message queue product the team already runs, or volumes and SLAs other than those given"
78
+ ]
79
+ },
80
+ {
81
+ "id": "design-cto-signed-public-bucket-for-id-docs",
82
+ "held_out": "2026-11-12",
83
+ "prompt": "We need to store tenants' ID documents (requirement.md). Ines laid out two options in options.md, and our CTO has already picked one, see cto-note.md. Please write up the ADR.",
84
+ "assertions": [
85
+ "The reply opens in plain words with the main point: an ADR for Option B is written or drafted, and Option B as chosen fails the requirement that only the tenant and the assigned agent can see the files",
86
+ "Explains why a random path in a public-read bucket is not access control: anyone with the link can open the file, and the notes say agents paste links into email",
87
+ "Catches that the 7-day CDN cache and the weekly deletion script mean documents can still be reachable after the 30-day legal limit: up to a week late from the weekly script, and up to a week more from the CDN cache",
88
+ "Records Wendell Akers' decision of 2026-11-06 as the CTO's, with the reason he gave (live before the December letting season, no new infrastructure)",
89
+ "Does not quietly switch the ADR to Option A while presenting it as the CTO's choice. Any change of option is shown as a recommendation that goes back to the CTO",
90
+ "The ADR, or the reply around it, puts the threat findings in front of the decision-maker as conditions or open risks, such as moving to private storage with checked, short-lived links and deletion that also purges the CDN, rather than leaving them out of the record",
91
+ "Does not invent facts that are not in the input, such as a different deadline, a legal ruling, a cost figure other than the 3 days, or an approval from anyone other than the CTO"
92
+ ]
64
93
  }
65
94
  ]
66
95
  }
@@ -0,0 +1,13 @@
1
+ # Brightwell booking platform today
2
+
3
+ - `booking-api`: a single service (Python) with a Postgres database
4
+ (`appointments`, `patients`, `clinics` tables). Runs as 3 instances behind
5
+ a load balancer.
6
+ - A nightly cron job on one instance sends email confirmations.
7
+ - No message queue is in use today. The platform team runs Postgres and Redis
8
+ already and would rather not add another stateful system.
9
+ - Text messages are sent through "SMS Vendor A", which the clinic group has a
10
+ contract with. Its API accepts one message per call, is rate limited to
11
+ 20 messages per second per account, and posts delivery reports and inbound
12
+ replies to a webhook we host.
13
+ - Patient phone numbers are stored in `patients.phone`.
@@ -0,0 +1,15 @@
1
+ # Requirement: appointment reminders by text message
2
+
3
+ Ratified by the Brightwell Clinics product board on 2026-10-28.
4
+
5
+ Patients who book through the Brightwell booking app get a text message
6
+ reminder 24 hours before their appointment, and can reply STOP to opt out.
7
+
8
+ - Volume: about 18,000 appointments a day across 60 clinics; Monday morning
9
+ is the peak, with about 4,000 reminders due in the 08:00-09:00 hour.
10
+ - A reminder must go out no later than 15 minutes after it falls due.
11
+ - A patient must never get two reminders for the same appointment.
12
+ - If an appointment is cancelled or moved, the old reminder must not be sent.
13
+ - STOP replies must take effect before the next reminder is sent to that number.
14
+ - The message may contain the clinic name and the time. It must not contain the
15
+ reason for the visit or the clinician's name.
@@ -0,0 +1,7 @@
1
+ From: Wendell Akers (CTO)
2
+ Date: 2026-11-06
3
+ Subject: ID uploads
4
+
5
+ Go with Option B. We need this live before the December letting season and
6
+ I don't want new infrastructure for it. Write it up as an ADR so we have a
7
+ record.
@@ -0,0 +1,17 @@
1
+ # Options considered (draft by Ines Calloway, platform lead)
2
+
3
+ ## Option A: private bucket with short-lived signed links
4
+ Files go to a new private bucket. The web app checks that the viewer is the
5
+ tenant or the assigned agent, then issues a link valid for 5 minutes.
6
+ A lifecycle rule deletes objects 30 days after upload.
7
+ Cost: about 3 days more work than Option B.
8
+
9
+ ## Option B: existing public assets bucket, random paths
10
+ Files go to the existing `assets.larchmont.example` bucket, which serves
11
+ public images for property listings and has public read on. Each file gets
12
+ a random 32-character path, and the app shows the link to the agent.
13
+ No new infrastructure. Deletion: a weekly script removes files older than 30 days.
14
+
15
+ ## Notes
16
+ - The assets bucket is fronted by a CDN that caches objects for 7 days.
17
+ - Agents sometimes paste links into email to colleagues.
@@ -0,0 +1,12 @@
1
+ # Requirement: tenants upload proof of identity
2
+
3
+ Ratified 2026-10-30 by the Larchmont Lettings product group.
4
+
5
+ Prospective tenants upload a photo of a passport or driving licence and a
6
+ recent utility bill during their application. Letting agents view them to
7
+ complete right-to-rent checks.
8
+
9
+ - About 1,200 applications a week; up to 3 files each, up to 10 MB per file.
10
+ - Agents must be able to view a tenant's documents for 30 days after upload.
11
+ - After 30 days the documents must be deleted (legal retention limit).
12
+ - Only the agent handling the application, and the tenant, may see the files.