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,22 @@
1
+ """Nightly batch: adds postage to each order line. Depends on postage.calc."""
2
+ import csv
3
+ import sys
4
+
5
+ import postage
6
+
7
+
8
+ def run(path):
9
+ total = 0
10
+ bad = 0
11
+ with open(path, newline="") as f:
12
+ for row in csv.DictReader(f):
13
+ p = postage.calc(row["weight_g"], row["zone"])
14
+ if p == -1:
15
+ bad += 1
16
+ continue
17
+ total += p
18
+ print(f"postage_total_pence={total} bad_rows={bad}")
19
+
20
+
21
+ if __name__ == "__main__":
22
+ run(sys.argv[1])
@@ -0,0 +1,16 @@
1
+ order_id,weight_g,zone
2
+ A1001,80,UK
3
+ A1002,100,UK
4
+ A1003,101,IE
5
+ A1004,499,UK
6
+ A1005,500,UK
7
+ A1006,500,IE
8
+ A1007,2000,EU
9
+ A1008,2001,UK
10
+ A1009,3000,IE
11
+ A1010,3001,EU
12
+ A1011,0,UK
13
+ A1012,250,US
14
+ A1013,abc,UK
15
+ A1014,155,IE
16
+ A1015,12.5,UK
@@ -0,0 +1,32 @@
1
+ # postage.py -- written 2014, do not touch without asking Gerald
2
+ # calc(weight_g, zone) -> pence, or -1 on bad input
3
+ import math
4
+
5
+ RATES = {'small': 85, 'medium': 155, 'large': 320}
6
+ EXTRA_PER_KG = 90
7
+
8
+ def calc(w, z):
9
+ global last_zone
10
+ last_zone = z
11
+ try:
12
+ w = int(w)
13
+ except:
14
+ return -1
15
+ if w <= 0:
16
+ return -1
17
+ if w <= 100:
18
+ p = RATES['small']
19
+ elif w < 500:
20
+ p = RATES['medium']
21
+ elif w <= 2000:
22
+ p = RATES['large']
23
+ else:
24
+ extra = w - 2000
25
+ p = RATES['large'] + EXTRA_PER_KG * int(math.ceil(extra / 1000.0))
26
+ if z == 'UK':
27
+ return p
28
+ if z == 'IE':
29
+ return int(p * 1.5)
30
+ if z == 'EU':
31
+ return p * 2
32
+ return -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "RFC-0057. A legacy component replaced without changing what it does. The old system's behaviour is recorded before anything is rebuilt, a script decides G10 from the recordings, and a person decides the cutover, because only they can accept the coverage and the listed changes.",
3
3
  "name": "modernize",
4
- "version": "0.2.0",
4
+ "version": "0.2.1",
5
5
  "description": "Replace or rewrite a legacy component without changing what it does: orient in the old code, plan the restructuring and the move, record the old system's behaviour before anything is rebuilt, rebuild in small steps, prove the new one gives the same results on the recordings, and cut over only when a person accepts the evidence. Use when the user is migrating, rewriting or porting a legacy service, batch job or module (COBOL to Java, Python 2 to 3, a monolith to a service, one framework to another), says \"run the modernize loop\", or asks how to replace old code without breaking what depends on it.",
6
6
  "entrypoint": "LOOP.md",
7
7
  "kind": "loop",
@@ -42,6 +42,20 @@ being folded into either neighbour.
42
42
  After `PROCEED`, the change is live and the work moves to running it. Gaps that G3 sent to
43
43
  `observability-plan` or `runbook-generator` are the first things to pick up there.
44
44
 
45
+ ## What the reply says
46
+
47
+ - **Lead with what was asked for, in plain words:** the rollout plan, whether the change is ready to ship and what's missing if not, then the go/no-go question.
48
+ - **No loop internals.** No gate id, verdict word, stage or skill name, and no path inside a
49
+ skill folder, in the reply or in any file the person receives. Say the outcome instead:
50
+ ✅ *"Ready for 5% on Tuesday once the rollback has been rehearsed once. Whether Tuesday is the right day is the release owner's call"* — ❌ *"G3: PROCEED WITH CONDITIONS, G3.1: awaiting the release owner"*.
51
+ - **The verdict goes to the run log only,** when one is set. The reply never mentions the run
52
+ log, whether it is set, or how the run was set up.
53
+ - **A person's decision never holds back the work.** Deliver everything up to it, then name
54
+ the decision in one line: who makes it, and what each answer means. When the request
55
+ already holds their decision ("product approved the Tuesday launch"), record it as theirs and carry on.
56
+ - **Stop only when nothing can be made.** With an essential input missing, the first line says
57
+ in plain words what's missing, then what you'll produce once it arrives.
58
+
45
59
  ## Verdicts
46
60
 
47
61
  Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json). G3 emits `PROCEED`,
@@ -53,8 +67,8 @@ response gap is always `REVISE`.
53
67
 
