From f98c5678bc53164683984bcfb65f504b1acad229 Mon Sep 17 00:00:00 2001 From: Sawyer Date: Fri, 4 Sep 2026 14:19:25 -0700 Subject: [PATCH] Restore the scribe skill 1:1 with GaaS Replace the Corbits ask_operator rewrite with Guy's GaaS body, including the question-tool YAML. Slash /scribe remains. ask_operator mapping stays on native-integration. Ignore GaaS scribe SKILL.md in prettier so list alignment stays 1:1. --- .prettierignore | 1 + CHANGELOG.md | 3 +- .../skills/native-integration/SKILL.md | 2 + plugins/corbits-skills/skills/scribe/SKILL.md | 239 +++++++++--------- tests/unit/corbits-skills-catalog.test.ts | 13 + 5 files changed, 141 insertions(+), 117 deletions(-) diff --git a/.prettierignore b/.prettierignore index a412eef9e..693a1918c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -6,6 +6,7 @@ node_modules/ CHANGELOG.md plugins/corbits-skills/skills/opsh/SKILL.md plugins/corbits-skills/skills/refactor/SKILL.md +plugins/corbits-skills/skills/scribe/SKILL.md tmp/ .claude/ diff --git a/CHANGELOG.md b/CHANGELOG.md index b7c223609..76bd884e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,10 +20,11 @@ parallel copies under `docs/` or `scripts/notes/`. At cut time: rename ### Changed - Drop unused `@opentui/keymap`, `@opentui/solid`, and `solid-js`. The interactive TUI is imperative `@opentui/core` only. +- Restore the scribe skill 1:1 with GaaS. ask_operator mapping stays on native-integration. Slash /scribe remains. - Restore the opsh skill 1:1 with GaaS. Tool/shell mapping stays on native-integration. user-invocable: false stays so it remains use_skill-only. - Restore the pull-request-review skill 1:1 with GaaS. ask_operator, /review mapping, and GitHub posting stay on native-integration. Slash /pull-request-review remains. - Restore the refactor skill 1:1 with GaaS. ask_operator mapping stays on native-integration. Slash /refactor remains. -- Ignore GaaS opsh and refactor SKILL.md in prettier so table/list alignment stays 1:1. +- Ignore GaaS opsh, refactor, and scribe SKILL.md in prettier so table/list alignment stays 1:1. - Restore the git-rebase skill body 1:1 with GaaS. Intern execution recipe stays on native-integration. user-invocable: false stays so it remains use_skill-only. - Restore the linear-issue-workflow skill body 1:1 with GaaS. Claim-first, In Review, and git-worktrees extras stay on native-integration. user-invocable: false stays so it remains use_skill-only. - Restore the interview skill body 1:1 with GaaS (AskUserQuestion). Operator-ask mapping stays on native-integration. Slash /interview remains. diff --git a/plugins/corbits-skills/skills/native-integration/SKILL.md b/plugins/corbits-skills/skills/native-integration/SKILL.md index 08d95830a..2982de013 100644 --- a/plugins/corbits-skills/skills/native-integration/SKILL.md +++ b/plugins/corbits-skills/skills/native-integration/SKILL.md @@ -43,6 +43,8 @@ Slash names that differ from GaaS skill ids: `/review` is GaaS `code-review`; `/ GaaS refactor says "ask clarifying questions" / "ask the user". Corbits extras: `ask_operator` (tool mapping above). Do not fork the GaaS refactor body. +GaaS scribe uses the `question` tool. Corbits extras: `ask_operator` (tool mapping above). Do not fork the GaaS scribe body. + When GaaS implement says you are orchestrated by karen, that is the Corbits primary (Skywalker). Route those disposition decisions through the primary, not a worker. ## Linear claim-first diff --git a/plugins/corbits-skills/skills/scribe/SKILL.md b/plugins/corbits-skills/skills/scribe/SKILL.md index bdfae2791..9b7a83c55 100644 --- a/plugins/corbits-skills/skills/scribe/SKILL.md +++ b/plugins/corbits-skills/skills/scribe/SKILL.md @@ -1,6 +1,13 @@ --- name: scribe description: Maintain product, architecture, and implementation docs — routes input, detects gaps, and interviews for completeness +tools: + - question + - read + - write + - edit + - glob + - grep --- # Scribe @@ -25,7 +32,6 @@ Before processing input, locate the documentation files: ## Document Types **Product** - Product-level documentation - - What we're building and why - User-facing value propositions - Vision and goals @@ -33,7 +39,6 @@ Before processing input, locate the documentation files: - Business justification **Architecture** - System architecture documentation - - How the system is structured - Components and their relationships - Abstractions and interfaces @@ -41,7 +46,6 @@ Before processing input, locate the documentation files: - Design decisions that are technology-agnostic **Implementation** - Implementation documentation - - Specific technology choices - Protocols and formats - Libraries and frameworks @@ -50,48 +54,68 @@ Before processing input, locate the documentation files: ## Using the Question Tool -Throughout this skill, you will use `ask_operator` to interact with the user. It takes a short `question` and an array of short option labels (strings). The operator picks one, types a custom answer, or dismisses. +Throughout this skill, you will use the `question` tool (also known as AskUserQuestion in some contexts) to interact with the user. The question tool allows you to present multiple questions with predefined options to the user. **Key mechanics:** - -- Independent questions are parallel `ask_operator` calls in the same turn — not one call with a `questions` array -- Options are short labels only. Put trade-offs, document routing, and "like [similar feature]" context in the transcript before the tool call -- Do not invent `{ label, description }` objects, `header`, or `multiple: true` — those are not this tool -- If the tool rejects a label as too long, put the essay in the transcript and retry with a shorter label -- Make options context-aware based on information you already have +- You can present multiple questions in a single tool call (as an array of questions) +- Each question has a header, question text, and multiple options +- Each option has a label and description +- Users can select one or multiple options (if `multiple: true`) +- The tool automatically includes a "Type your own answer" option by default +- Questions are answered together as a batch, but you should make options context-aware based on information you already have **When to provide context-aware options:** - - Reference similar features, patterns, or components already documented - Suggest options based on answers from previous interactions in the session - Use project-specific terminology from existing documents - When no patterns exist (empty/minimal documents), provide general options as fallbacks -**Example:** transcript first, then two parallel calls. - -PRODUCT.md already treats "reports" as a user-facing benefit; ARCHITECTURE.md has latency targets for other services. - -``` -ask_operator({ - question: "Is 'fast and reliable' a user-facing promise or a system design requirement?", - options: [ - "User-facing promise", - "System design requirement", - "Both" - ] -}) - -ask_operator({ - question: "Does 'fast' have a concrete target?", - options: [ - "Under 5 seconds", - "Different target", - "No specific target" +**Example invocation:** + +```json +{ + "questions": [ + { + "header": "Document classification", + "question": "Is 'fast and reliable' a user-facing promise or a system design requirement?", + "options": [ + { + "label": "User-facing promise", + "description": "Add to PRODUCT.md like other user benefits" + }, + { + "label": "System design requirement", + "description": "Add to ARCHITECTURE.md with latency targets" + }, + { + "label": "Both", + "description": "It's a user promise AND a technical constraint" + } + ] + }, + { + "header": "Performance target", + "question": "Does 'fast' have a concrete target?", + "options": [ + { + "label": "Under 5 seconds", + "description": "Similar to report generation target" + }, + { + "label": "Different target", + "description": "Specify a different performance goal" + }, + { + "label": "No specific target", + "description": "Keep it qualitative for now" + } + ] + } ] -}) +} ``` -Each call returns the selected label (or the operator's custom text). +The tool returns the selected options as an array of labels (e.g., `["Both", "Under 5 seconds"]`). ## Execution Steps @@ -113,24 +137,21 @@ Read the user's input and determine which category it falls into. Classification **General heuristics:** -_Product signals:_ - +*Product signals:* - Describes user needs or problems - Explains value or benefits - Discusses market or competitive positioning - Uses language like "users can", "enables", "provides value" - Talks about goals without specifying how -_Architecture signals:_ - +*Architecture signals:* - Describes components or modules - Explains how parts interact - Defines abstractions or interfaces - Discusses system properties without naming specific technologies - Technology-agnostic design decisions -_Implementation signals:_ - +*Implementation signals:* - Names specific technologies, protocols, or formats - Describes wire formats or API specifications - Specifies configuration details @@ -140,7 +161,6 @@ _Implementation signals:_ **Project-specific signals:** Read the existing documents to learn the project's vocabulary. Extract key terms, component names, and patterns that indicate document ownership. For example: - - If the architecture document discusses "the kernel" and "agents", mentions of these terms suggest architectural content - If the implementation document discusses "SMTP" and "IMAP", mentions of email protocols suggest implementation content - If the product document discusses "wallets" as a user-facing feature, wallet mentions in a value context suggest product content @@ -151,27 +171,25 @@ Use these learned signals alongside general heuristics. Project-specific vocabul If the categorization is clear, proceed to update the appropriate document. -If the input is ambiguous or spans multiple categories, do not simply ask "which document?" Instead, use `ask_operator` to interview the user and decompose the input into distinct claims that can each be routed precisely: +If the input is ambiguous or spans multiple categories, do not simply ask "which document?" Instead, use the `question` tool to interview the user and decompose the input into distinct claims that can each be routed precisely: 1. Explain what makes the input ambiguous — identify the product, architecture, and/or implementation aspects you see in it. -2. Use `ask_operator` to ask targeted questions that separate those aspects. Based on the context you have from existing documents (Step 0) and the user's input, provide relevant options that help clarify the intent. +2. Use the `question` tool to ask targeted questions that separate those aspects. Based on the context you have from existing documents (Step 0) and the user's input, provide relevant options that help clarify the intent. **If documents have content with patterns to reference:** - -- When user mentions "fast and reliable", reference existing performance promises or design constraints in the transcript, then ask with short labels: - - "User-facing promise" - - "System design requirement" - - "Both" -- When user mentions a component name, reference similar components in the transcript, then ask: - - "User-facing" - - "Internal abstraction" + - When user mentions "fast and reliable", reference existing performance promises or design constraints: + - "User-facing promise (add to PRODUCT.md like [similar feature])" + - "System design requirement (add to ARCHITECTURE.md with latency targets)" + - "Both - it's a user promise AND a technical constraint" + - When user mentions a component name, reference similar components: + - "[Component] is user-facing (like [similar component] in PRODUCT.md)" + - "[Component] is an internal abstraction (add to ARCHITECTURE.md)" **If documents are empty/minimal (no patterns to reference):** - -- Provide general options without specific references: - - "User-facing promise" - - "System design requirement" - - "Both" + - Provide general options without specific references: + - "User-facing promise (add to PRODUCT.md)" + - "System design requirement (add to ARCHITECTURE.md)" + - "Both - it's a user promise AND a technical constraint" 3. Route each extracted piece to its appropriate document. A single user statement may result in updates to multiple documents. @@ -180,7 +198,6 @@ If the input is ambiguous or spans multiple categories, do not simply ask "which Read the target document to understand its current structure and content. Determine where in the document the new content belongs: - - Does it extend an existing section? - Does it require a new section? - Does it modify existing content? @@ -188,7 +205,6 @@ Determine where in the document the new content belongs: Make the update, maintaining the document's existing style and structure. After updating, assess whether the change is **significant**. A change is significant if it: - - Introduces a new concept, component, or section - Contradicts or substantially revises existing content - Adds a top-level capability or design decision @@ -197,7 +213,7 @@ If the change is minor — extending an existing section with more detail, fixin ### Step 4: Cross-Document Consistency -_Only for significant updates._ +*Only for significant updates.* Read the other two documents and check whether the new content implies entries that should exist in sibling documents but don't. Common patterns to look for: @@ -206,7 +222,7 @@ Read the other two documents and check whether the new content implies entries t - An implementation detail referencing a component not described in architecture - A product goal with no implementation approach mentioned -If gaps are found, use `ask_operator` to present them as a batch of 2-4 questions. Based on the context from existing documents (Step 0) and the change just made, provide specific, relevant options. +If gaps are found, use the `question` tool to present them as a batch of 2-4 questions. Based on the context from existing documents (Step 0) and the change just made, provide specific, relevant options. **Example with existing patterns:** @@ -214,43 +230,41 @@ If you just added an export service to ARCHITECTURE.md, and PRODUCT.md has no me > I updated ARCHITECTURE.md with the export service. I noticed some potential gaps in other documents. -Use `ask_operator` with: - +Use the `question` tool with: - Question 1: "Should PRODUCT.md describe data export as a user-facing capability?" - - **If PRODUCT.md has similar features**: "Add as data-access capability" / "Fold into reporting" - - **If PRODUCT.md is minimal**: "Yes, add as user-facing" / "No, internal only" + - **If PRODUCT.md has similar features**: "Add export as data access capability (like reports feature)" / "Add as part of reporting feature" + - **If PRODUCT.md is minimal**: "Yes, add as new user-facing capability" / "No, exports are internal only" - Question 2: "How should IMPLEMENTATION.md describe export generation?" - - **If IMPLEMENTATION.md describes other services**: "Same approach as [service]" / "Different approach" - - **If IMPLEMENTATION.md is minimal**: "Name the library" / "Defer for now" + - **If IMPLEMENTATION.md describes other services**: "Similar to [existing service], using [library]" / "Different approach (specify details)" + - **If IMPLEMENTATION.md is minimal**: "Specify library/technology used" / "Defer implementation details for now" For each question the user answers, update the corresponding document before proceeding. ### Step 5: Gap Detection and Completeness -_Only for significant updates._ +*Only for significant updates.* Scan the updated document for weaknesses: - - Concepts referenced but not elaborated - Sections that are thin relative to their importance - Missing failure modes, edge cases, or constraints - Decisions stated without rationale -Use `ask_operator` to present 2-4 probing questions as a batch. Focus on non-obvious gaps — things the user might not think to document unprompted. Based on the content just added, questions already answered in this session, and patterns from existing documentation, provide specific, contextual options. +Use the `question` tool to present 2-4 probing questions as a batch. Focus on non-obvious gaps — things the user might not think to document unprompted. Based on the content just added, questions already answered in this session, and patterns from existing documentation, provide specific, contextual options. **Example with existing patterns:** If you just added an export service to ARCHITECTURE.md: - Question 1: "What happens when an export fails mid-generation?" - - **If other services have retry logic**: "Automatic retry, like [service]" / "User must re-trigger" / "Save partial for resume" - - **If no retry patterns exist**: "Automatic retry" / "User must re-trigger" / "Save partial for resume" + - **If other services have retry logic**: "Automatic retry (like [existing service])" / "User must re-trigger" / "Saved as partial export for resume" + - **If no retry patterns exist**: "Automatic retry" / "User must re-trigger" / "Partial export saved for resume" - Question 2: "Are there size or rate limits on exports?" - - **If similar features have limits**: "Same limits as [feature]" / "Different limits" / "No hard limits" - - **If no limits documented**: "10k rows / 100MB max" / "No hard limits" / "To be determined" + - **If similar features have limits**: "Same limits as [similar feature]" / "Different limits (specify)" / "No hard limits - best effort" + - **If no limits documented**: "10k rows / 100MB max" / "No hard limits - best effort" / "To be determined" - Question 3: "Who has permission to trigger exports?" - - **If docs mention role-based access**: "Any authenticated user" / "Admin/owner only" / "Configurable per workspace" - - **If auth not documented**: "Any authenticated user" / "Role-restricted" / "To be determined" + - **If docs mention role-based access**: "Any authenticated user" / "Only admin/owner roles" / "Configurable per workspace" + - **If auth not documented**: "Any authenticated user" / "Role-restricted (specify roles)" / "To be determined" Update the document with any answers the user provides. If the user declines to answer, move on without pressing. @@ -283,21 +297,19 @@ These examples demonstrate how classification and the active documentation steps **Input:** "Data export is fast and reliable" **Classification:** Ambiguous — has both product and architecture aspects. -Instead of asking "which document?", use `ask_operator` to decompose. After reading existing docs (Step 0) and seeing that PRODUCT.md already mentions "reports" as a user-facing feature and ARCHITECTURE.md discusses latency targets for other services: - -Use `ask_operator`: +Instead of asking "which document?", use the `question` tool to decompose. After reading existing docs (Step 0) and seeing that PRODUCT.md already mentions "reports" as a user-facing feature and ARCHITECTURE.md discusses latency targets for other services: +Use the `question` tool: - Question 1: "Is 'fast and reliable' a promise to users or a system design requirement?" - - Option 1: "User-facing promise" - - Option 2: "System design requirement" - - Option 3: "Both" + - Option 1: "User-facing promise (add to PRODUCT.md like other user benefits)" + - Option 2: "System design requirement (add to ARCHITECTURE.md with latency targets)" + - Option 3: "Both - it's a user promise AND a technical constraint" - Question 2: "Does 'fast' have a concrete target?" - - Option 1: "Under 5 seconds" - - Option 2: "Different target" + - Option 1: "Yes - under 5 seconds (similar to report generation target)" + - Option 2: "Yes - but different target (specify)" - Option 3: "No specific target yet" If the user selects "Both" and "under 5 seconds", this produces two updates: - - **PRODUCT.md:** Data export completes in under 5 seconds for typical datasets (up to 10k rows). - **ARCHITECTURE.md:** The export pipeline must meet a 5-second latency target for datasets up to 10k rows. @@ -307,16 +319,15 @@ If the user selects "Both" and "under 5 seconds", this produces two updates: After updating, scribe reads the other documents and finds that PRODUCT.md has no mention of notifications as a user-facing feature, but does mention "alerts" in a different context. IMPLEMENTATION.md describes other third-party integrations using specific provider names. -Use `ask_operator`: - +Use the `question` tool: - Question 1: "Should PRODUCT.md describe notifications as a user-facing capability?" - - Option 1: "Add as a user-facing feature" - - Option 2: "Fold into existing alerts" - - Option 3: "Internal only" + - Option 1: "Yes - add as new notifications feature (users receive updates via email/SMS/push)" + - Option 2: "Yes - integrate with existing 'alerts' feature (notifications are how alerts are delivered)" + - Option 3: "No - notifications are internal only, not user-facing" - Question 2: "Should IMPLEMENTATION.md specify the notification providers?" - - Option 1: "Yes — name the provider" - - Option 2: "Yes — different providers" - - Option 3: "Not yet" + - Option 1: "Yes - using [provider] (similar to how we document other integrations)" + - Option 2: "Yes - but different providers (specify which)" + - Option 3: "Not yet - still evaluating options" ### Gap Detection (Step 5) @@ -324,52 +335,48 @@ Use `ask_operator`: After updating, scribe scans the section and identifies gaps. From reading ARCHITECTURE.md (Step 0), scribe notices other sections mention security constraints and timeout values. IMPLEMENTATION.md describes storage mechanisms for other sensitive data. -Use `ask_operator`: - +Use the `question` tool: - Question 1: "What happens when a refresh token is revoked?" - - Option 1: "Signed out immediately" - - Option 2: "Signed out at next request" + - Option 1: "User signed out immediately (like session invalidation elsewhere in the system)" + - Option 2: "User signed out at next request (deferred enforcement)" - Option 3: "Configurable per deployment" - Question 2: "Is there a maximum session duration?" - - Option 1: "30 days" - - Option 2: "Different duration" - - Option 3: "No hard limit" + - Option 1: "Yes - 30 days (similar to other timeout values in the docs)" + - Option 2: "Yes - but different duration (specify)" + - Option 3: "No hard limit - refresh tokens last indefinitely until revoked" - Question 3: "How are tokens stored on the client side?" - - Option 1: "Same as other secrets" - - Option 2: "Different storage" - - Option 3: "Client decides" + - Option 1: "Same as [other sensitive data] - in secure storage" + - Option 2: "Different approach (specify storage mechanism)" + - Option 3: "Client implementation decision - not specified in architecture" ## Error Handling ### Document does not exist -If the target document does not exist, use `ask_operator` to ask the user if they want to create it, with context about what type of document it is: +If the target document does not exist, use the `question` tool to ask the user if they want to create it, with context about what type of document it is: Question: "The [DOCUMENT].md file does not exist. Should I create it?" Options: - -- "Yes, create it" -- "Use a different document" +- "Yes, create [DOCUMENT].md (will contain [brief description based on document type])" +- "No, use a different document instead" ### Content conflicts -If the new content contradicts existing content, use `ask_operator` to flag it with specific options: +If the new content contradicts existing content, use the `question` tool to flag it with specific options: Question: "This conflicts with existing content in [DOCUMENT].md: '[existing content]'. How should I resolve this?" Options based on the nature of the conflict: - -- "Replace with the new content" -- "Keep both, with clarification" -- "Merge the two" +- "Replace old content with new (new information supersedes old)" +- "Keep both with clarification (they represent different aspects/contexts)" +- "Merge the two (combine into comprehensive description)" ### Unclear scope -If the input is too broad or vague to place in a specific document, use `ask_operator` to narrow it down: +If the input is too broad or vague to place in a specific document, use the `question` tool to narrow it down: Question: "I'm not sure where '[user input]' belongs. Can you help me place it?" Options based on what aspects you can detect: - -- "PRODUCT.md" -- "ARCHITECTURE.md" -- "IMPLEMENTATION.md" -- "Multiple documents" +- "PRODUCT.md ([specific user-facing aspect you detected])" +- "ARCHITECTURE.md ([specific structural aspect you detected])" +- "IMPLEMENTATION.md ([specific technical aspect you detected])" +- "Multiple documents (it spans several concerns)" diff --git a/tests/unit/corbits-skills-catalog.test.ts b/tests/unit/corbits-skills-catalog.test.ts index dde864d55..be47f1857 100644 --- a/tests/unit/corbits-skills-catalog.test.ts +++ b/tests/unit/corbits-skills-catalog.test.ts @@ -277,6 +277,18 @@ test("interview skill is 1:1 with GaaS interview", async () => { expect(skill).not.toContain("## Acknowledgment"); }); +test("scribe skill is 1:1 with GaaS scribe", async () => { + const skill = await Bun.file(join(pluginRoot, "skills/scribe/SKILL.md")).text(); + expect(skill).toContain("tools:\n - question"); + expect(skill).toContain("Using the Question Tool"); + expect(skill).toContain("AskUserQuestion"); + expect(skill).toContain("the `question` tool"); + expect(skill).not.toContain("ask_operator"); + expect(skill).not.toContain(USER_INVOCABLE_FALSE); + expect(skill).not.toContain(DISABLE_MODEL_INVOCATION); + expect(skill).not.toContain("## Acknowledgment"); +}); + test("create-issue is Linear-first without restated MCP tool contracts", async () => { const skill = await Bun.file(join(pluginRoot, "skills/create-issue/SKILL.md")).text(); expect(skill).toContain("mcp__linear__"); @@ -409,6 +421,7 @@ test("native-integration maps GaaS tool names and parks Corbits extras", async ( expect(skill).toContain("Do not fork the GaaS opsh body"); expect(skill).toContain("Do not fork the GaaS pull-request-review body"); expect(skill).toContain("Do not fork the GaaS refactor body"); + expect(skill).toContain("Do not fork the GaaS scribe body"); expect(skill).toContain("prove"); });