skilldrop-cli 0.16.6 → 0.16.8

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 (135) hide show
  1. package/README.md +2 -1
  2. package/catalogue.json +11 -1
  3. package/model-routing.json +16 -0
  4. package/package.json +1 -1
  5. package/packs/ai-engineering/skills/ai-usage-policy/evals/evals.json +30 -0
  6. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/2/data-handling-sheet.md +18 -0
  7. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/2/it-notes.md +31 -0
  8. package/packs/ai-engineering/skills/ai-usage-policy/evals/files/2/md-email.md +29 -0
  9. package/packs/api-builder/skills/tool-use-schema-writer/evals/evals.json +29 -0
  10. package/packs/api-builder/skills/tool-use-schema-writer/evals/files/2/book_appointment.ts +64 -0
  11. package/packs/career/loops/apply/LOOP.md +97 -0
  12. package/packs/career/loops/apply/evals/eval_queries.json +9 -0
  13. package/packs/career/loops/apply/evals/evals.json +27 -0
  14. package/packs/career/loops/apply/loop.json +52 -0
  15. package/packs/career/pack.json +77 -0
  16. package/packs/career/skills/application-form-answers/SKILL.md +146 -0
  17. package/packs/career/skills/application-form-answers/evals/eval_queries.json +34 -0
  18. package/packs/career/skills/application-form-answers/evals/evals.json +103 -0
  19. package/packs/career/skills/application-form-answers/evals/files/1/form.md +17 -0
  20. package/packs/career/skills/application-form-answers/evals/files/1/posting.md +20 -0
  21. package/packs/career/skills/application-form-answers/evals/files/1/resume.md +32 -0
  22. package/packs/career/skills/application-form-answers/evals/files/2/form.md +15 -0
  23. package/packs/career/skills/application-form-answers/evals/files/2/posting.md +21 -0
  24. package/packs/career/skills/application-form-answers/evals/files/2/resume.md +32 -0
  25. package/packs/career/skills/application-form-answers/evals/files/4/form.md +14 -0
  26. package/packs/career/skills/application-form-answers/evals/files/4/posting.md +25 -0
  27. package/packs/career/skills/application-form-answers/evals/files/4/resume.md +29 -0
  28. package/packs/career/skills/application-form-answers/evals/files/5/form.md +15 -0
  29. package/packs/career/skills/application-form-answers/evals/files/5/posting.md +18 -0
  30. package/packs/career/skills/application-form-answers/evals/files/5/resume.md +23 -0
  31. package/packs/career/skills/application-form-answers/evals/files/6/form.md +11 -0
  32. package/packs/career/skills/application-form-answers/evals/files/6/posting.md +28 -0
  33. package/packs/career/skills/application-form-answers/evals/files/6/resume.md +35 -0
  34. package/packs/career/skills/application-form-answers/evals/files/7/form.md +11 -0
  35. package/packs/career/skills/application-form-answers/evals/files/7/posting.md +19 -0
  36. package/packs/career/skills/application-form-answers/evals/files/7/resume.md +26 -0
  37. package/packs/career/skills/application-form-answers/manifest.json +31 -0
  38. package/packs/career/skills/cover-letter/SKILL.md +132 -0
  39. package/packs/career/skills/cover-letter/evals/eval_queries.json +34 -0
  40. package/packs/career/skills/cover-letter/evals/evals.json +100 -0
  41. package/packs/career/skills/cover-letter/evals/files/1/posting.md +28 -0
  42. package/packs/career/skills/cover-letter/evals/files/1/resume.md +35 -0
  43. package/packs/career/skills/cover-letter/evals/files/2/posting.md +20 -0
  44. package/packs/career/skills/cover-letter/evals/files/2/resume.md +32 -0
  45. package/packs/career/skills/cover-letter/evals/files/4/posting.md +19 -0
  46. package/packs/career/skills/cover-letter/evals/files/4/resume.md +26 -0
  47. package/packs/career/skills/cover-letter/evals/files/5/posting.md +21 -0
  48. package/packs/career/skills/cover-letter/evals/files/5/resume.md +32 -0
  49. package/packs/career/skills/cover-letter/evals/files/6/posting.md +25 -0
  50. package/packs/career/skills/cover-letter/evals/files/6/resume.md +29 -0
  51. package/packs/career/skills/cover-letter/evals/files/7/posting.md +18 -0
  52. package/packs/career/skills/cover-letter/evals/files/7/resume.md +23 -0
  53. package/packs/career/skills/cover-letter/manifest.json +37 -0
  54. package/packs/career/skills/cover-letter/scripts/claim_check.py +250 -0
  55. package/packs/career/skills/job-fit-analysis/SKILL.md +152 -0
  56. package/packs/career/skills/job-fit-analysis/evals/eval_queries.json +34 -0
  57. package/packs/career/skills/job-fit-analysis/evals/evals.json +102 -0
  58. package/packs/career/skills/job-fit-analysis/evals/files/1/posting.md +28 -0
  59. package/packs/career/skills/job-fit-analysis/evals/files/1/resume.md +35 -0
  60. package/packs/career/skills/job-fit-analysis/evals/files/2/posting.md +20 -0
  61. package/packs/career/skills/job-fit-analysis/evals/files/2/resume.md +32 -0
  62. package/packs/career/skills/job-fit-analysis/evals/files/4/posting.md +25 -0
  63. package/packs/career/skills/job-fit-analysis/evals/files/4/resume.md +29 -0
  64. package/packs/career/skills/job-fit-analysis/evals/files/5/posting.md +18 -0
  65. package/packs/career/skills/job-fit-analysis/evals/files/5/resume.md +23 -0
  66. package/packs/career/skills/job-fit-analysis/evals/files/6/linkedin-about.txt +5 -0
  67. package/packs/career/skills/job-fit-analysis/evals/files/6/posting.md +25 -0
  68. package/packs/career/skills/job-fit-analysis/evals/files/6/resume.md +35 -0
  69. package/packs/career/skills/job-fit-analysis/evals/files/7/resume.md +32 -0
  70. package/packs/career/skills/job-fit-analysis/manifest.json +31 -0
  71. package/packs/career/skills/resume-tailor/SKILL.md +144 -0
  72. package/packs/career/skills/resume-tailor/evals/eval_queries.json +34 -0
  73. package/packs/career/skills/resume-tailor/evals/evals.json +133 -0
  74. package/packs/career/skills/resume-tailor/evals/files/1/posting.md +26 -0
  75. package/packs/career/skills/resume-tailor/evals/files/1/resume.md +32 -0
  76. package/packs/career/skills/resume-tailor/evals/files/2/posting.md +19 -0
  77. package/packs/career/skills/resume-tailor/evals/files/2/resume.md +26 -0
  78. package/packs/career/skills/resume-tailor/evals/files/3/posting.md +21 -0
  79. package/packs/career/skills/resume-tailor/evals/files/3/resume.md +32 -0
  80. package/packs/career/skills/resume-tailor/evals/files/4/posting.md +28 -0
  81. package/packs/career/skills/resume-tailor/evals/files/4/resume.md +35 -0
  82. package/packs/career/skills/resume-tailor/evals/files/5/posting.md +20 -0
  83. package/packs/career/skills/resume-tailor/evals/files/5/resume.md +32 -0
  84. package/packs/career/skills/resume-tailor/evals/files/6/posting.md +25 -0
  85. package/packs/career/skills/resume-tailor/evals/files/6/resume.md +29 -0
  86. package/packs/career/skills/resume-tailor/evals/files/7/posting.md +18 -0
  87. package/packs/career/skills/resume-tailor/evals/files/7/resume.md +23 -0
  88. package/packs/career/skills/resume-tailor/evals/files/8/posting.md +25 -0
  89. package/packs/career/skills/resume-tailor/evals/files/8/resume.typ +31 -0
  90. package/packs/career/skills/resume-tailor/evals/files/9/linkedin-about.txt +5 -0
  91. package/packs/career/skills/resume-tailor/evals/files/9/posting.md +25 -0
  92. package/packs/career/skills/resume-tailor/evals/files/9/resume.md +35 -0
  93. package/packs/career/skills/resume-tailor/manifest.json +37 -0
  94. package/packs/career/skills/resume-tailor/scripts/claim_check.py +250 -0
  95. package/packs/data-analytics/skills/metric-definition/evals/evals.json +30 -0
  96. package/packs/data-analytics/skills/metric-definition/evals/files/2/tables.md +42 -0
  97. package/packs/data-analytics/skills/metric-definition/evals/files/2/thread.md +40 -0
  98. package/packs/dev-team/skills/contribution-wizard/evals/evals.json +29 -0
  99. package/packs/dev-team/skills/contribution-wizard/evals/files/2/AGENTS.md +9 -0
  100. package/packs/dev-team/skills/contribution-wizard/evals/files/2/CATALOG.md +18 -0
  101. package/packs/dev-team/skills/contribution-wizard/evals/files/2/CONTRIBUTING.md +45 -0
  102. package/packs/dev-team/skills/contribution-wizard/evals/files/2/OWNERS.md +7 -0
  103. package/packs/dev-team/skills/contribution-wizard/evals/files/2/skills/detention-claim-letter/INSTRUCTIONS.md +20 -0
  104. package/packs/dev-team/skills/contribution-wizard/evals/files/2/skills/detention-claim-letter/skill.yaml +11 -0
  105. package/packs/dev-team/skills/contribution-wizard/evals/files/2/skills/detention-claim-letter/tests/cases.yaml +25 -0
  106. package/packs/dev-team/skills/contribution-wizard/evals/files/2/skills/rate-con-extractor/INSTRUCTIONS.md +20 -0
  107. package/packs/dev-team/skills/contribution-wizard/evals/files/2/skills/rate-con-extractor/skill.yaml +8 -0
  108. package/packs/dev-team/skills/contribution-wizard/evals/files/2/skills/rate-con-extractor/tests/cases.yaml +32 -0
  109. package/packs/dev-team/skills/devils-advocate/evals/evals.json +29 -0
  110. package/packs/dev-team/skills/devils-advocate/evals/files/2/signups.py +116 -0
  111. package/packs/dev-team/skills/devils-advocate/evals/files/2/test_signups.py +69 -0
  112. package/packs/dev-team/skills/release-notes/evals/evals.json +29 -0
  113. package/packs/dev-team/skills/release-notes/evals/files/2/commits.txt +35 -0
  114. package/packs/research/skills/source-synthesis/evals/evals.json +30 -0
  115. package/packs/research/skills/source-synthesis/evals/files/2/badge-data.md +27 -0
  116. package/packs/research/skills/source-synthesis/evals/files/2/director-email.md +16 -0
  117. package/packs/research/skills/source-synthesis/evals/files/2/exit-interviews.md +17 -0
  118. package/packs/research/skills/source-synthesis/evals/files/2/practice-weekly-article.md +21 -0
  119. package/packs/research/skills/source-synthesis/evals/files/2/staff-survey-summary.md +41 -0
  120. package/packs/solution-architect/skills/db-schema-design/evals/evals.json +29 -0
  121. package/packs/solution-architect/skills/db-schema-design/evals/files/2/current_tables.sql +29 -0
  122. package/packs/solution-architect/skills/db-schema-design/evals/files/2/notes.md +53 -0
  123. package/packs/solution-architect/skills/design-doc/evals/evals.json +29 -0
  124. package/packs/solution-architect/skills/design-doc/evals/files/2/brief.md +18 -0
  125. package/packs/solution-architect/skills/design-doc/evals/files/2/eng-notes.md +30 -0
  126. package/packs/solution-architect/skills/tech-comparison-matrix/evals/evals.json +29 -0
  127. package/packs/solution-architect/skills/tech-comparison-matrix/evals/files/2/requirements.md +20 -0
  128. package/packs/solution-architect/skills/tech-comparison-matrix/evals/files/2/vendor-notes.md +29 -0
  129. package/packs/sre-oncall/skills/postmortem-generator/evals/evals.json +30 -0
  130. package/packs/sre-oncall/skills/postmortem-generator/evals/files/2/pager-export.txt +22 -0
  131. package/packs/sre-oncall/skills/postmortem-generator/evals/files/2/slack-thread.txt +28 -0
  132. package/packs/stakeholder-comms/skills/guide-builder/evals/evals.json +29 -0
  133. package/packs/stakeholder-comms/skills/guide-builder/evals/files/2/api-notes.md +44 -0
  134. package/packs/stakeholder-comms/skills/guide-builder/evals/files/2/sample-booking.json +19 -0
  135. package/profiles.json +2 -2