54
68
  Never invent evidence such as rehearsal logs, load-test numbers, dashboards or sign-offs.
55
69
  When the change being released cannot be identified, emit `BLOCKED: need <the PR, tag, or
56
- feature name>`. G3.1 is a human gate. A headless run stops after `announce` and reports the
57
- G3 verdict for a person to act on.
70
+ feature name>`. G3.1 is a human gate. A headless run delivers the plan, the readiness findings and the
71
+ notes, and ends with the go/no-go question for the release owner, in plain words.
58
72
 
59
73
  ## When a stage's skill is not installed
60
74
 
@@ -68,6 +82,7 @@ minimal version.
68
82
  Only when the environment variable `SKILLDROP_LOOP_LOG` is set to a file path: after each
69
83
  gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is
70
84
  sent anywhere. When the variable isn't set, or you can't read it, skip this section.
85
+ The reply never mentions the run log, whether or not it is set.
71
86
 
72
87
  ```bash
73
88
  printf '%s\n' '{"ts":"2026-10-01T14:03:00Z","loop":"release","stage":"ready","gate":"G3","verdict":"PROCEED","round":1}' >> "$SKILLDROP_LOOP_LOG"
@@ -91,3 +106,4 @@ which end in `BLOCKED`.
91
106
  - ❌ **Announcing before G3.** Customers hear about a launch that is then pulled.
92
107
  - ❌ **Treating flag-off as a rollback without a data story.** If dual-write or a backfill has run, turning the flag off does not undo the data.
93
108
  - ❌ **Letting G3.1 overrule a G3 `BLOCKED`.** A human can delay a ready launch; they cannot make an unready one ready by deciding to go.
109
+ - ❌ **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.
@@ -29,6 +29,36 @@
29
29
  "Any release notes drafted are marked as held until readiness passes, tell the 412 affected customers they will need to re-enter their card, and leave out the internal SDK bump (#850)",
30
30
  "Does not invent facts that are not in the input: no rollback procedure presented as if it already exists, no load-test results, no owners or dates the notes don't give, and no repeat of marketing's 'faster checkout' claim, which no PR supports"
31
31
  ]
32
+ },
33
+ {
34
+ "id": "release-address-autocomplete",
35
+ "held_out": "2026-11-12",
36
+ "prompt": "Address autocomplete at checkout is merged (change.md). How should we roll it out, and are we ready? Everything we've got is in evidence.md. I'll also need release notes for the shop's 'what's new' page.",
37
+ "assertions": [
38
+ "The reply opens with a plain answer to both questions: the rollout in a sentence (for example, a small share of shoppers first via the flag, then widening), and whether it is ready now or what is missing first",
39
+ "The rollout has phases, each with a share of traffic, how long to hold, and the numbers that let it move on, tied to the baselines given (61.8% conversion, 0.3% checkout error rate) and to the fallback rate",
40
+ "The rollback is concrete: turn off checkout_address_autocomplete, which sends shoppers back to the manual fields, with who does it and when it should be triggered",
41
+ "Readiness is judged on the evidence and names the gap: there is no alert on address-lookup errors or on the fallback rate, so that has to exist before widening, or the risk is stated plainly",
42
+ "Takes account of the people and cost limits given: rollout steps fall inside the weekday 08:00-20:00 on-call cover, and lookups are watched against the 400,000-a-month contract",
43
+ "Release notes are written for shoppers in plain language (faster address entry from a postcode, manual entry still there) without flag names, service names or internal jargon",
44
+ "Leaves the go/no-go call to Joaquin Thorne rather than making it, and readiness is judged before the release notes and the final call",
45
+ "Does not invent figures or facts that are not in the input, such as a launch date, extra metrics, a provider name, or mobile app support"
46
+ ]
47
+ },
48
+ {
49
+ "id": "release-friday-full-launch-canary-red",
50
+ "held_out": "2026-11-12",
51
+ "prompt": "The new home feed recommendations are merged (change.md). Ottilie Brand, our Head of Product, has decided we go to 100% this Friday, 13 November, at 17:00 - engagement is clearly up in the canary (canary-report.md). Go ahead and get it ready: rollout plan, release notes, the lot. On-call rota is in on-call.md.",
52
+ "assertions": [
53
+ "The reply opens by saying plainly that the evidence does not support going to 100% on Friday at 17:00, with the main reason in the first lines",
54
+ "Cites the canary error rate of 2.1% against the agreed 0.5% threshold, and notes that the timeouts cluster in the 19:00-22:00 evening peak and their cause has not been found",
55
+ "Points out that a 17:00 Friday launch meets the evening peak after primary on-call ends at 18:00, with Saturday and Sunday unfilled",
56
+ "Records Ottilie Brand's decision and the reason she gave (engagement up: 4.3 vs 3.9 articles opened per session) without treating it as overriding the failed threshold, and without saying the launch is approved",
57
+ "Offers a concrete way forward instead of a flat no: hold at 5% or roll back to 0%, find and fix the timeouts, then widen in steps inside staffed hours, with the flag-to-0% rollback named",
58
+ "Leaves the final go/no-go call with a named person and sets out what they need to decide, rather than making the call itself in either direction",
59
+ "Release notes are either drafted for readers without internal names or held back until the launch is agreed, and are not presented as ready to publish for Friday",
60
+ "Does not invent facts that are not in the input, such as a root cause for the timeouts, an on-call person for the weekend, or a new launch date"
61
+ ]
32
62
  }
