Skip to main content
A standard is an agreed-upon, documented set of rules or criteria that ensures consistent, compatible, and high-quality results across people, systems, or products.
Aligning a team on standards—and following them—is hard. Many teams end up with wikis and Markdown files that nobody reads or maintains. With AI coding assistants, this problem becomes even more critical. Let’s see how we can make written documentation useful again with Packmind.
Read more about the anatomy of a Packmind standard in the dedicated section.

Create a standard from your codebase

You need to connect your MCP server to your IDE. See the setup guide: Get started with the MCP server.
  1. Open your IDE and your coding assistant in agentic mode.
  2. For this demo, we will create a language-agnostic standard. (You can also target a specific language or framework.)
  3. Type this prompt:
Analyze our codebase and create a Packmind standard about error handling.

How it works

The AI agent will automatically follow the standard creation workflow which guides it through:
  1. Understanding your request - The agent clarifies what standard you want to create and gathers appropriate context from your codebase
  2. Drafting the standard - The agent creates a draft with name, description, and rules, iterating with you for feedback
  3. Finalization - Once you’re satisfied, the agent validates the standard and calls the packmind_create_standard MCP tool
Your new standard will be available in the Packmind web app, in the Standards panel.
The workflow ensures consistent, high-quality standards by guiding the AI through best practices. You can provide feedback at any step, and the agent will refine the standard before submitting it.

Create a standard with a coding agent

When using a coding agent like Claude Code, you can invoke the /packmind-create-standard skill to get guided assistance through the entire standard creation process.

Using the skill

  1. Open your coding agent (e.g., Claude Code)
  2. Type /packmind-create-standard to invoke the skill
  3. Describe the standard you want to create
The agent will guide you through:
  1. Understanding your needs — Clarifying what problem the standard solves and where it applies
  2. Writing rules — Helping you craft clear, actionable rules following best practices
  3. Creating the playbook — Generating a JSON file with your standard definition
  4. Review — Showing you the complete standard for approval
  5. Submission — Creating the standard via the CLI
The skill workflow is interactive and iterative. The agent will ask clarifying questions and help you refine your rules before creating the standard.

Create a standard from the CLI

You can also create standards directly using the Packmind CLI with a JSON playbook file.
packmind-cli standards create ./my-standard.json

Playbook format

The playbook file defines your standard structure:
{
  "name": "Error Handling",
  "description": "Ensure errors are handled predictably with context.",
  "scope": "Applies to all services",
  "rules": [
    {
      "content": "Validate inputs at boundaries and fail fast"
    },
    {
      "content": "Preserve context when rethrowing errors",
      "examples": {
        "positive": "throw new AppError('Failed', { cause: e });",
        "negative": "throw new Error('Failed');",
        "language": "TYPESCRIPT"
      }
    }
  ]
}

Required fields

FieldDescription
nameStandard name displayed in the web app
descriptionContext and purpose of the standard
scopeWhere the standard applies (e.g., “TypeScript files”, “React components”)
rulesArray of rules (at least one required)

Rule format

Each rule requires a content field that starts with an action verb. Examples are optional but recommended.
FieldRequiredDescription
contentYesRule description (max ~25 words, starts with verb)
examples.positiveNoCode showing correct implementation
examples.negativeNoCode showing incorrect implementation
examples.languageNoLanguage for syntax highlighting
Supported languages: TYPESCRIPT, TYPESCRIPT_TSX, JAVASCRIPT, JAVASCRIPT_JSX, PYTHON, JAVA, GO, RUST, CSHARP, and more.
Use the CLI directly when you have standards defined as files in your repository or want to automate standard creation. See CLI: Standard Command for more details.

Create a standard from the web app

  1. Go to the Standards panel.
  2. Click to create a new standard.
  3. Fill in the following fields:
  • Name — a short title that explains the topic (e.g., “Frontend code conventions”, “DDD architecture”).
  • Description — context and benefits, for both coding assistants and developers.
  • Rules — a list of issues to avoid and coding rules to follow so the code complies with the standard.

Example

**Standard**: Error Handling

**Description**:
Ensure errors are handled predictably, with context, safety, and actionable feedback.
Non-goals: don't use exceptions for control flow; don't log the same error at multiple layers; don't expose stack traces or internals in user-facing messages.

**Checklist for reviews**: validated inputs; no empty catch; structured errors; cause preserved; safe logs; careful retries; actionable responses.

**Scope**: Applies to all services, CLIs, UIs, and libraries.

**Rules**

1) Validate inputs at boundaries; fail fast

Bad (JavaScript):
// UI handler
submit(order); // accepts anything; crashes deeper

Good (JavaScript):
import { z } from "zod";
const Order = z.object({ id: z.string().min(1), items: z.array(z.string()).nonempty() });
const parsed = Order.safeParse(payload);
if (!parsed.success) {
  throw new ValidationError("Invalid order", { issues: parsed.error.issues });
}
submit(parsed.data);

2) Avoid swallowing errors; surface or handle them explicitly

Bad (JavaScript):
try {
  processPayment(tx);
} catch (e) {
  // ignored; system appears "successful"
}

Good (JavaScript):
try {
  await processPayment(tx);
} catch (e) {
  if (e instanceof PaymentGatewayError) {
    logger.warn("Payment failed", { txId: tx.id, code: e.code });
    throw new PaymentFailed("Could not process payment", { cause: e });
  }
  throw e; // unknown error, bubble up
}

3) Preserve context when rethrowing

Bad (JavaScript):
try {
  await repo.save(user);
} catch (e) {
  throw new Error("Save failed"); // loses original cause
}

Good (JavaScript):
class PersistenceError extends Error {
  constructor(message, options) { super(message, options); this.name = "PersistenceError"; }
}
try {
  await repo.save(user);
} catch (e) {
  throw new PersistenceError("Save failed: User", { cause: e });
}

4) Use structured, domain-specific error types

Bad (JavaScript):
throw new Error("Not found");

Good (JavaScript):
class NotFoundError extends Error {
  constructor(kind, key, options) {
    super(`${kind} not found`, options);
    this.name = "NotFoundError";
    this.kind = kind; this.key = key;
  }
}
throw new NotFoundError("User", userId);

5) Log safely and meaningfully (no secrets; include identifiers)

Bad (JavaScript):
console.error("Auth failed for", credentials.password); // leaks secret

Good (JavaScript):
logger.error("Auth failed", { userId, ip, reason: "invalid_credentials" }); // no secret/PII

6) Retry deliberately with backoff only for safe, transient operations

Bad (JavaScript):
// Blind retry of a non-idempotent call
for (let i = 0; i < 5; i++) {
  await chargeCard(request); // may double-charge
}

Good (JavaScript):
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
for (let attempt = 0; attempt < 3; attempt++) {
  try {
    const res = await fetch(url, { method: "GET" }); // idempotent
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    break;
  } catch (e) {
    if (attempt === 2) throw new CacheUnavailable("Timed out", { cause: e });
    await sleep(2 ** attempt * 200); // exponential backoff
  }
}

7) Return actionable messages to callers; hide internals

Bad (JavaScript/JSON):
{ "error": "TypeError: Cannot read properties of undefined (reading 'email') at UserService.js:142:17" }

Good (JavaScript/JSON):
{ "error": { "code": "USER_NOT_FOUND", "message": "The user does not exist.", "requestId": "c1a9..." } }