package/README.md CHANGED
@@ -33,6 +33,7 @@ Install one pack. Every role pack also brings `core` (intake, critique, review c
33
33
  - **Governance, risk and compliance:** `grc` — DPIAs, SOC 2 evidence maps, risk registers, security questionnaire answers. [Open pack](https://sananthanarayan.github.io/skilldrop/packs/grc/)
34
34
  - **Infrastructure as code:** `infra-as-code` — Terraform modules with secure defaults, and plan reviews before apply. [Open pack](https://sananthanarayan.github.io/skilldrop/packs/infra-as-code/)
35
35
  - **Writing agent skills:** `skill-engineering` — author a portable skill with evals, and review one before it ships. [Open pack](https://sananthanarayan.github.io/skilldrop/packs/skill-engineering/)
36
+ - **Applying for a job:** `career` — an honest fit check against the posting, a tailored resume and cover letter that claim nothing you didn't, and the application form's answers. [Open pack](https://sananthanarayan.github.io/skilldrop/packs/career/)
36
37
  - **Everyone:** `core` on its own. [Open pack](https://sananthanarayan.github.io/skilldrop/packs/core/)
37
38
 
38
39
  ## Start in one command
@@ -54,7 +55,7 @@ In Claude Code you can use the plugin marketplace instead: run `/plugin marketpl
54
55
  ## How it works
55
56
 
56
57
  - **A skill produces one file you own.** Each ships a quality bar, named anti-patterns and acceptance evals, so the output is an artifact, not a conversation. See [every skill, by category](guides/reference/skill-catalogue.md).
57
- - **Loops order skills, and a gate decides when work moves on.** Five loops cover the lifecycle (`discover`, `design`, `build`, `release`, `operate`), plus the `ship-a-draft` wrapper for any document. Each gate is a script, a review panel or a person, chosen by how expensive the mistake is to undo. See [the loops, stage by stage](guides/reference/loops.md) and [why loops](guides/explanation/loops.md).
58
+ - **Loops order skills, and a gate decides when work moves on.** Five loops cover the lifecycle (`discover`, `design`, `build`, `release`, `operate`), plus the `ship-a-draft` wrapper for any document and `apply` for a job application. Each gate is a script, a review panel or a person, chosen by how expensive the mistake is to undo. See [the loops, stage by stage](guides/reference/loops.md) and [why loops](guides/explanation/loops.md).
58
59
  - **Measured, not asserted.** `run_bench.py` runs each acceptance eval with the skill and without it, in a sandbox, and reports the lift, a blind preference from two judges, and the cost per run. The results are published whether or not they flatter the skills. See [how skills are checked](https://sananthanarayan.github.io/skilldrop/evals/) and [RFC-0040](docs/rfcs/0040-skill-benchmark.md).
59
60
  - **Copy, never transform.** A skill is a plain `SKILL.md` folder in the [Agent Skills](https://agentskills.io) format, at `packs/<pack>/skills/<name>/`. What runs in your agent is byte-identical to what is reviewed here. There is no runtime, and the tooling has zero dependencies.
60
61
  - **Updates keep your edits.** `npx skilldrop-cli update` replaces files you haven't touched. For any file you changed, it leaves the new version beside it as `<file>.upstream`. See [upgrade installed skills](guides/how-to/upgrade-skills.md).
package/catalogue.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "RFC-0034. The catalogue index: pack display order and the outcome browse axis (RFC-0026). Pack metadata lives in packs/<pack>/pack.json; membership is the folders — a skill is in a pack because it sits at packs/<pack>/skills/<name>/.",
3
3
  "version": "1.0.0",
4
- "packs": ["core", "solution-architect", "product-manager", "dev-team", "sre-oncall", "stakeholder-comms", "design", "ai-engineering", "api-builder", "converters", "experience-design", "research", "trackers", "data-analytics", "grc", "infra-as-code", "skill-engineering"],
4
+ "packs": ["core", "solution-architect", "product-manager", "dev-team", "sre-oncall", "stakeholder-comms", "design", "ai-engineering", "api-builder", "converters", "experience-design", "research", "trackers", "data-analytics", "grc", "infra-as-code", "skill-engineering", "career"],
5
5
  "outcomes": {
6
6
  "decide-what-to-build": {
7
7
  "for": "Product managers · founders · strategists",
@@ -185,6 +185,16 @@
185
185
  "skill-author",
186
186
  "skill-review"
187
187
  ]
188
+ },
189
+ "apply-for-a-job": {
190
+ "for": "Anyone applying for a job, in any field",
191
+ "description": "Prepare one application that is tailored and true: an honest fit check against the posting, a resume reworked without adding a claim, a cover letter built only from what you supplied, and the application form's answers drafted from your resume.",
192
+ "skills": [
193
+ "job-fit-analysis",
194
+ "resume-tailor",
195
+ "cover-letter",
196
+ "application-form-answers"
197
+ ]
188
198
  }
189
199
  }
190
200
  }
@@ -481,6 +481,22 @@
481
481
  "ux-writing": {
482
482
  "tier": "standard",
483
483
  "rationale": "Short-form writing to fixed slot rules and character budgets, plus a terminology consistency pass. Bounded generation with clear checks."
484
+ },
485
+ "job-fit-analysis": {
486
+ "tier": "standard",
487
+ "rationale": "Matches a posting's requirements to resume lines and reports the gaps. The rule is mechanical: no line in the resume, no credit."
488
+ },
489
+ "resume-tailor": {
490
+ "tier": "standard",
491
+ "rationale": "Reorders and rewords existing content against a posting, with a script listing every figure and name the original doesn't contain."
492
+ },
493
+ "cover-letter": {
494
+ "tier": "standard",
495
+ "rationale": "A short letter from supplied facts, with a script listing every figure and name the person's material doesn't contain."
496
+ },
497
+ "application-form-answers": {
498
+ "tier": "standard",
499
+ "rationale": "Sorts questions into three kinds and drafts short answers from the resume. The hard rule is mechanical: a declaration is never answered for the person."
484
500
  }
485
501
  }
486
502
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "skilldrop-cli",
3
- "version": "0.16.6",
3
+ "version": "0.16.8",
4
4
  "description": "Portable AI-agent skills, measured against the agent without them. ADRs, PRDs, runbooks, decks and reviews, installable into Claude Code, Cursor, Kiro, and any IDE that takes custom instructions. One command per skill or per role-based pack.",
5
5
  "author": {
6
6
  "name": "Sanjay Ananthanarayan",
@@ -14,6 +14,36 @@
14
14
  "The disclosure rule states whether and where AI assistance must be declared",
15
15
  "No regulation is asserted beyond what the prompt names; unclear applicability is marked [confirm with counsel]"
16
16
  ]
17
+ },
18
+ {
19
+ "id": 2,
20
+ "held_out": "2026-10-05",
21
+ "prompt": "I'm the office manager at a 40-person recruitment agency and the MD has asked me to write our AI policy. Her email is in md-email.md, what our IT provider told me is in it-notes.md, and our existing data labels are in data-handling-sheet.md. Can you draft the policy so I can send it to her?",
22
+ "assertions": [
23
+ "It says candidate CVs, salary details and other Confidential data must not go into personal or free chatbot accounts, and tells staff what to do instead for the same task",
24
+ "It separates the 8-seat ChatGPT Team workspace from personal ChatGPT accounts, and notes that about 30 people have no Team seat",
25
+ "Copilot is not listed as an approved or available tool: the trial ended on 30 June 2026 and was not renewed",
26
+ "It does not state that the tools never train on the firm's data or that data stays in the UK; it says this is unconfirmed until someone checks the contract terms",
27
+ "It does not simply make Brightwell IT the policy owner: it notes Brightwell declined to make policy decisions and the operations manager post is vacant, and proposes an interim owner or flags ownership for the MD to decide",
28
+ "It says candidate data for Aldercroft Group roles must not go into any AI tool without Aldercroft's written consent",
29
+ "It says what to do about the 14 CVs pasted on 16 September and tells staff who to report it to if they have already pasted Confidential data",
30
+ "It names no law or regulation other than GDPR, which the MD mentioned, and NoteQuill is treated as unapproved or pending review, not as cleared"
31
+ ]
32
+ },
33
+ {
34
+ "id": 3,
35
+ "held_out": "2026-10-05",
36
+ "prompt": "we're a small charity, 12 staff plus volunteers. the trustees want an 'AI policy' by the next board meeting. honestly I don't know what tools people are using, I think a couple of them use chatgpt for grant applications. we hold case notes on the people we support. can you write something short I can take to the board",
37
+ "assertions": [
38
+ "It delivers a draft policy in the reply and does not stop at a list of questions",
39
+ "It says case notes and anything that identifies a person the charity supports must not be put into AI chatbots, and says what to do instead",
40
+ "Drafting grant applications with AI is allowed, with a person checking the facts and figures before the application is submitted",
41
+ "It says whether the policy covers volunteers as well as the 12 staff",
42
+ "It says which tools are in use is not known, and proposes finding out or leaves the approved-tool list to be filled in; it does not present a list of approved tools as already agreed",
43
+ "It names no individual and no charity name; responsibilities are given to roles (for example a named trustee role or the director) or flagged for the board to assign",
44
+ "It does not state that a specific law, regulator or sector code applies as fact; any mention is marked as something to confirm",
45
+ "The policy itself is short: about two pages or less (roughly 800 words)"
46
+ ]
17
47
  }
18
48
  ]
19
49
  }
@@ -0,0 +1,18 @@
1
+ # Larkfield Talent: data handling sheet (v3, January 2025)
2
+
3
+ Three labels. Everything the firm holds is one of these.
4
+
5
+ | Label | What it covers | Examples |
6
+ |---|---|---|
7
+ | **Public** | Anything already published | Job adverts, the website, published salary guides |
8
+ | **Internal** | Day-to-day business information that is not about an identifiable person | Internal process docs, anonymised placement statistics, fee templates |
9
+ | **Confidential** | Anything about an identifiable candidate or client contact, and anything a client contract restricts | Candidate CVs, salary and notice details, interview notes, client contracts, call recordings |
10
+
11
+ ## Client-specific terms
12
+
13
+ **Aldercroft Group** (master services agreement, clause 9.3): candidate data relating to
14
+ Aldercroft roles must not be passed to any third-party processor without Aldercroft's prior
15
+ written consent.
16
+
17
+ No other client contract has a clause like this as far as we know. Nobody has checked since
18
+ 2025.
@@ -0,0 +1,31 @@
1
+ # Notes from Brightwell IT (outsourced provider, on site Thursdays)
2
+
3
+ Sent by Petra Lindqvist, Brightwell IT, 30 September 2026, in reply to Wendell's questions.
4
+
5
+ ## Tools we know about
6
+
7
+ | Tool | Status | Detail |
8
+ |---|---|---|
9
+ | ChatGPT Team | Active | 8 seats, bought March 2026. Assigned to the directors and the marketing team. |
10
+ | ChatGPT free / personal accounts | In use, not managed | We see sign-ins from most consultant laptops. We reckon about 30 people. Personal email logins, nothing we control. |
11
+ | Microsoft Copilot | Not active | 10-seat trial. It ended on 30 June 2026 and was not renewed. |
12
+ | NoteQuill (call transcription) | In use, not managed | Browser extension. 6 consultants have it installed. Nobody bought it centrally. We have not looked at its terms. |
13
+
14
+ ## Things you asked
15
+
16
+ **Do the tools train on our data / where is it stored?** We have not reviewed the terms for
17
+ any of these and can't confirm either way. Somebody would need to read the contract for the
18
+ Team plan. For the personal accounts and NoteQuill we have nothing.
19
+
20
+ **Can Brightwell own the policy?** No. We keep the laptops and accounts running. We don't
21
+ make policy decisions for clients and we are only with you one day a week. We can enforce
22
+ whatever you decide (blocking sites, removing extensions) if you tell us what.
23
+
24
+ **Who did this before?** The operations manager, but that post has been empty since
25
+ Farida left in August.
26
+
27
+ ## The incident
28
+
29
+ On 16 September a consultant pasted 14 candidate CVs into a personal ChatGPT account to
30
+ get one-paragraph summaries for a client shortlist. We found out because he mentioned it.
31
+ Nothing has been done about it since.
@@ -0,0 +1,29 @@
1
+ From: Corinne Ashby (Managing Director)
2
+ To: Wendell Okafor (Office Manager)
3
+ Date: 28 September 2026
4
+ Subject: AI rules, need something written down
5
+
6
+ Wendell,
7
+
8
+ After the thing with Tobias I want an actual policy for AI tools that I can send to all
9
+ 40 of us. Short enough that people read it.
10
+
11
+ Where I think we are:
12
+
13
+ - ChatGPT is approved. We have a Team licence.
14
+ - We have Copilot as well.
15
+ - The transcription thing the consultants use on client calls, I don't know what it's
16
+ called.
17
+
18
+ Things I want it to say:
19
+
20
+ - Our tools never train on our data and everything stays in the UK. Clients ask about this
21
+ and I want to be able to point at the policy.
22
+ - What people can and can't put in. Candidate CVs are the obvious one. GDPR obviously
23
+ applies to us.
24
+ - What we do about the CVs Tobias already pasted in.
25
+ - IT will own it.
26
+
27
+ Use the labels from the data handling sheet, I don't want a second scheme.
28
+
29
+ Corinne
@@ -13,6 +13,35 @@
13
13
  "Includes a Python snippet passing the tool to client.messages.create(tools=[...]) and handling stop_reason == 'tool_use'",
14
14
  "Does not invent parameters, enum values, or behaviors not in the supplied signature and docstring"
15
15
  ]
16
+ },
17
+ {
18
+ "id": 2,
19
+ "held_out": "2026-10-05",
20
+ "prompt": "Need a Claude tool definition for bookAppointment (it's in book_appointment.ts) so our front-desk assistant can book visits for callers. Ideally the same tool lets it cancel a booking too.",
21
+ "assertions": [
22
+ "It produces a tool definition with a name, a description and an input_schema of type object, and ctx / RequestContext is not one of the properties",
23
+ "The top-level required array contains the clinic code, visit type, start time and contact, and does not contain duration, vet id or notes",
24
+ "The pet id is not unconditionally required: the definition or reply states it is needed for every visit type except new_patient and must be left out for new_patient",
25
+ "contact is a nested object with its own required array containing phone, with email and SMS reminders optional",
26
+ "It flags that the comment says bookings can be made up to 90 days ahead while the code enforces 60, and does not state 90 days as the limit",
27
+ "Duration is limited to 15, 30 or 45 with a default of 30, and the definition states that dental visits need 45 minutes",
28
+ "It says cancelling is not supported by this function and does not add a cancel parameter, action or mode to the tool",
29
+ "It does not list six clinic codes as an enum or as fact, since the source gives only the example PVG-03"
30
+ ]
31
+ },
32
+ {
33
+ "id": 3,
34
+ "held_out": "2026-10-05",
35
+ "prompt": "need tool defs for our support agent, two things: look up a shipment by tracking number, and get a shipping quote. quote needs origin zip, dest zip, weight (lbs) and service level - we have ground, 2-day and overnight i think? Dario would know for sure. dimensions are optional on the quote. no idea yet what the lookup gives back, that endpoint's still being built",
36
+ "assertions": [
37
+ "It delivers two tool definitions, each with a name, a description and an input_schema, and does not stop at questions",
38
+ "The quote tool's required array includes origin zip, destination zip and weight, and dimensions is not in it",
39
+ "The weight parameter's description states the unit is pounds",
40
+ "Service level offers ground, 2-day and overnight, and the reply says that list is unconfirmed and should be checked",
41
+ "Each tool's description says when the agent should call it, so a tracking question and a pricing question map to different tools",
42
+ "It does not state a tracking number format or pattern, a weight limit, carrier names or a dimension unit as fact",
43
+ "It does not describe the lookup's return fields as fact, and says what the lookup returns is not yet known"
44
+ ]
16
45
  }
17
46
  ]
18
47
  }
@@ -0,0 +1,64 @@
1
+ // scheduling/book_appointment.ts — Pawline Veterinary Group
2
+ import { RequestContext, ValidationError } from "../lib/http";
3
+ import { daysAhead, isQuarterHour, slots } from "./slots";
4
+
5
+ const MAX_ADVANCE_DAYS = 60;
6
+ const ALLOWED_DURATIONS = [15, 30, 45];
7
+
8
+ export type VisitType = "new_patient" | "checkup" | "vaccination" | "dental";
9
+
10
+ export interface OwnerContact {
11
+ phone: string; // E.164, e.g. +14155550123
12
+ email?: string;
13
+ smsReminders?: boolean; // default true
14
+ }
15
+
16
+ export interface BookAppointmentInput {
17
+ clinicCode: string; // one of our six clinic codes, e.g. "PVG-03"
18
+ visitType: VisitType;
19
+ petId?: string; // existing patient id: "pet_" followed by 8 characters
20
+ startTime: string; // ISO 8601 with UTC offset, on a 15-minute boundary
21
+ durationMinutes?: number; // default 30
22
+ vetId?: string; // omit to get the first available vet
23
+ contact: OwnerContact;
24
+ notes?: string; // shown to the vet, max 500 characters
25
+ }
26
+
27
+ /**
28
+ * Books an appointment slot at one clinic. Appointments can be booked up to
29
+ * 90 days ahead. Returns the confirmation code and the assigned vet.
30
+ *
31
+ * Booking only. Rescheduling and cancelling are handled by the front desk
32
+ * for now; there is no endpoint for either yet.
33
+ */
34
+ export async function bookAppointment(input: BookAppointmentInput, ctx: RequestContext) {
35
+ const duration = input.durationMinutes ?? 30;
36
+
37
+ if (input.visitType !== "new_patient" && !input.petId) {
38
+ throw new ValidationError("petId is required for existing patients");
39
+ }
40
+ if (input.visitType === "new_patient" && input.petId) {
41
+ throw new ValidationError("new_patient visits must not carry a petId");
42
+ }
43
+ if (!ALLOWED_DURATIONS.includes(duration)) {
44
+ throw new ValidationError("durationMinutes must be 15, 30 or 45");
45
+ }
46
+ if (input.visitType === "dental" && duration < 45) {
47
+ throw new ValidationError("dental visits need 45 minutes");
48
+ }
49
+ if (!isQuarterHour(input.startTime)) {
50
+ throw new ValidationError("startTime must be on a 15-minute boundary");
51
+ }
52
+ if (daysAhead(input.startTime) < 0) {
53
+ throw new ValidationError("startTime is in the past");
54
+ }
55
+ if (daysAhead(input.startTime) > MAX_ADVANCE_DAYS) {
56
+ throw new ValidationError("startTime is too far ahead");
57
+ }
58
+ if (input.notes && input.notes.length > 500) {
59
+ throw new ValidationError("notes is limited to 500 characters");
60
+ }
61
+
62
+ const slot = await slots.reserve({ ...input, durationMinutes: duration }, ctx.staffUserId);
63
+ return { confirmationCode: slot.code, vetId: slot.vetId, startTime: slot.startTime };
64
+ }
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: apply
3
+ description: Take one job posting and one resume to an application ready to send — an honest fit check, a tailored resume, a cover letter and the answers to the application form — with the candidate deciding whether to apply before any writing, and confirming every claim is true before anything is sent. Use when the user wants to apply for a job, says "help me apply for this", or wants a resume and cover letter prepared for one posting.
4
+ ---
5
+
6
+ # apply
7
+
8
+ One application, start to send, for any job. It opens with a gate because the cheapest
9
+ application is the one you decide not to write, and it closes with one because the candidate
10
+ signs these documents and answers for them at interview. Both gates are **human**: an agent
11
+ can say what the resume shows, but only the candidate knows what is true and what they want.
12
+
13
+ ## Stages
14
+
15
+ | # | Stage | Type | Skills | Gate |
16
+ |---|---|---|---|---|
17
+ | 1 | `fit` | gate | [`job-fit-analysis`](../../skills/job-fit-analysis/SKILL.md) | **G5** human |
18
+ | 2 | `tailor` | generate | [`resume-tailor`](../../skills/resume-tailor/SKILL.md) | — |
19
+ | 3 | `letter` | generate | [`cover-letter`](../../skills/cover-letter/SKILL.md) | — |
20
+ | 4 | `form` | generate | [`application-form-answers`](../../skills/application-form-answers/SKILL.md) | — |
21
+ | 5 | `confirm` | verify | [`output-hygiene`](../../../core/skills/output-hygiene/SKILL.md) | **G6** human |
22
+
23
+ ## How to run this loop
24
+
25
+ 1. **Check the fit and stop.** Run `job-fit-analysis` on the posting, the resume and any
26
+ other material of the candidate's: a LinkedIn summary, a portfolio, a project. Put its
27
+ verdict, what could get the application rejected and its questions to the candidate,
28
+ including whether anything outside the resume covers a gap, then wait at G5.
29
+ - `PROCEED`: they are applying. Go on.
30
+ - `PROCEED WITH CONDITIONS`: they are applying and have answered the questions. Save
31
+ their answers to `notes.md`; from here on those answers are source material alongside
32
+ the resume.
33
+ - `RECONSIDER`: they are not applying. The loop ends here, and that is a good outcome.
34
+ 2. **Tailor the resume.** Run `resume-tailor` with the resume, the posting and `notes.md`
35
+ if it exists. It works in the resume's own format, on a copy. Carry forward its three
36
+ lists: "Not claimed", "Cut" and "Added from outside the resume".
37
+ 3. **Write the letter.** Run `cover-letter` with the tailored resume, the posting, `notes.md`
38
+ and the candidate's reason for wanting the job if they gave one. Skip this stage when the
39
+ posting says not to send a letter.
40
+ 4. **Answer the form.** When the application has a form with questions beyond uploading
41
+ the documents, run `application-form-answers` with those questions and the tailored
42
+ resume. Skip this stage when there is no form.
43
+ 5. **Clean the documents.** Run `output-hygiene` on the resume and the letter.
44
+ 6. **Confirm at G6.** Show the candidate the documents with four short lists: what the
45
+ posting asks for that the documents do not claim; every fact added from outside the
46
+ resume and where it came from; every line cut from the resume; and the form questions
47
+ that are theirs alone to answer. Ask them to confirm every line is true. `NOT READY` returns to `tailor` with their
48
+ corrections added to `notes.md`. The candidate sends the application; the loop never does.
49
+
50
+ ## Verdicts
51
+
52
+ Defined in [`contracts/terminals.json`](../../../../contracts/terminals.json). G5 emits
53
+ `PROCEED`, `PROCEED WITH CONDITIONS`, `RECONSIDER` or `BLOCKED`. G6 emits `READY`,
54
+ `NOT READY` or `BLOCKED`. `RECONSIDER` leaves the loop: the candidate's time goes to a
55
+ better posting.
56
+
57
+ ## Non-interactive runs
58
+
59
+ With no person present, neither gate can be satisfied. Run `fit`, deliver the analysis and
60
+ emit `BLOCKED: need the candidate's decision to apply`. Do not decide for them, and do not
61
+ produce documents carrying their name that they have not confirmed.
62
+
63
+ ## When a stage's skill is not installed
64
+
65
+ Name the missing skill and skilldrop as its source, do the minimal inline version of that
66
+ stage under the same rule (nothing the candidate didn't supply), and record that it ran
67
+ degraded. Never skip G6.
68
+
69
+ ## Run log (opt-in)
70
+
71
+ Only when the environment variable `SKILLDROP_LOOP_LOG` is set to a file path: after each
72
+ gate's verdict, append one JSON line to that file. Nothing else is recorded, and nothing is
73
+ sent anywhere. When the variable isn't set, or you can't read it, skip this section.
74
+
75
+ ```bash
76
+ printf '%s\n' '{"ts":"2026-10-05T14:03:00Z","loop":"apply","stage":"fit","gate":"G5","verdict":"PROCEED","round":1}' >> "$SKILLDROP_LOOP_LOG"
77
+ ```
78
+
79
+ Fields: `ts` (UTC), `loop`, `stage`, `gate` (`null` for a stage without one), `verdict` (the
80
+ gate's exact word), and `round` (1 for the first attempt, counting returns under the cap).
81
+ The log holds verdicts only: never the posting, the resume or the candidate's name.
82
+
83
+ ## Quality bar
84
+
85
+ - **The candidate decides to apply before anything is written.** A tailored resume for a job they would have skipped is wasted work.
86
+ - **Every claim in both documents traces to the resume or to something the candidate said.** Answers given at G5 are written to `notes.md`, so the trace exists.
87
+ - **The resume, the letter and the form agree.** Same titles, dates and numbers in all three.
88
+ - **The candidate confirms and sends.** G6 is their signature; the loop never submits an application.
89
+
90
+ ## Anti-patterns to avoid
91
+
92
+ - ❌ **Skipping `fit` because the candidate is keen.** The screening requirements are what they most need to see before investing the time.
93
+ - ❌ **Treating a `Not shown` item as true** because the candidate proceeded. Only what they answered goes in.
94
+ - ❌ **Writing the letter from the original resume.** The letter follows the tailored one, or the two will disagree.
95
+ - ❌ **Answering a declaration on the form** for the candidate, or leaving out the list of what was added and cut.
96
+ - ❌ **Self-confirming at G6.** A clean claim check says the words are in the source; it cannot say they are true.
97
+ - ❌ **Submitting the application.** Sending is the candidate's act.
@@ -0,0 +1,9 @@
1
+ [
2
+ {"query": "help me apply for this job", "should_trigger": true},
3
+ {"query": "run the apply loop on this posting and my resume", "should_trigger": true},
4
+ {"query": "I want a tailored resume and cover letter for this role", "should_trigger": true},
5
+ {"query": "get my application for this job ready to send", "should_trigger": true},
6
+ {"query": "is this job a good fit for me?", "should_trigger": false},
7
+ {"query": "just write a cover letter for this", "should_trigger": false},
8
+ {"query": "turn these notes into a finished document", "should_trigger": false}
9
+ ]
@@ -0,0 +1,27 @@
1
+ {
2
+ "loop_name": "apply",
3
+ "evals": [
4
+ {
5
+ "id": "stops-at-the-fit-gate",
6
+ "prompt": "Run the apply loop. My resume is in resume.md and the job is in posting.md. [a warehouse supervisor's resume with a high school diploma; a posting that requires a bachelor's degree]",
7
+ "assertions": [
8
+ "Starts with job-fit-analysis and delivers its verdict before any resume or letter is written",
9
+ "Names the unmet bachelor's degree as a screening requirement",
10
+ "Stops at G5 and asks the candidate whether to apply; does not tailor the resume in the same turn",
11
+ "Does not advise claiming the degree or adding any keyword the resume does not support"
12
+ ]
13
+ },
14
+ {
15
+ "id": "answers-become-source-material",
16
+ "prompt": "Continuing the apply loop: yes I want to apply. To your questions: I do speak Spanish, and no, I've never used SAP. [same resume and posting]",
17
+ "assertions": [
18
+ "Records the gate verdict as PROCEED WITH CONDITIONS and saves the answers to notes.md",
19
+ "The tailored resume includes Spanish and does not claim SAP",
20
+ "The cover letter is written after the tailored resume and uses the same titles, dates and numbers",
21
+ "Runs output-hygiene on both documents before the final gate",
22
+ "Stops at G6 and asks the candidate to confirm every line is true; does not submit or send anything",
23
+ "Lists what the posting asks for that neither document claims"
24
+ ]
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "$comment": "RFC-0042. One job application, start to send. The first gate exists because the cheapest application is the one not written; the last because the candidate, not the agent, signs what is sent.",
3
+ "name": "apply",
4
+ "version": "0.2.0",
5
+ "description": "Take one job posting and one resume to an application ready to send — an honest fit check, a tailored resume, a cover letter and the answers to the application form — with the candidate deciding whether to apply before any writing, and confirming every claim is true before anything is sent. Use when the user wants to apply for a job, says \"help me apply for this\", or wants a resume and cover letter prepared for one posting.",
6
+ "entrypoint": "LOOP.md",
7
+ "kind": "loop",
8
+ "cap": 3,
9
+ "stages": [
10
+ {
11
+ "id": "fit",
12
+ "type": "gate",
13
+ "intent": "Say honestly where the candidate stands against the posting, then let them decide whether this application is worth writing.",
14
+ "skills": ["job-fit-analysis"],
15
+ "gate": {
16
+ "id": "G5",
17
+ "kind": "human",
18
+ "verdicts": ["PROCEED", "PROCEED WITH CONDITIONS", "RECONSIDER", "BLOCKED"]
19
+ }
20
+ },
21
+ {
22
+ "id": "tailor",
23
+ "type": "generate",
24
+ "intent": "Rewrite the resume for this posting from what the candidate has done and nothing else.",
25
+ "skills": ["resume-tailor"]
26
+ },
27
+ {
28
+ "id": "letter",
29
+ "type": "generate",
30
+ "intent": "Write the letter from the tailored resume, the posting and the candidate's own reason for wanting the job.",
31
+ "skills": ["cover-letter"]
32
+ },
33
+ {
34
+ "id": "form",
35
+ "type": "generate",
36
+ "intent": "Draft the application form's answers from the tailored resume, and hand back the declarations that are the candidate's alone.",
37
+ "skills": ["application-form-answers"]
38
+ },
39
+ {
40
+ "id": "confirm",
41
+ "type": "verify",
42
+ "intent": "Strip what the machine left behind, then have the candidate confirm that every line in the documents is true and theirs, and that anything added from outside the resume is right.",
43
+ "skills": ["output-hygiene"],
44
+ "gate": {
45
+ "id": "G6",
46
+ "kind": "human",
47
+ "verdicts": ["READY", "NOT READY", "BLOCKED"],
48
+ "revise_to": "tailor"
49
+ }
50
+ }
51
+ ]
52
+ }
@@ -0,0 +1,77 @@
1
+ {
2
+ "description": "One job application, for any occupation: an honest check of your resume against the posting, a tailored resume and a cover letter that say nothing you didn't, the application form's answers drafted from your resume, and a script that lists every figure and name in a draft that your own resume doesn't contain.",
3
+ "display_name": "Job applications",
4
+ "keywords": [
5
+ "resume",
6
+ "cv",
7
+ "cover letter",
8
+ "job application",
9
+ "job search",
10
+ "career change",
11
+ "job posting",
12
+ "application form"
13
+ ],
14
+ "links": {
15
+ "documentation": "https://sananthanarayan.github.io/skilldrop/packs/career/"
16
+ },
17
+ "maintainers": [
18
+ {
19
+ "name": "sananthanarayan"
20
+ }
21
+ ],
22
+ "first-value": {
23
+ "audience-posture": "non-technical",
24
+ "prerequisites": [
25
+ "Your resume or CV as text, Markdown or a file your agent can read",
26
+ "The job posting, pasted or saved as a file"
27
+ ],
28
+ "starter-task": "Find out where you stand against a posting before you write the application",
29
+ "starter-prompt": "My resume is in resume.md and the job I'm looking at is in posting.md. Am I a good fit? Be honest about what's missing.",
30
+ "verification": "job-fit-analysis opens with a verdict (strong match, worth applying, long shot or not a match), lists the requirements an employer screens on first, marks every requirement met, partly, not shown or not met with the resume line behind it, and ends with questions about what your resume doesn't show.",
31
+ "recovery": "If it credits you with something that isn't in your resume, say so and run it again. If job-fit-analysis does not activate, ask for it by name (\"use job-fit-analysis\")."
32
+ },
33
+ "requires": [
34
+ "core"
35
+ ],
36
+ "journey": {
37
+ "when": "You've found a job you might apply for and want an application that is tailored to it and true.",
38
+ "you_bring": [
39
+ "your current resume or CV",
40
+ "the job posting",
41
+ "anything relevant that isn't on your resume: a tool you've used, a language you speak, a number you know",
42
+ "your reason for wanting the job, if you have one"
43
+ ],
44
+ "time": "About half an hour for one application",
45
+ "steps": [
46
+ {
47
+ "skill": "job-fit-analysis",
48
+ "you_do": "Give it the posting, your resume and anything else of yours that bears on the job, such as a LinkedIn summary or a project.",
49
+ "you_get": "A verdict, the screening requirements first, every requirement marked against your resume with the line it rests on, and questions about what your resume doesn't show.",
50
+ "decide": "Whether to apply, and your answers to its questions."
51
+ },
52
+ {
53
+ "skill": "resume-tailor",
54
+ "you_do": "Give it the resume, the posting and your answers.",
55
+ "you_get": "A tailored resume in your resume's own format, as a new file, with every employer, title, date and number as you had them, plus what changed, what was cut, what was added from outside the resume, and what the posting asks for that it cannot claim."
56
+ },
57
+ {
58
+ "skill": "cover-letter",
59
+ "you_do": "Give it the tailored resume, the posting and your reason for wanting the job.",
60
+ "you_get": "A letter under a page that opens on your strongest evidence and says nothing about you or the employer that you or the posting didn't supply."
61
+ },
62
+ {
63
+ "skill": "application-form-answers",
64
+ "you_do": "If the application has a form, give it the form's questions and the tailored resume.",
65
+ "you_get": "An answer sheet in the form's order: answers drafted from your resume inside each word limit, the questions that could screen you out named first, and the declarations that are yours alone handed back with what on your resume bears on them.",
66
+ "decide": "Your answers on right to work, salary, start date and the other declarations."
67
+ },
68
+ {
69
+ "skill": "output-hygiene",
70
+ "you_do": "Run it on the resume and the letter before you send them.",
71
+ "you_get": "Both documents with invisible characters and machine residue removed, and any stock phrases quoted with a rewrite.",
72
+ "decide": "Read both documents once more: you sign them, so every line has to be true."
73
+ }
74
+ ],
75
+ "you_end_with": "A resume, a cover letter and a form's answers for one posting that you can defend line by line at interview, and a list of what the employer will notice is missing."
76
+ }
77
+ }