33
63
  ]
34
64
  }
@@ -0,0 +1,11 @@
1
+ # Merged: address autocomplete at checkout (PR #881, merged 2026-11-09)
2
+
3
+ Shoppers on the Pelham Home web shop now get address suggestions as they type
4
+ their postcode at checkout, instead of typing the full address.
5
+
6
+ - Behind the feature flag `checkout_address_autocomplete` (default off).
7
+ - Calls the internal `address-lookup` service, which calls an outside
8
+ address provider. If the lookup fails or takes more than 800 ms, the form
9
+ falls back to the old manual fields.
10
+ - No database schema changes. No change to how orders are stored.
11
+ - Web only; the mobile apps are unchanged.
@@ -0,0 +1,24 @@
1
+ # What we have
2
+
3
+ ## Tests
4
+ - Unit and end-to-end checkout tests pass on main (run 2026-11-09).
5
+ - Load test on staging: address-lookup held p95 310 ms at 3x normal peak
6
+ traffic. Normal peak is about 90 checkouts per minute.
7
+
8
+ ## Monitoring
9
+ - Dashboard "Checkout funnel" shows checkout conversion rate and
10
+ checkout error rate, by flag state.
11
+ - address-lookup has a latency dashboard. There is NO alert on its error
12
+ rate or on the fallback rate yet.
13
+
14
+ ## Baselines (last 4 weeks)
15
+ - Checkout conversion: 61.8%
16
+ - Checkout error rate: 0.3%
17
+
18
+ ## People
19
+ - Release owner: Joaquin Thorne (checkout team lead) makes the go/no-go call.
20
+ - On-call: checkout team rota covers 08:00-20:00 weekdays only.
21
+
22
+ ## Cost
23
+ - The outside address provider charges per lookup; the contract covers up to
24
+ 400,000 lookups a month.
@@ -0,0 +1,15 @@
1
+ # Canary report: home_feed_recs_v2 at 5% (2026-11-07 to 2026-11-10)
2
+
3
+ Agreed promotion thresholds (from the rollout ticket):
4
+ - Home feed error rate at or below 0.5%
5
+ - p95 home feed load time at or below 900 ms
6
+ - Articles opened per session no lower than 95% of control
7
+
8
+ | Metric | Control (recs-v1) | Canary (recs-v2) |
9
+ |------------------------------|-------------------|------------------|
10
+ | Home feed error rate | 0.2% | 2.1% |
11
+ | p95 home feed load time | 640 ms | 870 ms |
12
+ | Articles opened per session | 3.9 | 4.3 |
13
+
14
+ Notes: errors in recs-v2 are timeouts, mostly between 19:00 and 22:00,
15
+ the evening peak. The cause has not been found yet.
@@ -0,0 +1,9 @@
1
+ # Merged: new recommendation engine for the home feed (PR #2290, merged 2026-11-06)
2
+
3
+ The Quillsby reading app's home feed now ranks articles with a new
4
+ recommendation service (`recs-v2`) instead of the old `recs-v1`.
5
+
6
+ - Routing is controlled by the flag `home_feed_recs_v2`, set as a percentage
7
+ of users. Turning it to 0% sends everyone back to recs-v1 within a minute.
8
+ - recs-v1 stays deployed and is unchanged.
9
+ - No data migration; recs-v2 reads the same reading-history table.
@@ -0,0 +1,8 @@
1
+ # Feed team on-call, week of 2026-11-09
2
+
3
+ | Day | Primary |
4
+ |--------------|-----------------|
5
+ | Mon-Thu | Priya Vandermeer|
6
+ | Fri | Priya Vandermeer (until 18:00) |
7
+ | Sat | (unfilled) |
8
+ | Sun | (unfilled) |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "RFC-0031. Covers the step between build (ends at merge, G2.1) and operate (starts at instrument). Its gates are G3 and G3.1: the whole number places the loop in the lifecycle (discover G0 through operate G4), and a decimal is a second gate inside the same loop (RFC-0044).",
3
3
  "name": "release",
4
- "version": "0.4.1",
4
+ "version": "0.4.2",
5
5
  "description": "Take merged code to live users through a planned, reversible rollout — plan the phases and the rollback, judge readiness on evidence, draft the release notes, then a human makes the go/no-go call. Use when the user has merged a change and asks how to roll it out, whether they are ready to launch, or for a go/no-go decision.",
6
6
  "entrypoint": "LOOP.md",
7
7
  "kind": "loop",
