diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 1349197..a0db374 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,6 +1,6 @@ { "name": "refact-os", - "version": "2.16.0", + "version": "2.17.0", "owner": { "name": "Refact Developer", "email": "dev@refact.co" @@ -8,7 +8,7 @@ "plugins": [ { "name": "base", - "version": "1.11.1", + "version": "1.12.0", "source": "./plugins/base", "description": "Base toolkit: git workflow, code-dev gates, safe production writes, Asana, env sync, learnings, client updates, slim project config, Refact Control MCP setup + the /base:refact command + TS/JS LSP.", "author": { diff --git a/plugins/base/.claude-plugin/plugin.json b/plugins/base/.claude-plugin/plugin.json index 7bbb2f8..7bf8faf 100644 --- a/plugins/base/.claude-plugin/plugin.json +++ b/plugins/base/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "base", - "version": "1.11.1", + "version": "1.12.0", "description": "Base toolkit: git workflow, code-dev gates, safe production writes, Asana, env sync, learnings, client updates, slim project config, Refact Control MCP setup + the /base:refact command + TS/JS LSP.", "author": { "name": "Refact Developer", diff --git a/plugins/base/.codex-plugin/plugin.json b/plugins/base/.codex-plugin/plugin.json index a7b7dfd..d74b9fc 100644 --- a/plugins/base/.codex-plugin/plugin.json +++ b/plugins/base/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "base", - "version": "1.11.1", + "version": "1.12.0", "description": "Refact base workflows for Claude Code and Codex.", "author": { "name": "Refact Developer", diff --git a/plugins/base/skills/writing-client-updates/CHANGELOG.md b/plugins/base/skills/writing-client-updates/CHANGELOG.md index a41bfa9..1fd02e1 100644 --- a/plugins/base/skills/writing-client-updates/CHANGELOG.md +++ b/plugins/base/skills/writing-client-updates/CHANGELOG.md @@ -2,6 +2,25 @@ Newest first. Written by the Skill Analyzer; verdicts are filled in by code. +## 1.2.0 — 2026-09-09 — minor — Skill Analyzer 2026-W35 + +**Change:** Added a pre-draft fact check that runs before the draft: confirm the recipient from project memory, state only what the source material says and mark inferences as assumptions, read the whole referenced source rather than the first claim in it, and confirm whether the client asked for the work or we found it ourselves before choosing the opening. + +**Why:** Client-update drafts named contacts who do not exist, attributed unstated claims to real people, and framed internally-found work as a client request. Each one forced a redraft, three times in three sessions. + +**Evidence:** +- [F-010] skill.missing-instruction · rework · base:writing-client-updates v1.1.0 | A claim was attributed to a named client contact and a workspace account was asserted, neither stated in the source. | quote: "Nina said nobody on their side has n8n access, but there **is** an account under `jordan@credaily.com` on the workspace" | fix: Confirm the recipient and every attributed claim against project memory before naming either. | credaily-website · jamalisaeed +- [F-078] skill.missing-instruction · rework · base:writing-client-updates v1.1.0 | The draft had to be rewritten after review rather than checked before presenting. | quote: "Want it tighter (it's on the long side for an Asana comment)" | fix: Run the checks before drafting, not after the first draft is shown. | stlouis-website · Saeed Jamali +- [F-081] skill.missing-instruction · rework · base:writing-client-updates v1.1.0 | An unverified finding was stated to the client as settled fact. | quote: "The mechanism is gone: no plugin, no cache, no database, no settings screen." | fix: State only what the source says; mark an inference as an assumption in the same sentence. | stlouis-website · ali-karimii +- [F-082] skill.missing-instruction · rework · base:writing-client-updates v1.1.0 | Internally-discovered work prepared for a colleague to send was framed as a client-requested update. | quote: "also prepare an internal message and tell about preload and caching so I can send it on task." | fix: Confirm who asked for the work, and who the message is really for, before choosing the opening. | stlouis-website · ali-karimii + +**Collision check:** The ~120-word first-draft ceiling and the merge/deploy guard shipped in 1.1.0 are unchanged and still steps 5 and 6. The fact check is a pre-draft gate on the notes, not a section of the message, and it caps assumption marking at a few words: an unverified claim that would need a paragraph of hedging is cut instead. So it removes rewrite passes without adding length. Steps 4 and 5 of SKILL.md had run together on one line since 1.1.0; the numbering is repaired and "offer to tighten" moved to the end of the list, where it belongs in the order of work. + +**Expectation:** No client update names an unconfirmed contact, states an unmarked inference as fact, or opens internally-found work as a client request. + +**Verdict:** still collecting + + ## 1.1.0 — 2026-07-29 — minor — Skill Analyzer 2026-W31 **Change:** Added a guard forbidding merge/deploy/release claims without an observed tool action and a first-draft length ceiling. diff --git a/plugins/base/skills/writing-client-updates/SKILL.md b/plugins/base/skills/writing-client-updates/SKILL.md index 59329d2..d7dd27d 100644 --- a/plugins/base/skills/writing-client-updates/SKILL.md +++ b/plugins/base/skills/writing-client-updates/SKILL.md @@ -1,6 +1,6 @@ --- name: writing-client-updates -version: 1.1.0 +version: 1.2.0 description: Draft a structured client-facing update for a task or issue — by email or Slack — using a headline-first format that tells the client where things stand, why, and what comes next. pattern: procedure when_to_use: When a developer or designer needs to communicate task status, an issue resolution, or an in-progress update to a client via email or Slack. Trigger phrases include "write a client update", "draft an email to the client", "how do I tell the client about this", "send an update on the issue". @@ -19,9 +19,11 @@ Draft a client-facing update that is clear, structured, and confident — email 1. Read [`references/writing-client-updates.md`](references/writing-client-updates.md) for the full format, tone rules, and email vs. Slack guidance. 2. Ask for the raw situation if the user hasn't provided it: what happened, what was found, what was done, and what comes next. -3. Draft the update in the correct format for the channel (full 7-part structure for email; headline-first short form for Slack). -4. Offer to tighten or adjust tone before the user sends it.5. Never state a merge, deploy, or release status (e.g. "merged to stage", "promoted to production", "deployed") unless a corresponding tool action — an actual merge or deploy — was executed and observed in this session. If only a PR was opened, say exactly that; do not describe it as merged or released. +3. Run the [pre-draft fact check](references/writing-client-updates.md#pre-draft-fact-check) before writing a word: confirm the recipient from project memory, confirm every claim against the source material, and confirm whether the client asked for this work or we found it ourselves. It is a check on your notes, not a part of the message, so it adds nothing to the length target in step 6. +4. Draft the update in the correct format for the channel (full 7-part structure for email; headline-first short form for Slack). +5. Never state a merge, deploy, or release status (e.g. "merged to stage", "promoted to production", "deployed") unless a corresponding tool action — an actual merge or deploy — was executed and observed in this session. If only a PR was opened, say exactly that; do not describe it as merged or released. 6. Keep the first draft short: aim for roughly half a screen (about 120 words for email, 40 for Slack). Match length to the situation's complexity so the first draft does not need to be rewritten shorter. +7. Offer to tighten or adjust tone before the user sends it. ## The core principle diff --git a/plugins/base/skills/writing-client-updates/references/writing-client-updates.md b/plugins/base/skills/writing-client-updates/references/writing-client-updates.md index b07dd71..00bd6e2 100644 --- a/plugins/base/skills/writing-client-updates/references/writing-client-updates.md +++ b/plugins/base/skills/writing-client-updates/references/writing-client-updates.md @@ -6,6 +6,35 @@ This guide is for any developer or designer at Refact who needs to send a client A client reading your update should come away knowing four things without having to ask follow up questions. They should know where things stand right now, what we found when we looked into it, what they need to do if anything, and what we are doing next. Everything else is supporting detail. +## Pre-draft fact check + +Run this before you write a word of the draft. It is a check on your notes, not a part of the message. Nothing in this section is meant to end up in the update as extra text, so it does not compete with the length guidance below. + +### Confirm the recipient before you name them + +Find the client contact in project memory and use the name and the role it gives. Do not take a name from a chat message, a commit, an email address, or your own recollection of the account. If project memory names no contact, ask who the update is for. Do not guess a first name, and do not address someone who was only mentioned in passing. A greeting to a person who does not exist undoes the confidence the rest of the message is trying to build. + +### State only what the source says, and mark the rest + +Every fact, name, number, date, URL, quote, and contract clause in the draft must appear in the source material you were given: the notes, the transcript, the ticket, the document, or a file you opened. If it is not there, do one of two things. Leave it out, or mark it as an assumption in the same sentence with a few words such as "we believe" or "this looks like". Never present an inference as a checked fact, and never attribute a claim to a person unless that person actually said it in the source. + +Keep the marking short. If being honest about an unverified claim would take a paragraph of hedging, the claim is not ready to send. Cut it, and say what you will confirm and when. That is shorter than the hedge and more useful to the client. + +Read the whole source, not the first claim in it. When someone points you at a handoff document, a report, or a pull request, check every factual claim in it before you draft from it. Checking only the claim the person named first is how a real error survives into the client's inbox and the client finds it for you. + +Status words are facts too. A pull request that is only open is open. Do not call it merged, deployed, on staging, or released. Write "the fix is in review as a pull request" rather than "the fix is heading to staging" when nothing has been merged. The same rule applies to anything else that has a state, such as an invoice, an access request, or a ticket. + +### Confirm who asked for this work before you choose the opening + +Ask one question before you write the headline: did the client raise this, or did we find it ourselves? The answer changes the first sentence. + +- The client raised it. Answer their question in the headline. "The search bar is working again as of this morning." +- We found it ourselves. Say that we found it, then say where it stands. "While reviewing the caching layer we found that search results were being served from a stale cache. That is fixed as of this morning." + +Framing our own finding as something the client asked for reads as an answer to a question they never asked, and it usually forces a full rewrite once someone notices. + +Check who the message is really for as well. A request to prepare something for a colleague to send on a ticket is an internal message, not a client update, and it opens differently. If the notes do not tell you which case you are in, ask. + ## Match the length to the update Let the update earn its length. A short, simple situation gets a short update. A complex one gets a longer one. The structure below is a checklist of what to consider, not a set of sections you must all fill. If a step has nothing real behind it, leave it out rather than padding it with filler. A two sentence message that fully answers the client is a success, not an incomplete one. Never stretch a small update into a long report to make it look thorough, and never invent detail the raw notes do not contain. When in doubt, err on the side of shorter.