From 3e6e6a6b7780e0fd90078e3c71dc2632aa027158 Mon Sep 17 00:00:00 2001 From: Himamshu Soni Date: Thu, 27 Aug 2026 15:13:57 +0530 Subject: [PATCH] feat(skills): add docs skill and plugin manifest (#10) --- .oxcode-plugin/marketplace.json | 7 + plugins/docs/.oxcode-plugin/plugin.json | 13 ++ plugins/docs/skills/docs/SKILL.md | 164 ++++++++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 plugins/docs/.oxcode-plugin/plugin.json create mode 100644 plugins/docs/skills/docs/SKILL.md diff --git a/.oxcode-plugin/marketplace.json b/.oxcode-plugin/marketplace.json index 35102f7..e7bb214 100644 --- a/.oxcode-plugin/marketplace.json +++ b/.oxcode-plugin/marketplace.json @@ -61,6 +61,13 @@ "description": "Review public interfaces, endpoints, and library APIs for omissions, breaking changes, and caller ergonomics.", "category": "development", "author": "Oxlo.ai" + }, + { + "name": "docs", + "source": "./plugins/docs", + "description": "Document what code actually does rather than what it was supposed to do, and report where code and docs disagree.", + "category": "development", + "author": "Oxlo.ai" } ] } diff --git a/plugins/docs/.oxcode-plugin/plugin.json b/plugins/docs/.oxcode-plugin/plugin.json new file mode 100644 index 0000000..f3c4baf --- /dev/null +++ b/plugins/docs/.oxcode-plugin/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "docs", + "version": "1.0.0", + "description": "Document what code actually does rather than what it was supposed to do, and report where code and docs disagree.", + "author": { + "name": "Oxlo.ai" + }, + "license": "MIT", + "homepage": "https://github.com/Cyborg-Network/oxcode-skills", + "requires": { + "oxcode": ">=0.4.0" + } +} diff --git a/plugins/docs/skills/docs/SKILL.md b/plugins/docs/skills/docs/SKILL.md new file mode 100644 index 0000000..2295523 --- /dev/null +++ b/plugins/docs/skills/docs/SKILL.md @@ -0,0 +1,164 @@ +--- +name: docs +command: docs +label: Documentation +hint: Document what code actually does and report where code and docs disagree +description: >- + Document what code actually does rather than what it was supposed to do. Use + when writing or reviewing documentation, READMEs, docstrings, or architecture + notes from source code. +category: development +order: 70 +icon: book-open +capability: Deep analysis +workspace: required +tools: chat +--- + +You are documenting code. Your job is to document what the code actually does +rather than what it was supposed to do, to ground every behavioral claim in +verified source lines, and to report every disagreement between existing docs +and actual behavior as a primary finding. + +Documentation written by an agent is usually a restatement of function names, +docstrings, or aspirational comments. The value of documentation is in +discovering what the system actually does at runtime, highlighting surprising +guarantees or edge cases, and exposing where the implementation contradicts the +written specification. + +## Ground every statement in the code + +Every behavioural claim in your documentation must cite a concrete code reference +(`file:line` or exact symbol definition). + +- **Inspect implementation, not names**: Never base documentation on the function + name, parameter label, or pre-existing docstrings. Function names express intent; + source code expresses reality. + If a function is named `fetchAndValidateUser(id)`, inspect the implementation: + does it actually validate, does it return cached data, or does it silently + swallow network timeouts? +- **Cite evidence for every claim**: If you assert that a parameter is optional, a + return value is cached, or an error is thrown, cite the exact `file:line` that + proves it. +- **No claim without source proof**: If you cannot point to the line of code that + produces the behaviour, you have a guess rather than a documented fact. State + unverified behavior as an explicit boundary rather than assuming standard + behavior. + +## Report disagreements as findings (Never resolve them silently) + +When existing documentation (README, JSDoc/docstrings, OpenAPI specs, or inline +comments) contradicts actual code behavior, report the disagreement explicitly +as a **Disagreement Finding**. + +Never resolve a contradiction quietly: +- If you document what the README says when the code disagrees, you document an + imaginary system. +- If you silently update the documentation to match buggy code, you launder an + implementation defect into canonical documentation. + +Report every disagreement with: +- **Doc Claim**: What the existing doc or comment asserts (quote and file location). +- **Code Reality**: What the code actually executes (with `file:line` citation). +- **Risk**: Why silent resolution is dangerous (e.g., laundering a defect, breaking caller expectations). + +## Document the surprising, skip the obvious + +The single most common defect in AI-generated documentation is tautological +filler. Nobody needs a sentence stating that `getUser` gets a user. They need to +know that it returns `null` rather than throwing, and that it caches for 60 +seconds. + +Enforce the **Skip-the-Obvious Rule**: omit trivial restatements of identifiers +and focus exclusively on runtime semantics, non-obvious guarantees, and edge cases. + +### Obvious vs. Surprising Examples + +| Operation | ❌ Obvious (Skip / Omit) | ✅ Surprising & Essential (Document) | +|---|---|---| +| `getUser(id)` | "Retrieves a user by their user ID." | "Returns `null` rather than throwing on 404 (`user.ts:42`), caches responses in-memory for 60 seconds (`user.ts:48`), and silently serves stale data if the database times out (`user.ts:55`)." | +| `validateEmail(email)` | "Validates the format of an email address string." | "Trims whitespace (`validator.ts:12`), accepts '+' sub-addressing (`validator.ts:15`), rejects punycode/IDN domains (`validator.ts:18`), and enforces a 254-character maximum (`validator.ts:22`)." | +| `setPort(port)` | "Sets the port number for the server." | "Coerces string inputs to integers (`server.ts:30`), throws `RangeError` if port is <= 1024 without root privileges (`server.ts:34`), and does not restart active listeners (`server.ts:40`)." | +| `calculateTotal(items)` | "Calculates the total price of the items." | "Modifies `items` in-place by attaching tax breakdown objects (`calc.ts:60`), applies discounts before tax (`calc.ts:68`), and rounds fractional cents using banker's rounding (`calc.ts:74`)." | + +Focus documentation on the non-obvious aspects callers must understand: +- **Return semantics**: `null` vs `undefined` vs throwing vs returning an empty collection on missing data. +- **Caching and TTL**: In-memory vs external cache, expiration duration, and invalidation triggers. +- **Error handling**: Swallowed exceptions, fallback values, custom error types, and unhandled rejections. +- **Mutations and side effects**: In-place modification of arguments, disk/network I/O, and global state updates. +- **Concurrency & idempotency**: Thread-safety guarantees, locking behavior, and retry side effects. +- **Implicit defaults & coercion**: Type coercion, environment variable fallbacks, and hidden timeout limits. + +## Say what is not covered (Name undocumented areas) + +A doc that silently omits error paths, untested branches, or unverified +subsystems reads as if there are none. + +Always include an explicit **Undocumented Areas & Boundaries** section that names: +- Omitted error paths and uninspected exception handlers. +- External service dependencies whose failure modes were not verified. +- Uninspected configuration flags or environment variable overrides. +- Untested or unreachable code branches. + +State boundaries plainly: +`"Cannot verify token refresh behavior because authentication logic delegates to external service in 'auth_client.py', which was outside the inspected files."` +`"The error recovery path for WebSocket disconnects in 'stream.ts:88-102' was not traced and is left undocumented."` + +## Write for someone who has not read the code + +Write for someone who has not read the code, which is the only reader +documentation has. + +- **Focus on observable contracts**: Describe inputs, outputs, prerequisites, + invariants, and observable side effects. +- **Avoid private implementation trivia**: Do not refer to internal temporary + variable names or private loop counters unless they directly dictate + caller-facing behavior. +- **Use plain, direct statements**: No conversational filler, no hedging, and + no speculative descriptions of developer intent. + +## What is NOT documentation + +- Paraphrasing code line by line into English prose. +- Restating type signatures or parameter lists without explaining operational semantics. +- Speculating on intended architecture or future plans not present in the code. +- Silently resolving ambiguities or guessing past missing context. + +## Worked example + +Consider documenting a user profile retrieval function: + +> **1. Documented Behaviour & Contracts:** +> +> `fetchUserProfile(userId, options)` (`src/users/profile.ts:24`) +> - Retrieves user profile data from primary database (`src/users/profile.ts:32`). +> - Accepts optional `options.includeDeleted` (boolean, defaults to `false` at `src/users/profile.ts:26`). +> - Returns `null` when user does not exist or when `is_deleted` is `true` and `includeDeleted` is `false` (`src/users/profile.ts:40-43`). +> +> **2. Surprising Behaviours & Invariants:** +> - **In-memory Caching**: Caches user objects in an LRU cache for 120 seconds (`src/users/profile.ts:35`). The cache key ignores `options.includeDeleted`, so requesting a profile with `includeDeleted: false` followed by `includeDeleted: true` within 120 seconds returns the cached non-deleted profile (`src/users/profile.ts:37`). +> - **Silent Fallback on Timeout**: If the database query exceeds 500ms, catches the timeout error and returns `{ status: "degraded", user: null }` instead of throwing (`src/users/profile.ts:50-54`). +> - **Input Mutation**: Normalizes `userId` to lowercase by mutating `options.normalizedId` in-place (`src/users/profile.ts:28`). +> +> **3. Disagreements / Doc Drift (Findings):** +> - **Doc Claim**: `README.md:88` states `"fetchUserProfile throws UserNotFoundError if the requested ID does not exist."` +> - **Code Reality**: `src/users/profile.ts:41` explicitly returns `null` rather than throwing when the record is not found. +> - **Risk**: Callers relying on `try/catch` blocks will fail to detect missing users, leading to `TypeError: Cannot read property of null` downstream. +> +> **4. Undocumented Areas & Boundaries:** +> - **Uninspected Dependency**: The eviction policy and memory bounds of the LRU cache instance in `src/cache/lru.ts` were not inspected. +> - **Omitted Error Path**: Database connection failures other than `TimeoutError` (such as authentication or network disconnects) bubble up as unhandled rejections; exact error types are undocumented. + +## Output + +Structure your documentation output as follows: + +1. **Documented Behaviour & Contracts**: Function/endpoint signatures with + concrete `file:line` references for every behavioural claim. +2. **Surprising Behaviours & Invariants**: Edge cases, return semantics, + caching/TTL, error handling, input mutations, and concurrency constraints. +3. **Disagreements / Doc Drift**: Identified contradictions between existing + docs/comments and code reality, formatted as findings with Doc Claim, Code + Reality, and Risk. +4. **Undocumented Areas & Boundaries**: Explicitly named gaps, uninspected + dependencies, and omitted error paths.