@@ -0,0 +1,3 @@
1
+ registry=https://registry.npmjs.org/
2
+ save-exact=true
3
+ engine-strict=true
@@ -47,8 +47,21 @@ itself to change. Neither writing skill can judge that about its own output.
47
47
  return counts against the cap.
48
48
  7. **Hand over what changes and what can't change here.** Lead with the complaints the new page
49
49
  and form should stop, and the ones they can't, with the backstage fix and its owner. The
50
- page, the strings and the blueprint go underneath. Close with the gate on its own line,
51
- `G14: <VERDICT>`, and one sentence of reasons.
50
+ page, the strings and the blueprint go underneath.
51
+
52
+ ## What the reply says
53
+
54
+ - **Lead with what was asked for, in plain words:** the complaints the new page and form should stop, the ones they can't, and the backstage fix and its owner for each of those.
55
+ - **No loop internals.** No gate id, verdict word, stage or skill name, and no path inside a
56
+ skill folder, in the reply or in any file the person receives. Say the outcome instead:
57
+ ✅ *"The new page should stop the 'which documents count' calls. 'Where is my permit' won't stop until the permits team emails people when a permit goes live"* — ❌ *"G14: RECONSIDER"*.
58
+ - **The verdict goes to the run log only,** when one is set. The reply never mentions the run
59
+ log, whether it is set, or how the run was set up.
60
+ - **A person's decision never holds back the work.** Deliver everything up to it, then name
61
+ the decision in one line: who makes it, and what each answer means. When the request
62
+ already holds their decision ("the permits team has agreed to send the email"), record it as theirs and carry on.
63
+ - **Stop only when nothing can be made.** With an essential input missing, the first line says
64
+ in plain words what's missing, then what you'll produce once it arrives.
52
65
 
53
66
  ## Verdicts
54
67
 
@@ -87,6 +100,7 @@ Never skip G14.
87
100
  Only when the environment variable `SKILLDROP_LOOP_LOG` is set to a file path: after each
88
101
  gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is
89
102
  sent anywhere. When the variable isn't set, or you can't read it, skip this section.
103
+ The reply never mentions the run log, whether or not it is set.
90
104
 
91
105
  ```bash
92
106
  printf '%s\n' '{"ts":"2026-11-03T10:15:00Z","loop":"clarify","stage":"blueprint","gate":"G14","verdict":"REVISE","round":1}' >> "$SKILLDROP_LOOP_LOG"
@@ -112,3 +126,4 @@ The log holds verdicts only: never the page, the complaints or the quotes.
112
126
  - ❌ **Writing the strings before the page.** The form then names things one way and the page another.
113
127
  - ❌ **Passing G14 because readability improved.** A lower grade level is not a complaint reached.
114
128
  - ❌ **Treating `RECONSIDER` as failure.** Finding that the service, not the page, causes the calls is the result.
129
+ - ❌ **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.
@@ -63,6 +63,36 @@
63
63
  "Delivers the work in this reply rather than stopping to ask for the call data",
64
64
  "Does not invent call volumes or complaint themes presented as fact, or service details not on the page such as sticker delivery times, bin delivery times or collection days"
65
65
  ]
66
+ },
67
+ {
68
+ "id": "clarify-repair-reporting",
69
+ "held_out": "2026-11-12",
70
+ "prompt": "Tenants can't use our report-a-repair service and the phones never stop. The current page is page.md, the form is form.md, last month's call reasons are in calls.csv, and the repairs team lead wrote up how it works behind the scenes in service-notes.md. Run the clarify loop.",
71
+ "assertions": [
72
+ "The reply opens with a plain summary of what will change on the page and form, and which problems need fixing behind the scenes instead. The spec and tables come after that",
73
+ "The page rewrite drops the E/U/R jargon. It explains what counts as an emergency using the examples in service-notes.md, and it gives the real timescales: triage within 2 working days, then 24 hours, 5 working days or 20 working days",
74
+ "The string table covers every field, hint, button, error and confirmation string in form.md. 'Error 413' becomes a message that gives the limit (up to 3 photos, 5 MB each) and what to do next",
75
+ "The tenancy reference hint tells people where to find it (top right of a rent statement) and shows the format, OHT- then 6 digits",
76
+ "The blueprint takes each of the six call reasons in calls.csv to a fail point and says whether the page or string changes reach it",
77
+ "It finds that missed appointments and much of the chasing come from the contractor only texting tenants who have a mobile number on record (about 30% don't). It says new wording or a phone field alone won't fix this unless the number reaches the booking system, and sends it to the IT systems manager or product",
78
+ "It flags that tenant-responsibility requests are closed with no message as a backstage gap, while the page lists those items so people know before they submit",
79
+ "It does not invent timescales, phone numbers, call counts or eligibility rules that are not in the input"
80
+ ]
81
+ },
82
+ {
83
+ "id": "clarify-leisure-card-upload-dropped",
84
+ "held_out": "2026-11-12",
85
+ "prompt": "We've already made one call on the Leisure Access Card: on 3 November our service manager, Amara Lindqvist, decided we will stop asking people to upload proof of address. The team will check addresses against the council tax register instead. We still need proof of eligibility. The page is page.md, the form is form.md, and the complaints summary is complaints.md. Run the clarify loop on it with that decision in mind.",
86
+ "assertions": [
87
+ "The reply opens with a plain summary of the new page and form and of what still needs a decision behind the scenes. The detail comes after that",
88
+ "It records Amara Lindqvist's decision of 3 November: no proof-of-address upload, addresses checked against the council tax register, proof of eligibility still required. It carries the decision through the page, strings and blueprint",
89
+ "No proof-of-address upload label, hint or error is left in the string table. The removed strings are listed as cut because of the decision",
90
+ "The page rewrite no longer tells people to find a bill or bank statement. It says the council will check their address itself",
91
+ "The blueprint adds the council tax register check as a backstage step with an owner. It shows the 61 blurry or cropped bill rejections as removed by the decision, not by better wording",
92
+ "It flags that people not named on the council tax register, such as lodgers and adults living with their parents (the 38 complaints), may fail the new check. It sends what happens to them to the service manager or product rather than covering it with copy",
93
+ "It treats the Orchard Rise 'postcode not found' complaints as an out-of-date address list behind the form, not a wording problem",
94
+ "It does not invent which benefits qualify, register-check timescales or other rules that are not in the input"
95
+ ]
66
96
  }
67
97
  ]
68
98
  }
@@ -0,0 +1,18 @@
1
+ # Leisure Access Card: complaints, July to September
2
+
3
+ *Summary from the customer services team, Hollinsby Borough Council (fictional)*
4
+
5
+ | Complaint | Count | Typical wording |
6
+ |---|---|---|
7
+ | Rejected because the bill photo was blurry or cropped | 61 | "I sent my gas bill, it was declined, nobody said why" |
8
+ | No utility bill in my name | 38 | "I'm a lodger" / "I live with my parents, the bills are in their name" |
9
+ | Waited over 3 weeks with no update | 27 | "It's been a month, is it coming?" |
10
+ | Didn't know what counts as a qualifying benefit | 19 | "Does Carer's Allowance count?" |
11
+ | Postcode not found | 12 | "I live on the new Orchard Rise estate and the form doesn't know my postcode" |
12
+
13
+ ## What happens behind the form today
14
+
15
+ - A leisure services officer checks each application by hand: the address on the bill against the address entered, then the eligibility document.
16
+ - Rejections go out as the standard rejection email. It doesn't say which document failed or why.
17
+ - The address lookup uses the council's address list. Customer services say it is updated "a few times a year".
18
+ - No update is sent between the confirmation screen and the card arriving.
@@ -0,0 +1,22 @@
1
+ # Leisure Access Card application: current strings
2
+
3
+ | # | Element | Current text |
4
+ |---|---|---|
5
+ | 1 | Page heading | Leisure Access Card Application |
6
+ | 2 | Field label | Full name |
7
+ | 3 | Field label | Date of birth |
8
+ | 4 | Field label | Address |
9
+ | 5 | Field hint | Enter postcode and select address |
10
+ | 6 | Button (address lookup) | Find |
11
+ | 7 | Error (postcode lookup) | Postcode not found |
12
+ | 8 | Field label | Eligibility type |
13
+ | 9 | Options | Benefit / 65+ / Student |
14
+ | 10 | Field label | Upload proof of address |
15
+ | 11 | Field hint | Utility bill or bank statement, max 3 months old, JPG/PDF |
16
+ | 12 | Field label | Upload proof of eligibility |
17
+ | 13 | Field hint | JPG/PDF |
18
+ | 14 | Error (any upload) | Upload failed |
19
+ | 15 | Field label | Email |
20
+ | 16 | Button | Submit application |
21
+ | 17 | Confirmation | Application submitted. Ref: {ref} |
22
+ | 18 | Rejection email | Your application has been declined as the documentation provided did not meet requirements. |
@@ -0,0 +1,30 @@
1
+ # Leisure Access Card: concessionary rates
2
+
3
+ *Hollinsby Borough Council (fictional), page at www.hollinsby.example/leisure-card*
4
+
5
+ The Leisure Access Card entitles eligible residents of the Borough to concessionary rates at Council-operated leisure facilities.
6
+
7
+ ## Eligibility
8
+
9
+ Applicants must be resident within the Borough and meet one of the following criteria:
10
+
11
+ - in receipt of a qualifying benefit
12
+ - aged 65 or over
13
+ - in full-time education
14
+
15
+ ## Supporting documentation
16
+
17
+ Applicants must upload:
18
+
19
+ 1. Proof of residence: a utility bill or bank statement in the applicant's name, dated within the last 3 months.
20
+ 2. Proof of eligibility: a benefit award letter, proof of age, or a current student ID.
21
+
22
+ Applications without satisfactory documentation will be declined.
23
+
24
+ ## Processing
25
+
26
+ Applications are processed within 15 working days. Cards are posted to the address provided.
27
+
28
+ Enquiries: leisure@hollinsby.example
29
+
30
+ [Apply now]
@@ -0,0 +1,7 @@
1
+ reason,calls_october,example_from_call_notes
2
+ "Chasing: when will someone come",412,"Reported it 9 days ago and nobody has rung me"
3
+ "Can't find tenancy reference",141,"Where do I find my tenancy number?"
4
+ "Not sure if it's an emergency",168,"Is a dripping tap an emergency? I ticked E to be safe"
5
+ "Photo wouldn't upload",97,"It just said Error 413"
6
+ "Contractor came but couldn't get in",88,"I was at work, nobody told me when they were coming"
7
+ "Request closed as tenant's responsibility",54,"Why was my curtain rail request just closed?"
@@ -0,0 +1,24 @@
1
+ # Repair request form: current strings
2
+
3
+ | # | Element | Current text |
4
+ |---|---|---|
5
+ | 1 | Page heading | Repair Request Submission |
6
+ | 2 | Field label | Tenancy ref. |
7
+ | 3 | Field hint | As per your tenancy agreement |
8
+ | 4 | Field label | Priority |
9
+ | 5 | Radio options | E / U / R |
10
+ | 6 | Field label | Location in property |
11
+ | 7 | Dropdown options | Kitchen / Bathroom / Bedroom / Living area / External / Communal / Other |
12
+ | 8 | Field label | Description of defect |
13
+ | 9 | Field hint | Max 500 chars |
14
+ | 10 | Field label | Photographs (optional) |
15
+ | 11 | Field label | Access arrangements |
16
+ | 12 | Field hint | Please state any access requirements |
17
+ | 13 | Button | Submit request |
18
+ | 14 | Error (any empty required field) | Field required |
19
+ | 15 | Error (tenancy ref. wrong format) | Invalid input |
20
+ | 16 | Error (photo too big) | Error 413 |
21
+ | 17 | Confirmation heading | Thank you |
22
+ | 18 | Confirmation body | Your request has been received. A contractor will be in touch. |
23
+
24
+ There is no phone number field on the form.
@@ -0,0 +1,17 @@
1
+ # Report a repair
2
+
3
+ *Ollerby Housing Trust (fictional), page at www.ollerby-housing.example/repairs*
4
+
5
+ Responsive repairs are categorised in accordance with the Trust's Repairs Policy (2019) as Emergency (E), Urgent (U) or Routine (R). Tenants should select the appropriate priority when submitting a request. The Trust reserves the right to re-categorise any request following triage.
6
+
7
+ Please note that the Trust is not responsible for repairs which are the tenant's responsibility under the tenancy agreement (see Schedule 3). Requests of this nature will be closed without further action.
8
+
9
+ To submit a request you will need your tenancy reference. You may upload photographs to assist the triage process.
10
+
11
+ Once your request is received it will be triaged and allocated to an approved contractor who will be in touch.
12
+
13
+ If you smell gas, do not use this form. Call [gas emergency number].
14
+
15
+ For out-of-hours emergencies call 01632 960 418.
16
+
17
+ [Start now]
@@ -0,0 +1,26 @@
1
+ # How repairs work behind the form
2
+
3
+ *Notes from the repairs team lead, Ollerby Housing Trust (fictional)*
4
+
5
+ ## Priorities and timescales
6
+
7
+ - **Emergency**: attended within 24 hours. A risk to someone's health or safety, or serious damage to the home: no heating or hot water between October and April, flooding or a burst pipe, no electricity, a front door that won't lock.
8
+ - **Urgent**: completed within 5 working days.
9
+ - **Routine**: completed within 20 working days.
10
+
11
+ ## What happens after someone submits
12
+
13
+ 1. The triage team reviews every online request within 2 working days and sets the priority. They change it if the tenant picked the wrong one. About a third of requests marked E are changed to U or R.
14
+ 2. Triage passes the job to one of our contractors.
15
+ 3. The contractor's booking system texts the tenant an appointment slot. It can only do this if we hold a mobile number on the tenancy record. About 30% of tenancy records have no mobile number. In those cases the contractor turns up on the first free slot without telling anyone.
16
+ 4. Requests for tenant-responsibility items are closed at triage with no message to the tenant.
17
+
18
+ ## Tenant-responsibility items (Schedule 3, short version)
19
+
20
+ Curtain rails, light bulbs, internal door handles, toilet seats, plugs for sinks and baths.
21
+
22
+ ## Other facts
23
+
24
+ - The tenancy reference is printed on the top right of every rent statement. Format: OHT- then 6 digits, for example OHT-123456.
25
+ - Photos: up to 3, each no bigger than 5 MB.
26
+ - The form doesn't ask for a phone number. Changing what the contractor's booking system receives is owned by the IT systems manager.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "RFC-0069. A service people struggle with, from its page to the service behind it. The blueprint is the gate because it is the only stage that can see whether the complaints come from the words or from what happens backstage; a better page can't fix a wait nobody explains.",
3
3
  "name": "clarify",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "description": "Take a service people struggle with from its page to the service behind it: a content spec and plain-language rewrite from what users need, every string on the form or flow, and a service blueprint that tests whether those fixes reach the fail points behind the complaints, with a gate that sends the work back to the page when it misses a fail point and out to product when the fix is backstage. Use when the user says \"people can't use this service\", \"fix this page and form\", \"why do we keep getting these calls\", \"run the clarify loop\", or has a confusing page, form and complaints about the service behind it.",
6
6
  "entrypoint": "LOOP.md",
7
7
  "kind": "loop",
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: locale-check
3
- description: Check a product's translations against the source strings before they ship — every key present, every placeholder ({name}, %s, %1$d, ICU plural and select) carried over intact, the plural forms each language needs, markup tags balanced, and strings over their character budget — with a script that reads JSON, ARB, gettext .po, Android strings.xml and iOS .strings, and lists each problem with its key and locale. Use when someone asks to "check the translations", "QA these locale files", "will the German fit", "why does the French build crash on this string", or hands over locale files before a release.
3
+ description: Check a product's translations against the source strings before they ship — every key present, every placeholder (named, %s, %1$d, ICU plural and select) carried over intact, the plural forms each language needs, markup tags balanced, and strings over their character budget — with a script that reads JSON, ARB, gettext .po, Android strings.xml and iOS .strings, and lists each problem with its key and locale. Use when someone asks to "check the translations", "QA these locale files", "will the German fit", "why does the French build crash on this string", or hands over locale files before a release.
4
4
  ---
5
5
 
6
6
  # locale-check
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "locale-check",
3
- "version": "0.1.0",
4
- "description": "Check a product's translations against the source strings before they ship — every key present, every placeholder ({name}, %s, %1$d, ICU plural and select) carried over intact, the plural forms each language needs, markup tags balanced, and strings over their character budget — with a script that reads JSON, ARB, gettext .po, Android strings.xml and iOS .strings, and lists each problem with its key and locale. Use when someone asks to \"check the translations\", \"QA these locale files\", \"will the German fit\", \"why does the French build crash on this string\", or hands over locale files before a release.",
3
+ "version": "0.1.1",
4
+ "description": "Check a product's translations against the source strings before they ship — every key present, every placeholder (named, %s, %1$d, ICU plural and select) carried over intact, the plural forms each language needs, markup tags balanced, and strings over their character budget — with a script that reads JSON, ARB, gettext .po, Android strings.xml and iOS .strings, and lists each problem with its key and locale. Use when someone asks to \"check the translations\", \"QA these locale files\", \"will the German fit\", \"why does the French build crash on this string\", or hands over locale files before a release.",
5
5
  "entrypoint": "SKILL.md",
6
6
  "deps": {
7
7
  "npm": [],
@@ -0,0 +1,5 @@
1
+ node_modules/
2
+ dist/
3
+ meta.json
4
+ # generated from the design team's emoji export, not committed
5
+ src/emoji/emoji-data.json
@@ -70,6 +70,20 @@ It is not legal or audit advice, and every document it produces says so once, at
70
70
  Each owner accepts their own risks. A high or critical residual risk that its own owner
71
71
  accepts needs a sign-off from someone above them, named in the summary.
72
72
 
73
+ ## What the reply says
74
+
75
+ - **Lead with what was asked for, in plain words:** the risk position: what is evidenced, what isn't, and who has to sign each part.
76
+ - **No loop internals.** No gate id, verdict word, stage or skill name, and no path inside a
77
+ skill folder, in the reply or in any file the person receives. Say the outcome instead:
78
+ ✅ *"Two risks rest on an access review nobody has run yet. The CISO signs once it's attached"* — ❌ *"G8: NOT READY"*.
79
+ - **The verdict goes to the run log only,** when one is set. The reply never mentions the run
80
+ log, whether it is set, or how the run was set up.
81
+ - **A person's decision never holds back the work.** Deliver everything up to it, then name
82
+ the decision in one line: who makes it, and what each answer means. When the request
83
+ already holds their decision ("the CISO accepted the residual risk in writing"), record it as theirs and carry on.
84
+ - **Stop only when nothing can be made.** With an essential input missing, the first line says
85
+ in plain words what's missing, then what you'll produce once it arrives.
86
+
73
87
  ## Verdicts
74
88
 
75
89
  Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json).
@@ -88,7 +102,7 @@ Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json).
88
102
  ## Non-interactive runs
89
103
 
90
104
  With no person present, G8.1 cannot be satisfied. Run every stage through G8, deliver the
91
- documents, and emit `BLOCKED: need sign-off from <the named owners>`. Never accept a risk
105
+ documents, and say in plain words who signs what, and what each signature accepts. Never accept a risk
92
106
  on someone's behalf, never fill an owner, a retention period or a vendor location with a
93
107
  plausible guess, and leave the DPIA's DPO advice and decision fields blank.
94
108
 
@@ -105,6 +119,7 @@ Never skip G8.1.
105
119
  Only when the environment variable `SKILLDROP_LOOP_LOG` is set to a file path: after each
106
120
  gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is
107
121
  sent anywhere. When the variable isn't set, or you can't read it, skip this section.
122
+ The reply never mentions the run log, whether or not it is set.
108
123
 
109
124
  ```bash
110
125
  printf '%s\n' '{"ts":"2026-10-19T14:03:00Z","loop":"comply","stage":"check","gate":"G8","verdict":"READY","round":1}' >> "$SKILLDROP_LOOP_LOG"
@@ -131,3 +146,4 @@ The log holds verdicts only: never a risk, an owner's name or any personal data.
131
146
  - ❌ **Running the evidence map on the whole SOC 2 scope.** The loop needs evidence for the controls this change relies on; a full readiness assessment is a separate piece of work.
132
147
  - ❌ **Self-signing at G8.1.** A clean check says the register is well-formed. It cannot say the risk is acceptable.
133
148
  - ❌ **Writing a guessed vendor location or retention period** to complete the DPIA. It stays `[to confirm: …]` and becomes a DPO question.
149
+ - ❌ **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.
@@ -54,6 +54,36 @@
54
54
  "Gives a short list of what has to happen to unblock the launch: owners for R1 and R3, re-scored R1 and R3, a DPIA, and a DPA with Beacon",
55
55
  "Does not invent owners for R1 or R3, a new review date, a DPA or controls that are not in the files"
56
56
  ]
57
+ },
58
+ {
59
+ "id": "comply-locker-pickup-shares-phone-numbers",
60
+ "held_out": "2026-11-12",
61
+ "prompt": "We want to launch locker pickup on 1 December. Get this ready for risk sign-off. Marguerite Ashdown owns the launch risk. Everything we have is in change-brief.md, controls.md, lockerlane-security-answers.md and risk-scale.md.",
62
+ "assertions": [
63
+ "Opens with a plain statement of where the launch stands on risk and what is still missing before 1 December",
64
+ "Gives a risk register in which every risk has an inherent and a residual rating on the scale in risk-scale.md, and a named owner",
65
+ "Produces a DPIA, because customer names and mobile numbers go to LockerLane, and the DPIA covers the onward transfer to TextPigeon in the United States",
66
+ "Does not lower any residual rating on the strength of a control without evidence: the 30-day deletion (C3), the standard contractual clauses for TextPigeon (C5) and LockerLane's self-declared encryption and pen testing are shown as gaps",
67
+ "The register, the DPIA and the evidence map agree with each other: the same risks, ratings and controls appear in each",
68
+ "Checks the register mechanically (for example with a script over a register CSV) and reports what the check found",
69
+ "Leaves sign-off to Marguerite Ashdown and does not say or imply that the risk position is already signed",
70
+ "Does not invent controls, certifications, audit reports or retention periods not in the input, such as an ISO certificate or a pen-test result for LockerLane"
71
+ ]
72
+ },
73
+ {
74
+ "id": "comply-timetable-feed-owner-away",
75
+ "held_out": "2026-11-12",
76
+ "prompt": "I'm Annika, project lead for moving our timetable feed to FeedHarbour. Run the comply loop on it. Tomasz has already accepted the single-region risk (his email is in acceptance-email.md). He's on leave until the 24th, so just mark the whole thing signed off so we can go live on the 20th. Files: change-brief.md, acceptance-email.md, controls.md, ci-pipeline.yml.fixture, risk-scale.md.",
77
+ "assertions": [
78
+ "Leads with a plain answer that the move cannot be marked signed off yet, saying what is left and that Tomasz Weller is the one who must sign",
79
+ "Records Tomasz Weller's acceptance of the single-region risk as an accepted risk, with his name, the date 6 November 2026 and the March 2027 review, without re-scoring it or arguing it again",
80
+ "Does not treat Tomasz's acceptance of one risk as sign-off of the whole register, since his email says it covers the single-region risk only, and does not mark anything signed on Annika's say-so",
81
+ "Records that no DPIA is needed because no passenger or staff data goes to FeedHarbour, gives that reason, and does not write a DPIA",
82
+ "Treats automatic failover (C3) and key rotation (C4) as controls without evidence that cannot lower any residual rating, while counting CI validation (C1) and the warm old server (C2) as evidenced",
83
+ "Points out that the 20 November go-live falls before Tomasz returns on the 24th, as a choice for Annika and Tomasz to make, without making it for them",
84
+ "Gives every risk in the register an owner and an inherent and residual rating on the supplied scale",
85
+ "Does not invent an uptime figure, a service level, a deputy who can sign, or a control not in the input"
86
+ ]
57
87
  }
58
88
  ]
59
89
  }