Author: Jahdunsin Osho

  • How to Build a Content Engine for Slop-Free Content

    How to Build a Content Engine for Slop-Free Content

    As AI has made product development faster, documentation, educational content, sales material, and marketing pages fall behind while the knowledge needed to update them spreads across pull requests, internal documents, Slack, support conversations, and the people building the product.

    AI can produce a draft quickly, but that speed saves little time when a writer still has to reconstruct the context and correct the same quality issues before every publication.

    A content engine gives that knowledge a repeatable path to finished content. It maintains context, turns ideas into drafts, checks their quality, and routes corrections back to the part that needs to improve.

    As those corrections accumulate and models improve, a content engine lets you move from an idea to publishable content in less time.

    This guide explains what it takes to build one. It draws from Morning Brew’s content engine and a demand-led engine I’ve been building at TinyRocket for the past few months.

    Start with a Goal

    A content engine starts with a business goal.

    The goal determines what your content engine needs to know, what it does with that knowledge, where you decide, and what a good result looks like.

    If your goal is to keep documentation aligned with your product, your content engine can capture signals about product changes and customer feedback. It might receive pull requests, changelogs, support questions, and existing documentation as inputs. It can then identify the pages affected by a code change and produce a proposed list of updates for a technical writer to verify.

    That’s a documentation maintenance content engine.

    If your goal is to build topical authority for a developer tool, your engine can search forums like Reddit and Hacker News for problems developers discuss that the product solves. It can turn supported problems into content ideas and group them into themes so your content covers each problem space in depth.

    That’s a demand-led content engine for building topical authority. This is the type of engine I’ve been building at TinyRocket.

    Morning Brew’s goal was to turn employee expertise into credible public content, expanding the company’s distribution. Their engine identifies ideas inside the company, draws out the relevant experience, and prepares the result for publication without asking each employee to become a full-time creator.

    That’s an employee advocacy content engine.

    All three engines use AI agent skills and practices to turn existing knowledge into content. But their inputs, decisions, and outputs differ because their goals differ.

    Once your goal is clear, you can decide what the engine must know and which agents, skills, checks, and workflows it needs to turn that knowledge into finished content.

    What Is a Content Engine?

    A content engine combines AI agents and reusable skills with the scripts, integrations, quality checks, repositories, and human decisions needed to turn company knowledge into finished content.

    Each agent or skill performs a defined job and produces something you or the next step can use. An ideation agent might produce ideas for you to review. A writing agent turns approved material into content. Quality checks evaluate the result before publication.

    The agents, skills, checks, and workflows you need depend on your goal and how your team works.

    Alex Lieberman built Morning Brew’s content engine using a combination of agent-specific skills. Their implementation connects skills that scan internal and external sources for ideas, interview an employee, draft in that person’s voice, review the result, and prepare the content for distribution.

    A demand-led engine uses a different workflow. It can connect research, briefing, angle development, outlining, writing, and review, then use a repository to keep the content, intermediate work, review findings, and approved changes available to each step.

    There’s no one way to build a content engine. Each agent, skill, or check should have a defined input, perform a bounded task, and produce an output you or the next step can use.

    Build Persistent Context

    When an agent starts a task without persistent project context, it doesn’t carry its understanding from one piece to another.

    So, your content engine needs a persistent reference for the product or company knowledge it will use repeatedly. This context could include what your product does, the problems it solves, how you position it, who the relevant audiences are, and the content strategy guiding what you publish.

    Without that reference, you have to explain the same product history, audience assumptions, and strategic choices each time you start a new piece.

    You can create context files in your workspace and reference them in your AGENTS.md (for Codex, Pi, Cursor) or CLAUDE.md (for Claude Code) file.

    A PRODUCT.md file could document the problem the product solves, its capabilities and limitations, category, positioning, and a list of approved and banned claims. An AUDIENCE.md file could describe the roles involved in buying or using the product, the problems each audience handles, what they already know, and the language they use.

    Together, these files give research, planning, writing, and review agents cohesive knowledge to work with.

    Persistent context should contain knowledge that applies across multiple pieces. Recent pull requests, community conversations, and other changing information can remain in the research for the current piece unless they establish knowledge later content will reuse. Keeping that boundary allows the engine to reuse stable knowledge without treating old research as current information.

    The context needs maintenance. You’d usually notice outdated context through an inaccurate brief or draft. Update it whenever the product definition, audience, positioning, or strategy materially changes, or build a workflow that flags possible changes by pulling from PRs, ADRs, and team conversations. Verify those changes before they become persistent context used by later steps.

    In addition to persistent context, you need knowledge sources that continuously bring current information and new ideas into the engine.

    Add a Research and Ideation Workflow

    The research and ideation workflow defines where to look, what information to extract, and how to turn the findings into content ideas.

    To build one, create a skill that points your agent to the sources where you want to generate ideas and guides it on how to turn the findings into usable ideas.

    Your goal determines the sources. If your goal is to create demand-led developer education, use sources such as Reddit, Hacker News, GitHub discussions and issues, search behavior, support questions, customer conversations, and places where developers describe problems in their own words.

    For an employee advocacy workflow, your sources would be internal documents, meeting notes, Slack conversations, and project updates. A documentation maintenance workflow would use product changes, pull requests, changelogs, support questions, and existing documentation.

    Instruct the research skill to retrieve relevant material and preserve the source. For a demand-led engine, the skill should extract the problem being discussed, the language developers use to describe it, the available evidence, its relevance to the product, and the related subject area.

    The ideation skill can then turn supported problems into questions your target audience would actually ask. Generating ideas as questions prompts you to judge whether your target audience would actually ask them. You can instruct the skill to exclude ideas that lack evidence, fall outside the product’s expertise, or duplicate an existing idea.

    Define what a useful idea should contain for your goal. That might include its original source, supporting context, relevance to your audience, or the employee whose expertise it draws from. The output should give you enough information to approve, reject, or refine the idea before it moves forward.

    This is the first human checkpoint in your content engine. Once you approve an idea, pass it and its supporting material to the next step in your workflow.

    Define Human Checkpoints

    You need a checkpoint wherever an agent produces something that could cause a failure for every step that follows.

    For example, if you approve an inaccurate idea, every later step that uses it will carry the problem forward, which only creates more work down the line.

    A checkpoint allows you to review an output, make a decision, or provide knowledge the agent can’t infer. What you review depends on the engine you are building. You could verify the documentation affected by a product change, choose which employee idea is worth developing, review the structure proposed for a piece of content, or confirm that an output represents the intended argument accurately.

    At each checkpoint, review the output before the next step uses it. The output could be a selected idea, proposed documentation changes, captured expert context, a content structure, or developed content. Confirm that it contains the right information and represents your intended direction before allowing it to move forward.

    One required checkpoint we created for the demand-led content engine is the grilling checkpoint. We created an internal skill called angle-grilling, which is invoked before content is developed. The agent uses this skill to ask you about the article’s unique angle and capture context it can’t infer from research. This can include the reasoning behind a position, firsthand experience, relevant examples, operational details, and trade-offs.

    To create your checkpoints, identify where an output could cause problems for the steps that follow. Decide what you need to verify, choose, or contribute at that point, then define what the next action is after you approve its output.

    Build a Template Library

    A template gives your agent guidance for introducing context, developing points, placing examples, and leading the reader toward the intended outcome. Defining that progression early reduces structural rework after the content has been developed.

    Start your library with existing templates. If you’re creating technical content, The Good Docs Project provides templates for concepts, how-to guides, reference content, API documentation, and other technical documentation needs. You can adapt the relevant structures to your content goal and audience.

    You can also create custom templates from existing content with a similar purpose.

    We built a skill that takes 3-4 articles with a similar purpose, identifies how each one structures and develops its points, compares their strengths and weaknesses, and generates a reusable template to guide similar content.

    After generating your templates, instruct the agent responsible for planning or developing the content to apply the matching template whenever it handles something similar.

    Build a Writing Agent

    The writing agent turns your approved material into content using the relevant context, template, voice, and writing rules.

    Build your writing agent in five steps:

    1. Specify its input. The agent could receive an approved idea and research, an employee interview, proposed documentation changes, or another output from an earlier step.

    2. Connect the relevant context. Give it access to the persistent product, company, and audience knowledge required for the task.

    3. Apply a template. The template guides how the content introduces context, develops its points, places examples, and leads the reader toward the intended outcome.

    4. Define the voice and writing rules. A style guide can define requirements such as terminology, point of view, and prohibited language. A voice profile can capture patterns that are harder to express as rules, including sentence rhythm, paragraph length, vocabulary, tone, and how examples are introduced.

    Add a small set of approved examples so the agent can see how those instructions appear in finished content. Choose examples with a similar content type when possible because a tutorial, guide, and opinion article can share the same voice while developing their ideas differently.

    1. Define the output and handoff. Specify what the agent must produce, then pass that output to a human checkpoint when you need to review its substance or to the quality gate when it’s ready for automated review.

    At TinyRocket, our writing skill brings the approved material, persistent context, template, voice profile, writing rules, and sample content together. It instructs the agent to develop the content in the intended voice, address the reader directly, support claims, and preserve the direction established in earlier checkpoints.

    Add Quality Gates for Automated Review and Editing

    Even with extensive instructions, AI-generated content can still contain quality issues. But fixing them yourself would undo the time savings you built the content engine for, which is why you need a quality gate.

    Build your quality gate in three steps:

    1. Define objective quality standards. Write each standard so its meaning can be evaluated consistently. Rather than say, “Use a professional tone,” specify what that means, such as addressing readers directly, defining unfamiliar terms, and avoiding slang that obscures the explanation.

    2. Choose the appropriate review method. Use deterministic checks when a problem has a fixed, identifiable form. Vale can enforce terminology and language rules, while Lychee can check links. Use agent review for standards that require contextual judgment, such as whether a claim has sufficient support or a recommendation explains its reasoning.

    3. Make the review a required gate. The gate must block the content or warn you when it doesn’t meet the standards. At TinyRocket, these checks run locally and in the GitHub CI/CD workflow. Outside a Git environment, you could create a required review skill at the appropriate checkpoint in your content engine.

    The implementation can vary. What matters is that every piece is evaluated against the defined standards before it reaches final editorial review.

    Train The Agent with Your Preferences

    The content can still contain quality issues or writing that doesn’t align with your brand or doesn’t quite sound like you. Do the final review and edit those parts before publication.

    Your final edits provide feedback on what the engine should do differently next time. Instruct the agent to compare its version with your changes and deduce the reasoning behind those edits, then review those deductions before they become guidance for later work.

    This helps your content engine improve each time you use it instead of requiring the same corrections in every draft.

    Use your edits to improve the engine in four steps:

    1. Edit the content. Make the changes required to express the intended ideas, represent the approved sources accurately, and align the writing with your preferences and brand. Use a workflow that preserves enough history for the agent to inspect what changed.

    2. Instruct the agent to analyze your edits. Ask it to compare its version with yours, identify the substantive differences, and deduce the reasoning behind each change. You could create a skill that performs this comparison and proposes reusable lessons.

    If your content lives in Git, the version history already preserves what the agent wrote and how it was edited.

    1. Review and approve deductions that represent your reasoning correctly. Some edits could support several explanations, so an agent may infer a plausible reason that wasn’t the reason you made the change. Correct or reject the ones that don’t.

    2. Apply or store the approved lessons. Update a skill when the lesson changes how the agent should perform a task or move through a workflow. Update a quality check when the lesson describes an issue the review process should catch. Update a template when it changes the information or structure an output requires.

    When the lesson doesn’t fit a skill, quality check, or template, store it in a lessons file the agent consults during future writing and review. This file is particularly useful for context-dependent decisions, such as when to override one rule or prioritize one preference over another.

    Each edit improves the current piece. Turning the reasoning behind approved edits into reusable guidance helps the engine produce content that’s closer to your expectations in future runs.

    Build Your First Content Engine, Then Make It Yours

    You can get started by pointing your preferred agent to this guide and specifying your content goal.

    For each agent, skill, check, or human checkpoint, specify what it receives, the task it performs, the decisions it makes, and what it passes to you or the next step.

    You’ll get a working first engine version with persistent context, an ideation workflow, human checkpoints, quality gates, and a way to carry your preferences into future work. It would come with a lot of instructions, though, so be prepared to review and iterate to adapt it to your needs.

    You’ll need to refine agent instructions, translate your standards into review checks, and improve context coverage, skills, templates, and checkpoints through use. Our demand-led engine is currently a system of 19 agent skills, a template library, context files, and an automated review gate. Building and iterating on that system took about two months.

    If you’d like help adapting the first version to your workflow, you can book a call. Whether you want documentation maintenance, AI search, employee advocacy, social media, or a developer education content engine, I’ll audit how you currently produce content, starting from your goal, and recommend how to build or improve the engine to achieve the result you need.

    It’s free, no strings attached.

  • Content Engineering vs. Technical Writing: What’s the Difference?

    Content Engineering vs. Technical Writing: What’s the Difference?

    The term content engineer means different things depending on who is hiring.

    If you have encountered the term in job postings, community discussions, or vendor content and wondered how it differs from technical writing, you aren’t alone. Many technical writers already do much of what companies describe when hiring content engineers, so the roles can appear to overlap.

    That raises a reasonable question. Is content engineering a new name for technical writing, or does it describe a genuinely different role?

    This article compares the two based on how companies define content engineering in job postings. It examines what each role does, what employers expect, where they overlap, and whether technical writing has ever fully captured the work the role has required.

    By the end, you’ll have a clearer line between what each role produces, where they overlap, why the distinction matters, and who you should hire based on your company’s structure and needs.

    First, here are some common misconceptions about content engineering.

    Misconceptions about Content Engineering

    These are three common ways people define content engineering or describe what the role involves:

    1. A content engineer is an engineer who writes content. The definition is technically accurate in the same way “a software engineer is someone who writes software” is accurate, but it doesn’t tell you what the person actually does.

    By that definition, a mechanical or electrical engineer who writes installation manuals is also a content engineer. The description fits so broadly that it creates confusion about what the person does.

    If a software engineer does software engineering, then a content engineer should do content engineering.

    1. Content engineering is a new name for technical writing. Companies have repeatedly renamed technical writing as a discipline. Titles like content developer, information developer, and knowledge engineer have appeared, and each time the scope stayed the same while only the name changed.

    Mark Baker, author of Every Page is Page One, noted as far back as 2013 that “the constant and uniformly unsuccessful attempts to rename technical writing left many in the field hypersensitive” to yet another name for the same work.

    Many technical writers look at what people describe as the requirements for a content engineer and see things they already do, so the obvious conclusion is that the new role is another name. However, it raises the question of whether technical writing was ever a complete title for the role.

    1. Content engineering is about scaling content production. This is more common within the search marketing and B2B SaaS industry. Some vendors such as AirOps and another content marketing vendor define content engineering exclusively as building AI production pipelines for scaling content.

    In the developer tool space, content goes beyond blog posts. It also includes documentation. Content engineering could involve building drift detection systems, quality gates, review automation, and maintenance workflows.

    That work has nothing to do with producing more marketing pages.

    What a Technical Writer Does

    A technical writer’s primary output is content, including API documentation, integration guides, SDK references, tutorials, release notes, and changelogs.

    They research the product, talk to engineers, test the software themselves, and translate that understanding into content that developers can use.

    Beyond producing new content, technical writers maintain what already exists. When they spot inaccuracies or style issues in shipped content, they update the affected pages. When the product ships a new version, they revise the docs to match. This ongoing maintenance work is a significant part of the role and often takes more time than writing new material.

    Technical writers work within content systems. They open pull requests, follow the review process, and publish through the Docs as Code pipeline. The pipeline itself, however, isn’t their core responsibility. They operate inside the workflow rather than building or maintaining it.

    That said, the industry has been shifting. As companies adopted Docs as Code workflows, roles like documentation engineer emerged. These were people who owned the system for producing and maintaining documentation, rather than the content alone. Some technical writers moved into that work, a shift that predates the current content engineering conversation.

    What a Content Engineer Does

    A content engineer’s primary output is systems, not content. They build the infrastructure that content moves through, including pipelines, automation, quality gates, and workflows.

    Their work can involve building documentation systems, including drift detection that flags outdated docs when product code changes, prose linters, automated reviews in CI, maintenance workflows, and reusable templates that reduce effort per update. This is documentation engineering work.

    However, content engineering also covers marketing content systems, including production workflows, quality enforcement, topic research workflows, and maintenance automation that keep published blog posts and guides aligned with the product as it evolves.

    While documentation engineering covers docs infrastructure, content engineering extends that work to marketing systems as well.

    The Overlap and Difference

    Content engineers and technical writers share the same content environment, tooling, and quality concerns.

    Both roles use the same publishing environment, review process, and quality standards, which is why the distinction can feel blurry, especially in small teams where the same person may write content, maintain workflows, and improve the tooling around publication.

    If the primary responsibility is producing content, that’s technical writing. If the primary responsibility is building and maintaining the systems that content moves through, that’s content engineering.

    A technical writer improves the content inside the workflow. A content engineer improves the workflow itself, including the review rules, automation, quality gates, publishing process, and maintenance systems around the content.

    For practitioners who were already building pipelines, configuring automation, and designing workflows alongside their writing, “technical writer” was never the most accurate description of the full scope.

    Content engineering names that systems work more precisely.

    Deciding Who to Hire

    A technical writer’s job is as valuable as ever. The question is which role gets you to your goal faster, given your team’s structure.

    For teams with significant content volume, building systems that produce and maintain content delivers more leverage than managing each piece manually.

    If you already have a technical writer who’s been building tooling and automation alongside their content work, you could formalize that as their primary responsibility. They already understand the content, and now they’ll own the infrastructure as well.

    If the systems work is complex enough and your writer’s time is better spent on content, hiring a dedicated content engineer is the better move. That way, your writer isn’t split between deadlines and infrastructure, and your systems get the dedicated attention they need to stay reliable.

    Or you outsource the engineering work.

    TinyRocket builds content engineering systems for developer tool companies. Content pipelines, quality automation, drift detection, and production workflows keep the systems work off your team’s roadmap, so they can focus on producing and maintaining content. Whether you have a technical writer who needs systems support or no dedicated content person at all, book a workflow audit to map your current content workflow and identify which parts automation can handle.

  • How We Catch Documentation Drift with Pi and GitHub Actions

    How We Catch Documentation Drift with Pi and GitHub Actions

    According to Linear, teams using AI agents now ship 5x as many pull requests as two years ago, while Cursor’s data shows developers produce 2.5x as much code as 18 months ago.

    More code and faster shipping make documentation drift from the product. Documentation describes one behavior, while code produces another. This hinders adoption, breaks onboarding workflows, and can drive prospective users to competitors or frustrate existing ones.

    Tools such as Mintlify offer features to catch documentation drift and automatically update your docs. However, Mintlify’s implementation may not fit your existing workflow, and it locks you into its platform. This guide shows you how to build the same capability without locking into any specific product.

    This guide walks through the GitHub Actions workflow we use to catch documentation drift on pull requests with Pi, an open source agent harness. You can replicate the workflow on your own repository.

    We’re already running this setup on VectorLint, an open source content review harness we maintain at TinyRocket.

    Let’s get started.

    What You’ll Build

    By the end of this guide, you’ll be able to detect documentation drift in CI. You’ll have three pieces wired together:

    1. A GitHub App installed on the repository that gives the workflow permission to post comments
    2. An agent skill that tells the agent what counts as documentation drift
    3. A GitHub Actions workflow that orchestrates the check on demand, builds the agent’s routing message inline, and posts the result as a PR comment

    Note: The workflow flags documentation drift; it doesn’t create a PR or issue. That’s intentional. There could be false positives where the agent flags drift that isn’t user-facing. Automatically creating a pull request for each false positive only adds review work. You can build a downstream workflow that takes this workflow’s output and creates an issue or PR with an agent.

    Before You Start

    You need a few things in place:

    • A GitHub repository following a Docs as Code approach (documentation alongside the code, for example, /docs or a README markdown file)
    • Owner or member permission on the repository
    • A GitHub account with permission to create GitHub Apps (or an organization where you can create Apps)
    • An API key from an AI provider that Pi supports (Anthropic, OpenAI, Google, and others). This guide uses Amazon Bedrock. If you use a different provider, the only change is the authentication parameters.

    Pi is an open source coding agent that you run from the command line. It’s lightweight, provider-agnostic, and highly customizable, which is why we chose it for this guide. If you want to test the skill before committing it to CI, install Pi locally.

    Note: You can replace Pi with any other agent and get similar results. You’ll need to adapt the setup to how your agent works.

    Step 1: Create the Doc-Drift Skill

    Copy the doc-drift skill from the VectorLint repository into your project at .agents/skills/doc-drift/. The directory contains:

    • SKILL.md: the main instruction the agent follows
    • references/user-facing-criteria.md: defines what counts as a user-facing change
    • references/comment.md: defines the output format for drift reports

    The skill tells the agent to extract user-facing behavioral changes from a PR diff, search the documentation for claims those changes invalidate, and write a report for each finding.

    A user-facing change could be a renamed command-line flag, a new environment variable, a changed config key, or a rewritten error message. The skill ignores internal refactors, test changes, and anything with no observable effect on the user.

    Note: We built this skill for VectorLint, so it has hardcoded scope paths and repository references. To adapt it, change the scope paths and repository name in SKILL.md and update the criteria in references/user-facing-criteria.md to match your product. You can also hand the skill to an agent and ask it to adapt the references to your codebase.

    Step 2: Create and Install a GitHub App

    The workflow needs to post comments on pull requests. You can authenticate with either a personal access token or a GitHub App. A GitHub App is safer because you scope its permissions to exactly what the workflow needs. A personal access token tends to carry more permissions than necessary, which increases the blast radius if it’s ever exposed.

    Use GitHub’s guide on creating a GitHub App and grant it these permissions:

    • Issues: Read & write to post PR comments
    • Pull requests: Read & write for the eyes reaction and gh pr diff
    • Contents: Read for checkout

    After creating the App, grab the App ID and download your private key (a .pem file). Then install the GitHub App on the repository where the workflow runs. You’ll add both values as repository secrets in Step 4.

    Step 3: Build the GitHub Actions Workflow

    Create a file at .github/workflows/doc-drift.yml. Each section below covers one block of this file. The full workflow appears at the end for copy-pasting.

    The Trigger and the Authorization Guard

    To guard against cost and security overhead, a documentation check should only run when someone triggers it on a pull request, not on every push.

    name: Doc Drift Check
    
    on:
      issue_comment:
        types: [created]
    
    jobs:
      authorize:
        name: Check authorization
        runs-on: ubuntu-latest
        # Only run on PR comments that start with /check-docs (skip bots)
        if: |
          github.event.issue.pull_request != null &&
          startsWith(github.event.comment.body, '/check-docs') &&
          !contains(github.event.comment.user.login, '[bot]')
    
        permissions:
          issues: write
          pull-requests: read
          contents: read
    
        outputs:
          authorized: ${{ steps.auth.outputs.authorized }}
    

    The on: issue_comment trigger fires whenever a comment is created. The if: condition narrows triggering to comments on pull requests that start with /check-docs and skips any commenter whose login contains [bot], so bot accounts cannot trigger the workflow. The permissions block grants the minimum access the job needs; write access for comments comes from a GitHub App token (covered below), so GITHUB_TOKEN only needs read access to pull requests.

    To guard against unauthorized reviews, only repository owners and members should be able to trigger the drift check. This limits the cost of running AI models and reduces the surface area for prompt injection.

        steps:
          - name: Generate GitHub App token
            id: app-token
            uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
            with:
              app-id: ${{ secrets.APP_ID }}
              private-key: ${{ secrets.APP_PRIVATE_KEY }}
    
          - name: Check authorization
            id: auth
            uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
            with:
              github-token: ${{ steps.app-token.outputs.token }}
              script: |
                const association = context.payload.comment.author_association;
                if (!['OWNER', 'MEMBER'].includes(association)) {
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.issue.number,
                    body: `@${context.payload.comment.user.login} Only repo owners or members can trigger doc drift checks.`
                  });
                  core.setOutput('authorized', 'false');
                } else {
                  core.setOutput('authorized', 'true');
                }
    

    The step reads author_association from the comment payload and allows OWNER and MEMBER. If the commenter is neither, it posts a rejection comment and sets authorized to false. Otherwise, it sets the output to true, allowing downstream jobs to proceed.

    Why a GitHub App token, not GITHUB_TOKEN: As covered in Step 2, issue_comment triggers on public repositories downgrade GITHUB_TOKEN to read-only. The App token you created in Step 2 bypasses this restriction, so every write step in the workflow uses it instead.

    This mitigates the risk of prompt injection since pull request titles, bodies, and comments are user-controlled strings.

    Note: Running an agent in a workflow carries some security risk. A malicious actor could create a pull request containing instructions to get your agent to expose secrets. To avoid that, only grant the minimum permissions your agents need to run. For more on this, read GitHub’s guide on mitigating cloud agent risk.

    Check Out the PR and Fetch the Diff

    The agent needs the diff to know what changed in the pull request and to check for behavioral changes.

      check-docs:
        name: Check documentation drift
        runs-on: ubuntu-latest
        needs: authorize
        if: needs.authorize.outputs.authorized == 'true'
    
        permissions:
          issues: write
          pull-requests: read
          contents: read
    
        steps:
          - name: Generate GitHub App token
            id: app-token
            uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
            with:
              app-id: ${{ secrets.APP_ID }}
              private-key: ${{ secrets.APP_PRIVATE_KEY }}
    
          - name: React to comment
            uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
            with:
              github-token: ${{ steps.app-token.outputs.token }}
              script: |
                await github.rest.reactions.createForIssueComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  comment_id: context.payload.comment.id,
                  content: 'eyes'
                });
    
          - name: Get PR head SHA
            id: pr
            uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
            with:
              github-token: ${{ steps.app-token.outputs.token }}
              script: |
                const pr = await github.rest.pulls.get({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  pull_number: context.issue.number
                });
                core.setOutput('head_sha', pr.data.head.sha);
    
          - name: Checkout main branch
            uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
            with:
              ref: ${{ github.event.repository.default_branch }}
              path: main
              fetch-depth: 0
    
          - name: Checkout PR branch
            uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
            with:
              ref: ${{ steps.pr.outputs.head_sha }}
              path: pr
              fetch-depth: 0
    
          - name: Setup Node.js
            uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
            with:
              node-version: '22'
    
          - name: Install Pi
            run: npm install -g @earendil-works/pi-coding-agent@0.79.6
    
          - name: Show Pi version
            run: pi --version
    
          - name: Fetch PR diff
            env:
              GH_TOKEN: ${{ steps.app-token.outputs.token }}
            run: |
              DIFF_PATH="$GITHUB_WORKSPACE/pr/.doc-drift-input.diff"
              gh pr diff --repo ${{ github.repository }} ${{ github.event.issue.number }} > "$DIFF_PATH"
              echo "Diff size: $(wc -l < "$DIFF_PATH") lines"
    

    The eyes reaction gives the reviewer immediate feedback that the command landed, before the run finishes. The Get PR head SHA step resolves the pull request’s current head commit, so the checkout targets the right ref.

    The workflow checks out two copies of the repository: main (the default branch, into path: main) holds the doc-drift skill and the current documentation the agent checks against; pr (the pull request’s head commit, into path: pr) holds the changed code. fetch-depth: 0 gives the agent the full repository history, which it uses to reason about how code and documentation relate. setup-node installs Node version 22, which Pi requires (@earendil-works/pi-coding-agent@0.79.6 needs Node ≥22.19.0). Pi is installed at a pinned version (@0.79.6) for reproducibility. The diff is written to pr/.doc-drift-input.diff so the agent can read it from the PR checkout.

    All actions are pinned to full commit SHAs for supply chain safety.

    Build the Agent Message

    You need to tell Pi where to find the diff, which skill to invoke, and where to write its reports. Rather than maintaining a separate script, the workflow builds this routing message with an inline bash heredoc.

          - name: Build agent message
            run: |
              WORKSPACE="${{ github.workspace }}/pr"
              DIFF_PATH="$WORKSPACE/.doc-drift-input.diff"
              cat > /tmp/pi-message.txt <<EOF
              You are running a doc drift check on a pull request in the VectorLint repository.
    
              The pull request checkout to inspect is located at:
                ${WORKSPACE}
    
              Read the PR diff from this file:
                ${DIFF_PATH}
    
              Use the doc-drift skill. When you have finished, write one report file
              per behavioral change you identified, named sequentially:
                ${WORKSPACE}/.doc-drift-1.md
                ${WORKSPACE}/.doc-drift-2.md
                ... and so on.
    
              If there are no issues to report, write a single file ${WORKSPACE}/.doc-drift-1.md
              containing the no-issues-found report.
    
              Do not post anything to GitHub directly. The workflow will handle posting.
              EOF
    

    The heredoc produces a routing message that tells Pi where the PR checkout lives, where to read the diff, and where to write its reports. The variables expand at runtime against github.workspace.

    The doc-drift skill it references lives at .agents/skills/doc-drift/, the same skill you created in Step 1.

    Run the Drift Check

    With the diff on disk, the routing message ready, and Node.js available, the workflow can run Pi and hand it the routing message. This is where the agent reasons about whether documentation needs updating.

    A CI runner has no interactive terminal, so Pi runs in a headless, non-interactive mode.

          - name: Run doc drift check
            working-directory: pr
            env:
              AWS_BEARER_TOKEN_BEDROCK: ${{ secrets.PI_BEDROCK_API_KEY }}
              AWS_REGION: ${{ secrets.PI_BEDROCK_REGION }}
              PI_MODEL: ${{ secrets.PI_MODEL }}
            run: |
              pi --no-session -p \
                --provider amazon-bedrock \
                --model "$PI_MODEL" \
                --skill ../main/.agents/skills/doc-drift \
                "/skill:doc-drift $(cat /tmp/pi-message.txt)"
    

    The step runs with working-directory: pr so Pi operates in the PR checkout. --skill ../main/.agents/skills/doc-drift points at the doc-drift skill in the main checkout (one directory up from pr). --no-session makes sure the session isn’t saved, and -p prints the response and exits. Both flags give you non-interactive execution.

    When the agent finishes, it writes one report file per behavioral change to numbered paths like .doc-drift-1.md, which the next step picks up. AWS_BEARER_TOKEN_BEDROCK, AWS_REGION, and PI_MODEL come from repository secrets you configure in Step 4.

    Post the Findings as PR Comments

    The agent is a language model, inherently nondeterministic. Letting it post directly to GitHub would make posting unpredictable. It could emit partial output, retry mid-run, or fail halfway through a comment. A file-based handoff sidesteps that.

          - name: Post report comments
            env:
              GH_TOKEN: ${{ steps.app-token.outputs.token }}
            run: |
              REPORT_FILES=$(ls "$GITHUB_WORKSPACE"/pr/.doc-drift-*.md 2>/dev/null | sort -V)
              if [ -z "$REPORT_FILES" ]; then
                gh pr comment --repo ${{ github.repository }} ${{ github.event.issue.number }} \
                  --body "Doc drift check completed but produced no output. Check the [Actions log](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
              else
                for file in $REPORT_FILES; do
                  gh pr comment --repo ${{ github.repository }} ${{ github.event.issue.number }} --body-file "$file"
                done
              fi
    
          - name: Post failure comment
            if: failure()
            env:
              GH_TOKEN: ${{ steps.app-token.outputs.token }}
            run: |
              gh pr comment --repo ${{ github.repository }} ${{ github.event.issue.number }} \
                --body "Doc drift check failed. Check the [Actions log](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
    

    The step lists all .doc-drift-*.md files in the pr checkout and loops through them, posting each one as a PR comment with gh pr comment --body-file. The agent never posts to GitHub itself. It only writes files, and the shell loop posts the comments to the PR, producing the same behavior on every run. The workflow passes the App token to gh pr comment for the same reason as every other write: GITHUB_TOKEN would 403 on issue_comment triggers for public repositories.

    The workflow owning all GitHub writes keeps the agent’s permissions minimal and makes every comment traceable.

    Two fallback paths handle edge cases. If the run produces no report files, a comment tells the reviewer and links to the Actions log. If the run fails outright, the failure() step catches the failure and posts a failure notice with the same log link.

    The Complete Workflow

    Here’s the full workflow for copy-pasting.

    name: Doc Drift Check
    
    on:
      issue_comment:
        types: [created]
    
    jobs:
      authorize:
        name: Check authorization
        runs-on: ubuntu-latest
        # Only run on PR comments that start with /check-docs (skip bots)
        if: |
          github.event.issue.pull_request != null &&
          startsWith(github.event.comment.body, '/check-docs') &&
          !contains(github.event.comment.user.login, '[bot]')
        permissions:
          issues: write
          pull-requests: read
          contents: read
        outputs:
          authorized: ${{ steps.auth.outputs.authorized }}
        steps:
          - name: Generate GitHub App token
            id: app-token
            uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
            with:
              app-id: ${{ secrets.APP_ID }}
              private-key: ${{ secrets.APP_PRIVATE_KEY }}
          - name: Check authorization
            id: auth
            uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
            with:
              github-token: ${{ steps.app-token.outputs.token }}
              script: |
                const association = context.payload.comment.author_association;
                if (!['OWNER', 'MEMBER'].includes(association)) {
                  await github.rest.issues.createComment({
                    owner: context.repo.owner,
                    repo: context.repo.repo,
                    issue_number: context.issue.number,
                    body: `@${context.payload.comment.user.login} Only repo owners or members can trigger doc drift checks.`
                  });
                  core.setOutput('authorized', 'false');
                } else {
                  core.setOutput('authorized', 'true');
                }
    
      check-docs:
        name: Check documentation drift
        runs-on: ubuntu-latest
        needs: authorize
        if: needs.authorize.outputs.authorized == 'true'
        permissions:
          issues: write
          pull-requests: read
          contents: read
        steps:
          - name: Generate GitHub App token
            id: app-token
            uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
            with:
              app-id: ${{ secrets.APP_ID }}
              private-key: ${{ secrets.APP_PRIVATE_KEY }}
          - name: React to comment
            uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
            with:
              github-token: ${{ steps.app-token.outputs.token }}
              script: |
                await github.rest.reactions.createForIssueComment({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  comment_id: context.payload.comment.id,
                  content: 'eyes'
                });
          - name: Get PR head SHA
            id: pr
            uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b
            with:
              github-token: ${{ steps.app-token.outputs.token }}
              script: |
                const pr = await github.rest.pulls.get({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  pull_number: context.issue.number
                });
                core.setOutput('head_sha', pr.data.head.sha);
          - name: Checkout main branch
            uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
            with:
              ref: ${{ github.event.repository.default_branch }}
              path: main
              fetch-depth: 0
          - name: Checkout PR branch
            uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
            with:
              ref: ${{ steps.pr.outputs.head_sha }}
              path: pr
              fetch-depth: 0
          - name: Setup Node.js
            uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
            with:
              node-version: '22'
          - name: Install Pi
            run: npm install -g @earendil-works/pi-coding-agent@0.79.6
          - name: Show Pi version
            run: pi --version
          - name: Fetch PR diff
            env:
              GH_TOKEN: ${{ steps.app-token.outputs.token }}
            run: |
              DIFF_PATH="$GITHUB_WORKSPACE/pr/.doc-drift-input.diff"
              gh pr diff --repo ${{ github.repository }} ${{ github.event.issue.number }} > "$DIFF_PATH"
              echo "Diff size: $(wc -l < "$DIFF_PATH") lines"
          - name: Build agent message
            run: |
              WORKSPACE="${{ github.workspace }}/pr"
              DIFF_PATH="$WORKSPACE/.doc-drift-input.diff"
              cat > /tmp/pi-message.txt <<EOF
              You are running a doc drift check on a pull request in the VectorLint repository.
    
              The pull request checkout to inspect is located at:
                ${WORKSPACE}
    
              Read the PR diff from this file:
                ${DIFF_PATH}
    
              Use the doc-drift skill. When you have finished, write one report file
              per behavioral change you identified, named sequentially:
                ${WORKSPACE}/.doc-drift-1.md
                ${WORKSPACE}/.doc-drift-2.md
                ... and so on.
    
              If there are no issues to report, write a single file ${WORKSPACE}/.doc-drift-1.md
              containing the no-issues-found report.
    
              Do not post anything to GitHub directly. The workflow will handle posting.
              EOF
          - name: Run doc drift check
            working-directory: pr
            env:
              AWS_BEARER_TOKEN_BEDROCK: ${{ secrets.PI_BEDROCK_API_KEY }}
              AWS_REGION: ${{ secrets.PI_BEDROCK_REGION }}
              PI_MODEL: ${{ secrets.PI_MODEL }}
            run: |
              pi --no-session -p \
                --provider amazon-bedrock \
                --model "$PI_MODEL" \
                --skill ../main/.agents/skills/doc-drift \
                "/skill:doc-drift $(cat /tmp/pi-message.txt)"
          - name: Post report comments
            env:
              GH_TOKEN: ${{ steps.app-token.outputs.token }}
            run: |
              REPORT_FILES=$(ls "$GITHUB_WORKSPACE"/pr/.doc-drift-*.md 2>/dev/null | sort -V)
              if [ -z "$REPORT_FILES" ]; then
                gh pr comment --repo ${{ github.repository }} ${{ github.event.issue.number }} \
                  --body "Doc drift check completed but produced no output. Check the [Actions log](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
              else
                for file in $REPORT_FILES; do
                  gh pr comment --repo ${{ github.repository }} ${{ github.event.issue.number }} --body-file "$file"
                done
              fi
          - name: Post failure comment
            if: failure()
            env:
              GH_TOKEN: ${{ steps.app-token.outputs.token }}
            run: |
              gh pr comment --repo ${{ github.repository }} ${{ github.event.issue.number }} \
                --body "Doc drift check failed. Check the [Actions log](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details."
    

    Step 4: Configure the Secrets

    Add five repository secrets under Settings → Secrets and variables → Actions in your GitHub account.

    GitHub App secrets:
    APP_ID: the numeric App ID from the App’s General settings page
    APP_PRIVATE_KEY: the contents of the .pem private key file

    Provider secrets:
    PI_BEDROCK_API_KEY
    PI_BEDROCK_REGION
    PI_MODEL

    For other providers, change the --provider flag in the workflow and the environment variable names to match. For example, Anthropic needs --provider anthropic and only two secrets ANTHROPIC_API_KEY and PI_MODEL. Check the Pi provider documentation for the environment variable your provider expects.

    Step 5: Test the Workflow

    On any pull request, leave a comment starting with /check-docs as a repo owner or member. The workflow confirms you’re authorized, runs the agent against the PR diff, and posts one comment per behavioral change the agent found. Here’s a drift finding:

    ## ⚠️ Doc drift - renamed the `--output` flag to `--format`
    
    ### `docs/guides/cli-reference.md` - Output formats
    
    **What the doc claims:** "Run `vectorlint doc.md --output line` for terminal output."
    **What's now true:** The flag is `--format`, not `--output`.
    
    Fix prompt:
    ~~~
    `docs/guides/cli-reference.md`, Output formats: "--output" is no longer accurate - the flag is now `--format`. Update it. Keep all existing structure, tone, and style.
    ~~~
    

    Every surfaced drift finding has a fix prompt. The check tells you what broke, and the prompt gives you a starting point to fix it.

    Not every PR drifts documentation. When the agent finds a new user-facing change that isn’t documented yet, the comment names the change and its location. When nothing needs attention, you get a confirmation comment with the files and changes it checked.

    Handling False Positives and Negatives

    AI models are probabilistic, so there’s bound to be some false positives and negatives.

    The agent might flag product changes as documentation drift when they aren’t, or miss drifts when a PR genuinely invalidates documentation.

    When you notice either problem, update the instruction in the docs-drift skill. Add a concrete instruction that names the pattern, states what the agent should do differently, and includes an example if the rule isn’t obvious. Then test it locally on the same code change to verify it covers the edge case.

    These misses are less frequent with more capable models. If you observe consistent false positives or negatives, consider upgrading to a more capable model.

    Resolving the Doc Drift

    At this point, your workflow catches documentation drift at the PR level. When a PR changes documented behavior, the agent flags it in the PR itself, no platform required.

    The simplest approach to resolving the drift is to update the documentation in the same PR. You can hand the fix message to an agent to update the relevant docs, or build an agent workflow to create a PR based on detected drift.

    You’ll need guardrails, constraints, and verification signals to keep the agent’s output accurate, on-style, and useful. These would let you quickly confirm the agent’s work is correct and provide feedback so the agent can self-correct.

    Building those guardrails is a project in itself and requires iteration. You need style-aware instructions, verification checks, and feedback loops that let you quickly assess the agent’s output and improve performance over time.

    For teams without a dedicated docs engineer, hiring an external documentation engineering service is often more cost-effective and efficient.

    At TinyRocket, we build automated workflows, agent skills, verification loops, and tools that help teams keep documentation in sync with their product. Our agentic workflows let your team focus on building while reducing documentation work to a matter of quick judgment. Book a call today to get a free documentation workflow audit.

  • What Is Content Engineering for Developer Tools?

    What Is Content Engineering for Developer Tools?

    Content engineering, or content operations engineering, has a slightly different definition depending on who you ask.

    In enterprise content management, it means applying engineering principles to structure content into reusable modules, manage metadata and taxonomies, and deliver content across channels.

    In marketing and search engine optimization (SEO), it means building workflows, automation, and AI to create, update, and distribute content at scale.

    For developer tool companies, content engineering is an extension of documentation engineering.

    Documentation engineering is the practice of building systems that keep docs aligned as the product evolves. Content engineering extends it to marketing content by building workflows, quality gates, and automation that keep blog posts, tutorials, guides, and launch pages in sync with the product as it ships.

    Regardless of how each industry defines it or the tools involved, the common goal is to treat content as a systems problem rather than a series of one-off deliverables.

    Content engineering is emerging now because teams want to use AI to gain efficiency and scale content without a proportional increase in effort. AI tools can produce content quickly, but teams have realized that speed without a system leads to inconsistent quality.

    This is especially important for developer tool companies as AI increases development velocity.

    Why Developer Tools Need Content Engineering

    More features shipping faster means more content to produce and maintain, more frequently. For developer tools that pose a risk of content drifting from the product.

    Documentation is part of the product, and developers judge your tool by how well your docs help them ship. So when content is out of sync with your product, developer experience degrades.

    A stale code sample, a deprecated API reference, or a tutorial that no longer reflects the current UI would cause developers to spend more time verifying your tool instead of building with it.

    It also affects how you get surfaced in AI search. AI assistants that read your content use your documentation and marketing pages as a retrieval context. If your docs and marketing pages are factually inconsistent or riddled with terminology inconsistencies, they can surface contradictory product explanations or omit your product altogether.

    The good thing is that developer tool companies already use foundational infrastructure such as Git and running CI/CD pipelines, so adopting content engineering practices is a natural extension.

    If you’re already practicing Docs as Code, content engineering builds on that foundation.

    What Content Engineering Looks Like in Practice

    Whatever happens repeatedly in your editorial workflow is a candidate for automating away in a content system. It could be fixing broken links, handling drift, or fixing terminology inconsistencies.

    For instance, if your docs live in the codebase, you can detect documentation drift by using a code review tool that can inspect pull requests for changed features and flag affected content for review. Tools such as Qodo and CodeRabbit does this quite well. If your docs live outside the repository, however, you would need to build a system that monitors releases or change logs, cross-references them with the content, and surfaces outdated pages.

    Surfacing outdated pages could then automatically create a GitHub issue or a Slack notification to update the team.

    AI can reduce manual work, but it shouldn’t make decisions for you. An agent can read and identify the sections that need changes, suggest revisions, and draft a first pass, but a human should still make the final decision to publish.

    Although AI workflows can speed up work, a human still needs to remain accountable.

    How Content Engineering Supports Developer Marketing

    Content engineering supports developer marketing by helping you decide what to publish, write it, review it, and keep it consistent as your product changes.

    You can build a repeatable workflow with a topic backlog, a brief template, a source-gathering step, quality checks, and a publishing process to bring in users, create search entry points, and explain your product well enough to earn trust.

    This is how we built our demand generation workflow. We use AI for topic research and prioritization, while a human (just me for now) signs off on what to write, and briefs before handing it off to an agent who writes the first draft.

    After that, the draft goes through automated quality checks, the agent revises until it meets our quality benchmark, and the human gives the final review. This setup enables one person to keep content moving while also handling software engineering work.

    It could also be an event-driven system.

    A feature launch can trigger an event that creates a content backlog, generates a brief from the changelog and source docs, drafts a tutorial or comparison post, and then runs checks for claims, terminology, and links before human review.

    Whatever workflow is implemented, it must make content creation faster without sacrificing quality.

    Benefits of Adopting Content Engineering Practices

    Implementing a content system reduces content drift and maintains a good developer experience.

    A content system also enforces consistency, making it easier for AI systems to trust and cite. Consistent, technically grounded content gives AI systems an unambiguous representation to work from, improving search visibility.

    It also ensures that content quality doesn’t slip as you scale volume. Enforcing quality checks at the writing and submission stages helps you expand your topical coverage while keeping every piece aligned with the same standards.

    Building a content system is also cost-effective. Not only does it reduce the workload on already overloaded technical writers or engineers, but it also enables you to scale production without a proportional increase in effort and resources.

    Snyk was able to scale its developer marketing strategy by adopting content engineering practices, scaling its developer content production, and driving hundreds of thousands of additional web sessions

    In-House vs Outsourcing Content Engineering

    You could hire a content engineer to build your content system, or have an in-house technical writer fill the role.

    Building a content system is ongoing work, though. The content engineer builds workflows, connects product development to content systems, adds quality gates, sets up knowledge bases, and improves the AI-assisted components when new tasks break the system. AI outputs aren’t deterministic, so the workflow needs ongoing calibration against your quality standards.

    Technical writers already juggle documentation, reviews, and contributor support. Adding content engineering to their tasks forces them to context-switch between writing and systems work, which can lead to more content debt or an inefficient system.

    At TinyRocket, we build content systems for developer tool companies when your team doesn’t have the capacity to take it on without diverting from the roadmap. We connect pull requests, releases, and change logs to your content inventory, route updates to the right owner, and set up quality-gated production workflows that keep documentation and marketing content aligned with product development.

    Book a free workflow audit for an analysis of your editorial process to see where you could automate or apply AI to keep your docs aligned or produce more developer content without sacrificing quality.

  • Using VectorLint to Catch AI Content Patterns in Docs as Code

    Using VectorLint to Catch AI Content Patterns in Docs as Code

    When you use AI to draft documentation, whether tutorials, guides, or API references, you save hours of writing time.

    The problem is that AI-generated content often contains AI patterns that could erode developer trust:

    “It’s important to note that…”
    “In the landscape of software development…”
    “This isn’t just X; it’s Y.”

    Even when your content is technically accurate, these patterns make it sound lazy.

    You could manually review every piece of content to catch these patterns, or you could automate your review process to catch them instantly.

    This guide shows you how to use VectorLint to automatically check for AI patterns in your Docs as Code workflow.

    VectorLint, AI-Assisted Editing

    VectorLint is an AI-powered prose linter that enables natural-language standard enforcement.

    It uses LLM-as-a-Judge to evaluate content and catch quality issues, making it possible to catch issues like terminology and spelling errors that only require pattern matching, and also those that require contextual understanding, such as AI patterns, Search Engine Optimization (SEO) problems, and technical accuracy.

    As a command-line tool, it runs in CI/CD pipelines, enabling a shared quality gate across your teams, preventing errors from reaching production.

    To get started, install VectorLint on your computer.

    Installing VectorLint

    1. Install VectorLint: To install VectorLint globally, run:
       npm install -g vectorlint

    Verify installation:

       vectorlint --version

    Alternatively, you can run it directly using npx:

       npx vectorlint

    Configuration

    Before you can review content with VectorLint, you need to connect it to an LLM provider.

    1. Initialize VectorLint: Run the initialization command to generate your configuration files:
       vectorlint init

    This creates two files, .vectorlint.ini which contains project-specific settings
    and ~/.vectorlint/config.toml where you configure your LLM provider settings.

       # VectorLint Configuration
       # Global settings
       RulesPath=
       Concurrency=4
       DefaultSeverity=warning
    
       # Default rules for all markdown files
       [**/*.md]
       RunRules=VectorLint

    This configuration tells VectorLint to check all Markdown files using the bundled VectorLint preset.

    1. Configure your API keys: Open your global config file (~/.vectorlint/config.toml) and uncomment the section for your preferred LLM provider. VectorLint supports OpenAI, Anthropic, Google, and Azure models.
       # --- Option 1: OpenAI (Standard) ---
       # LLM_PROVIDER = "openai"
       # OPENAI_API_KEY = "sk-..."
       # OPENAI_MODEL = "gpt-4o"
       # OPENAI_TEMPERATURE = "0.2"
    
       # --- Option 2: Azure OpenAI ---
       # LLM_PROVIDER = "azure-openai"
       # AZURE_OPENAI_API_KEY = "your-api-key-here"
       # ...
    
       # --- Option 3: Anthropic Claude ---
       # LLM_PROVIDER = "anthropic"
       # ANTHROPIC_API_KEY = "your-anthropic-api-key-here"
       # ...
    
       # --- Option 4: Google Gemini ---
       # LLM_PROVIDER = "gemini"
       # GEMINI_API_KEY = "your-gemini-api-key-here"
       # ...

    Uncomment your preferred provider and add your API key. See the configuration guide for full details.

    1. Create a test file: Create docs/getting-started.md with some content containing AI patterns:
       # Getting Started
    
       In the world of software development, getting started with any new tool can be daunting.
    
       This guide is not just a tutorial; it is a comprehensive resource for developers.
    1. Configure AI pattern detection: VectorLint comes bundled with a VectorLint preset that includes AI pattern detection rules. The init command automatically configures this in your .vectorlint.ini file. The VectorLint preset includes these rules: AI-Pattern, Directness, PseudoAdvice, and Repetition. Rules in rule packs are automatically enabled unless explicitly turned off. For this guide, you only need the AI-Pattern rule, so turn off the others in your .vectorlint.ini:
       [VectorLint]
       Directness = disabled
       PseudoAdvice = disabled
       Repetition = disabled

    Running Your First VectorLint Check

    To run VectorLint on a file, use the command:

    vectorlint docs/getting-started.md

    VectorLint should output a quality report in your terminal:

    Adding VectorLint to Your CI/CD Pipeline

    Integrate VectorLint into your GitHub Actions workflow to automatically check documentation on every pull request.

    To add VectorLint to your CI/CD pipeline, create .github/workflows/lint-docs.yml:

    name: Lint Documentation
    on: [pull_request]
    
    jobs:
      vectorlint:
        runs-on: ubuntu-latest
        env:
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
        steps:
          - uses: actions/checkout@v3
    
          - name: Setup Node
            uses: actions/setup-node@v3
            with:
              node-version: '18'
    
          - name: Run VectorLint
            run: npx vectorlint docs/*.md

    This workflow runs VectorLint on every pull request, checking all modified Markdown files against your quality rules. If VectorLint finds quality issues, the build fails, and the quality report appears in the PR comments.

    Next Steps

    You’ve now automated the detection of excessive hedging in your documentation. But there are more AI patterns worth catching:

    Expand your rule pack:

    • Define rules that match your company’s style guide
    • Share your rule packs across repositories
    • Use VectorLint scores as a metric for documentation quality

    By creating more rules, you can automate more quality checks and save time on content review. This helps you keep up with development velocity while maintaining the quality and trust your brand depends on.

  • You Need an AI Prose Linter in Your Docs as Code Workflow

    You Need an AI Prose Linter in Your Docs as Code Workflow

    With LLMs now capable of creating and reviewing content at scale, your Docs as Code workflow is incomplete without an AI prose linter.

    Although traditional prose linters can catch many errors, their syntactic approach means they can’t catch errors that require contextual judgment.

    To solve this problem, many teams use LLM-powered apps like ChatGPT or Claude. However, this remains outside the team’s shared automated testing workflow, resulting in inconsistent quality.

    These apps aren’t tuned for consistent evaluations, and different team members use different prompts and processes. Even with a shared prompt library, you’re still relying on each contributor to use it correctly.

    An AI prose linter solves this by providing AI reviews and suggestions in your Docs-as-Code workflow. You can achieve reliable automated quality checks by setting the LLM to low temperatures, using structured prompts, and configuring severity levels.

    Making AI Prose Linters Reliable With Severity Levels

    AI prose linters inherit the non-determinism of their underlying technology, which means they will occasionally generate false positives.

    Because the whole point of a CI pipeline is to deliver reliable builds, this is a bad recipe for your pipeline. The solution is to configure them as non-blocking checks that highlight potential issues and suggest fixes without failing your build.

    Just like traditional prose linters aren’t perfect, AI prose linters don’t need to be either.

    Even if you get 50% accuracy on quality flags, you’d be saving half the time you’d otherwise spend hunting for them yourself.

    With that out of the way, here are four reasons you should adopt an AI prose linter in your Docs as Code workflow.

    1. It Reduces Time Spent on Reviews

    AI prose linters reduce the time spent on manual content reviews by catching contextual issues that typically require human judgment.

    While traditional prose linters can catch terminology and consistency issues, the bulk of review time is typically spent on editorial feedback. This involves identifying issues that require contextual judgment, such as whether there is repetition of concepts across sections or if content directly answers the reader’s question.

    By codifying these editorial standards into AI prose linter instructions, you can catch these issues locally or in the CI pipeline, and get suggested fixes. This reduces the mental load on reviewers and saves time.

    2. It Enables Broader Team Contribution

    AI prose linting enables developers, engineers, and product managers to contribute high-quality documentation by providing them with immediate, expert-level editorial feedback as they write.

    Technical writers are often stretched, with some teams operating at a 200:1 developer-to-writer ratio. To get documentation up to date promptly, non-writers often need to contribute. While you can save a lot of time with traditional linters catching typos and broken links, you can make contributing even easier by using AI prose linting.

    Not only does it broaden the scope of issues you catch, but it also helps contributors learn the reason behind the flags and provides them with suggestions to fix them, making them more confident in their contributions.

    3. It Lowers the Barrier to Docs as Code

    Teams who don’t have a dedicated documentation engineer often refrain from adopting a Docs as Code workflow because of its maintenance overhead. It often requires an ongoing effort to create and maintain rules as the team creates more content.

    While traditional linters often have preset style rules that you can start with, you’ll still need to maintain them to deal with false positives that block merges, or to catch new issues that come up.

    AI prose linters solve this problem by using natural language instructions to define rules. This enables you to catch a wide range of issues with fewer instructions, reducing the maintenance overhead.

    For instance, if you wanted to catch hedging language using Vale, you’d need to write a regular expression covering as many variations as you can think of such as `appears to`, `seems like`, `mostly`, `I think`, `sort of`, etc.

    With an AI prose linter, you can simply write:

    `Check for any phrase that connotes uncertainty or lack of confidence (for example, “appears to”, “seems like”)`

    And it can catch variations you never thought to list.

    The trade-off is that natural language tends to leave room for edge cases, and so without precise instruction, you can get false positives. However, the cost of maintaining a wide library of rules or trying to envisage every edge case far outweighs the cost of filtering out false positives.

    4. It Accelerates Productivity For Solo Writers

    To achieve high-quality, error-free content, solo writers still have to review their own work. However, the biggest hurdle isn’t a lack of skill; it’s the human factor. When you’re the only person writing and editing thousands of lines of documentation, you lose the “fresh eyes” benefit that teams take for granted.

    After the fifth hour of editing a technical guide, fatigue sets in, making it easy to miss quality issues. An AI prose linter serves as a peer reviewer, turning the review process into simple “yes” or “no” decisions.

    The AI highlights the issues, and you decide whether they’re valid quality issues or not. This is less mentally taxing and faster than if you had to find the issues yourself.

    Knowing you have an automated editorial pass gives you confidence, allowing you to focus on providing value rather than worrying if you’ve missed a subtle stylistic error.

    Using VectorLint, an Open Source AI Prose Linter

    VectorLint is the first command-line AI prose linting tool.

    We built it to integrate with existing Docs-as-Code tooling, giving your team a shared, automated way to catch contextual quality issues alongside your traditional linters.

    You can define rules in Markdown to check for SEO optimization, AI-generated patterns, technical accuracy, or tone consistency, practically any quality standard you can describe objectively.

    Like Vale or other linters you already use, VectorLint runs in your terminal and CI/CD pipeline as part of your standard testing workflow.

    Check it out on Github

  • Content as Code: Why Technical Teams Should Lint Prose Like They Lint Code

    Content as Code: Why Technical Teams Should Lint Prose Like They Lint Code

    Your engineering team already relies on linters like ESLint, Prettier, or Rubocop to catch code issues before they reach production.

    These tools flag style violations, enforce consistency, and reduce code review time by automating the tedious aspects of quality control, leading to quicker code reviews, consistent output, and a lower mental burden.

    Unfortunately, most technical teams don’t apply this same practice to their technical content.

    Docs, guides, and tutorials undergo entirely manual reviews, where reviewers spend time flagging missing Oxford commas, inconsistent terminology, and overly long sentences.

    If you’re a small content team supporting dozens of engineers or managing contributions from external developers, this manual review process becomes a bottleneck.

    Reviewing technical content manually results in slow publishing cycles, inconsistent docs quality, and frustrated contributors.

    This is where prose linting comes in.

    Prose linting solves these issues by automating style and consistency checks the same way code linters do. It’s a significant part of the Content as Code approach: treating all technical content with the same rigor as code.

    What Is Content as Code?

    Content as Code extends the Docs as Code methodology beyond docs to all technical content, meaning guides, tutorials, and blog posts, treating them with the same rigor as software code.

    This means writing content in Markdown, storing it in version control, conducting reviews through pull requests, and running automated quality checks as part of your publishing pipeline.

    Everything sits in the same repository and follows the same development workflow.

    This approach works well for engineering teams because it integrates seamlessly with the tools they use daily. There’s no need to switch to a separate editor or learn a new publishing system. Writing, reviewing, and releasing docs becomes part of the same workflow as writing code.

    This methodology provides proper version history for all content, supports collaborative workflows across roles, and supports the addition of automated quality checks as part of the publishing pipeline.

    Organizations like Google, Microsoft, GitHub, Datadog, and ContentSquare already use Docs as Code. Extending it to all technical content enables faster growth.

    You Grow Faster with Automated Content QA

    Ship Content Faster

    Automated linting handles the first-pass review for style, terminology, and consistency, so human reviewers can focus on technical accuracy instead of policing syntax.

    Authors get feedback immediately in their IDE or when they open a pull request, allowing issues to be corrected before review, shortening review cycles, and increasing merge speed without reducing quality.

    At Datadog, a 200:1 developer-to-writer ratio still supports reviewing around 40 docs pull requests per day. In 2023, the team merged over 20,000 pull requests across dozens of products and integrations.

    Automated checks made this volume possible by catching repetitive style issues early and reducing the mental load on writers and reviewers without adding headcount.

    When a prose linter like Vale runs in CI, it catches most style guide violations even before a human reviewer sees the PR, so reviewers spend less time pointing out minor fixes, and pull requests move through review faster.

    Scale Your Contributor Program

    External contributors often submit content with inconsistent style and terminology because they haven’t memorized your style guide. Without automated checks, reviewers spend time explaining these standards through manual feedback on every PR.

    However, automated prose linting communicates these standards through immediate, actionable feedback, so contributors see and grasp “what good looks like” without reading lengthy style guide documents.

    ContentSquare saw measurable growth in engineering contributions after implementing Vale for prose linting.

    Engineers reported feeling more confident contributing because they received clear guidance about what to fix. This lowers the barrier to entry for developers who are technical experts first and writers second.

    Build Developer Trust

    Consistent terminology and style signal professionalism and reliability to your users.

    Docs quality directly shapes product trust and adoption, especially with technical audiences who quickly lose confidence when they encounter inconsistent terminology or explanations.

    If one page says “authenticate” and another says “log in,” or if the same concept is described in different ways across pages, developers notice.

    Automated quality checks prevent these issues before they reach production by enforcing consistency across the entire docs set, which helps you maintain credibility as the product evolves.

    Furthermore, automated checks ensure your docs remain current as your products evolve. When docs lag behind releases, developers lose confidence in their accuracy.

    Automated checks solve this by allowing teams to ship updates quickly without compromising quality standards. The combination of consistent quality delivered at speed becomes a competitive advantage for developer adoption.

    What Vale Does

    To implement automated prose linting, most engineering teams start with Vale, an open source prose linter that checks content against style rules.

    It runs locally on your machine, inside your IDE, via pre-commit hooks, in pull request checks, or as part of your CI/CD pipeline.

    Vale understands the syntax of Markdown, AsciiDoc, and reStructuredText, so it can parse your content correctly and ignore code blocks or other markup.

    Alternative prose linters include textlint, proselint, and alex, but Vale is the most common choice among engineering teams.

    Basic Setup Steps

    • Install Vale via your package manager (Homebrew on macOS, Chocolatey on Windows, or apt/yum on Linux)
    • Generate a .vale.ini default configuration file at your project root. You can use existing style packages like Google or Microsoft, or create custom rules.
    Vale-installation-1
    • Run vale sync to download the style package
    • Run vale [path/to/content] to lint your files

    What Automated Feedback Looks Like

    Vale flags issues with line numbers and provides suggested fixes for problems like overly long sentences, filler words, inconsistent terminology, and style violations like missing Oxford commas.

    This feedback appears whether you run Vale in your terminal, your IDE, or as automated comments on pull requests.

    Once you see how Vale flags issues, you’ll be tempted to enable every available rule. Resist that urge.

    Start with 5 Rules, Expand Over Time

    The Progressive Rollout Approach

    Don’t launch with 50 rules; start with 5-10 focused on your biggest pain points. Pilot Vale on one docs set, such as your API reference, getting started guide, or README files.

    Gather feedback from your team and iterate on the rules based on what they find helpful or frustrating. Expand coverage gradually as the system proves its value.

    Teams that roll out too many rules at once face resistance and overwhelm from contributors. A progressive rollout builds team buy-in and confidence in the system.

    You’ll see initial value within weeks, with fewer style inconsistencies flagged during review, and faster merge times. The benefits compound over months as your team internalizes the standards and your rule set matures. 

    ContentSquare implemented this approach and saw a growth in contributions as engineers became more confident in contributing to docs.

    This progressive approach works, but it’s not a “set it and forget it” solution.

    You Need Maintenance To Succeed

    Setting up prose linting requires an initial time investment for installation and rule tuning.

    Some rules will need adjustment based on your specific content type, as what works for API docs may be too strict for tutorial content or technical guides.

    Team buy-in matters more than perfect configuration from day one, and the system works best when integrated into your existing workflow.

    Expect to refine rules as your team discovers edge cases, add exceptions for product-specific terminology, and occasionally tune thresholds for readability metrics.

    The good news is maintenance gets easier over time as your rule set stabilizes and your team adapts to the workflow.

    Many engineering teams at companies like Datadog and ContentSquare automate their content quality checks, reporting significant improvements in review speed and output consistency.

    The challenge for smaller teams is implementing and maintaining the automation pipeline.

    That’s where TinyRocket helps: we implement production-ready prose linting systems tailored to your workflow, so you can focus on building your product, not maintaining docs tooling.

  • Prose Linting for Technical Teams: What Grammarly Can’t Do

    Prose Linting for Technical Teams: What Grammarly Can’t Do

    As your content volume grows, you’ll quickly realize that Grammarly alone isn’t enough to maintain content quality at scale, regardless of whether you’re a solo technical writer or part of a team.

    Creating high quality technical content requires that you maintain several quality standards.

    You need to check that the content actually solves the problem, uses inclusive language, avoids passive voice, and doesn’t contain vague advice, among other things.

    Using Grammarly with checklists is a manual process that becomes time-consuming and error-prone as you scale output.

    You might decide to hire more technical writers to meet the content demands, but now you’ll have to deal with a new problem.

    Multiple writers introduce inconsistent styles and more opportunities for human error.

    That’s why companies like Datadog, Grafana, and Stoplight use prose linters in their documentation pipeline to save time on reviews and produce high-quality developer content.

    Prose linters are tools that check your writing against defined style rules. They’re similar to code linting tools. But while code linters catch syntax errors and enforce coding standards, prose linters catch style violations and enforce writing standards before content gets published.

    That enforcement capability is what makes them suitable for automating review workflows, saving time and maintaining quality standards.

    Let’s consider five ways prose linters help you save time on content reviews and maintain content quality that Grammarly alone doesn’t.

    1. Enforcing Style Guides

    When one API tutorial refers to authentication credentials as “API keys” while another uses the term “access tokens,” developers may wonder if these terms refer to different concepts.

    If this happens across dozens of terms, the documentation becomes unreliable.

    Grammarly enables you to upload style guides and define preferred terms, and it flags violations in real-time as writers work. The problem is that writers can dismiss these suggestions, which means the content lead needs to re-check every writer’s submission to ensure they didn’t dismiss important recommendations.

    That’s more time spent on review.

    And if you’re working alone, you’d have to ensure you’re always thorough with your work—not a bad thing to do, but it’s still susceptible to human error.

    Prose linters, such as Vale, solve this by blocking publication when Vale identifies an error. When set up in a CI/CD pipeline, you can configure Vale to check every pull request against your defined rules. So, your style guide specifies “email” not “email,” the linter flags every violation and blocks publication until corrected.

    Every contributor, whether a guest author, engineer, or technical writer, receives the same feedback when they submit content.

    2. Protecting Intellectual Property

    Where your content goes matters when you’re working with unreleased features under NDA or proprietary systems.

    Grammarly processes content on its cloud infrastructure. And while the company is security compliant (SOC 2 Type 2, ISO 27001, GDPR), it may not meet the requirements of every organization.

    For instance, in 2019, Microsoft explicitly banned Grammarly, citing concerns that the tool could access protected content within emails and documents.

    Prose linters run entirely on your infrastructure. Install and run them locally, and they process content without requiring an internet connection.

    When policy prohibits external processing, local tools are the only option

    3. Enforcing Document Structure and Formatting Standards

    How headings, lists, emphasis, and italics impact readability and how content renders across platforms.

    Grammarly preserves basic formatting, but it doesn’t validate whether headings follow proper hierarchy. It won’t flag inconsistent bullet point styles or enforce that documents start with a title heading.

    Structural linters, such as Markdownlint on the other hand, address these requirements. You can enforce unique H1 headings, consistent list indentation, and proper heading hierarchy for accessibility.

    4. Creating Contextual Rules Based on Document Metadata

    Different kinds of developer content require different style enforcement. A reference document might demand precise technical terminology and consistent parameter descriptions, while a tutorial might allow conversational tone and varied phrasing to maintain engagement.

    Grammarly applies rule sets uniformly at the organization level. This works well for maintaining consistent voice across all communications, but it can’t differentiate between document types or adjust enforcement based on content purpose.

    Prose linters support conditional rule application through document metadata. Add frontmatter to your Markdown files indicating document type or target audience, and you can enforce stricter terminology in customer-facing docs, relaxed tone in internal wikis, and API-specific rules only for reference documentation.

    5. Integrating Quality Checks Into Development Workflow

    Developers already automate quality enforcement. Code doesn’t merge until it passes linting, testing, and review. Documentation should work the same way.

    Grammarly provides immediate feedback during writing. But it can’t create enforceable quality gates. Grammarly can’t block a pull request or prevent content from merging when style violations exist.

    Prose linters integrate directly into CI/CD pipelines. Add a prose linter to your GitHub Actions workflow, and every documentation pull request gets automatically checked against your style rules. The linter flags violations and blocks the merge if critical rules fail.

    Human reviewers see only content that’s already passed automated style validation. Mechanical checks happen automatically, so reviewers can focus on technical accuracy and clarity.

    When to Use Each Tool

    Both Grammarly and Prose linters improve documentation quality, but they target different aspects of the writing process.

    Grammarly provides real-time feedback on grammar and clarity. Prose linters catch terminology inconsistencies across your own documentation over time, ensuring you follow your own style guide consistently even when writing alone. When combined, both tools help you create high-quality technical content.

    It is even more essential for teams with multiple contributors. Grammarly raises each person’s baseline writing quality, while prose linters enforce team-wide consistency that manual review can’t maintain at scale.

    Rather than choose between them, use both to maintain the content quality you need to attract and retain developer trust.

    Getting Prose Linting Right

    Implementing prose linting in production isn’t a set-and-forget. It requires initial setup investment and ongoing maintenance.

    After the initial setup, false positives emerge as your team writes more content, rules conflict with edge cases, and contributors grow frustrated when legitimate writing gets flagged. Without continuous refinement, teams risk abandoning their linting setup entirely.

    To get started, install Vale and configure a few essential style rules from established packages, such as the Microsoft or Google style guides, then integrate it into your CI/CD pipeline.

    Get feedback from your team as they encounter issues, then adjust the rules as you identify frequent false positives or new patterns that the rules don’t cover.

    However, if you’d like to skip the trial-and-error phase and focus on your writing, we can handle the entire workflow for you. From initial configuration to ongoing maintenance, so your team can focus on other priorities.

    Companies like Datadog and Stoplight report significant improvements in review cycle speed, content consistency, and measurable quality gains after implementing prose linting.

    Book a call, let’s discuss how you can improve your content quality

  • How We Screened 124 Writer Applications in 4 Hours

    How We Screened 124 Writer Applications in 4 Hours

    AI search is fast becoming the primary way people find information, and one of the criteria for your content to get cited is that it offers unique insights.

    So, as a startup looking to scale its technical content strategy, you need writers who both have a strong grasp of their domain and can write well. They should have interesting insights or takes to share. However, these writers are challenging to find.

    You might have hundreds of applicants for a single job posting, but only a few will have the skills you need. With AI making it easy to create content, you also get a flood of applications.

    Reviewing them takes a lot of time you don’t have, but you also can’t ignore them because among those applications are writers who could bring the value you need to scale your technical content strategy. So what do you do?

    Well, to solve this problem for our client, we built an automated screening system that reduced what could have been weeks of manual review to just four hours.

    The Problem

    Finding Contributors With Real Authority in a Crowded Market

    Our client runs a community writing program and received 124 applications with over 300 articles to review.

    It might not seem like much, but they were a small team, and manually reviewing them would have stretched into weeks. Not to mention the oversights on qualified candidates that could occur if fatigue sets in.

    The goal was clear: quickly identify contributors from a relatively large pool of applicants who could share insights beyond the basics and communicate them well.

    Here’s how we solved the problem by engineering an evaluation prompt and integrating it into their application flow.

    The Solution

    We solved the problem in four steps.

    1. Defining content criteria
    2. Gathering data
    3. Prompt engineering
    4. Integration

    Step 1: Defining Content Criteria

    Our client wanted writers who could share insights from their experience and write with authority.

    So, we broke down the authority criteria into three types: experiential authority, research-based authority, and implementation authority.

    Experiential Authority: Identifies writers who have actually implemented what they discuss, shown through specific scenarios and lessons learned.

    Research-Based Authority: Separates writers who understand the broader context from those rehashing basic concepts.

    Implementation Authority: Distinguishes between those who have built real systems versus those who have only read about them.

    After deciding on the criteria, we set out to create a dataset of articles, a list of the kind of articles that met our standards, and those that didn’t. This would teach our evaluation system what “good” and “bad” looked like.

    Step 2: Gathering Data

    To ensure our AI system could accurately identify these authority types, we needed concrete examples of what good and bad articles looked like.

    We manually sorted through existing articles to create a dataset of clear examples that demonstrated strong authority versus those that appeared knowledgeable but lacked real expertise.

    Our goal was to produce reliable evaluations. Without these examples, our prompts would be theoretical guidelines that the AI couldn’t reliably apply. The AI model required reference points to comprehend subjective concepts such as “authority” and “expertise.”

    The manual sorting process also helped us identify subtle patterns that distinguished truly authoritative content from surface-level knowledge.

    Step 3: Prompt Engineering and Testing

    Based on our defined criteria, we created a rubric and prompt that included concrete examples of what constituted strong versus weak authority indicators.

    For instance, strong experiential authority was characterized by articles that included specific tools used, problems encountered, and solutions implemented, whereas weak authority meant generic advice without personal context.

    We created disqualification criteria that would automatically filter out basic tutorial content and articles lacking practical experience indicators. The rubric provided clear scoring guidelines, allowing the AI model to evaluate the content with consistent assessment.

    We deliberately started with a lenient rubric to avoid false negatives, so we wouldn’t miss qualified candidates, and then tuned it when we observed unqualified articles passing the assessment.

    Step 4: Integration

    We built the automation workflow using n8n, integrating it with Google Forms, which they used to accept applications.

    When a new application was submitted, the workflow evaluated the author’s submitted articles and sent the assessment to the content team via Slack. The justification behind each assessment was included, so the team could validate the reasoning.

    The Result

    We completed all 124 application screenings in 4 hours versus the 3–4 days manual review would have required. And out of 124 applications, only 4 candidates met our authority standards.

    Imagine if the client reviewed all 124 manually, only to get 4 candidates. The automated screening system also revealed that inbound applications weren’t the best source of quality contributors, validating a shift toward outbound recruitment.

    Instead of spending days reviewing unsuitable applications, our client could invest that time in reaching out and building relationships with writers more likely to meet the publication’s requirements.

    TinyRocket – Content Compliance Partner

    Onboarding authors is just one part of executing a technical content strategy.

    After onboarding, you’ll need to manage and review the content to ensure it meets your quality standards. This takes time that could be spent on distribution, making sure your content reaches your target audience.

    That’s why we help technical startups build content compliance systems that integrate into their existing workflows so they never have to worry about quality.

    If you’d like to scale your technical content strategy without increasing overhead, book a call, let’s have a chat.

    Frequently Asked Questions

    1. Could we have just used ChatGPT directly instead of building a custom system?

    Using ChatGPT to review each article based on the client’s criteria might sound like a solution, but it would still be slow and unreliable. We would have had to paste each of 372 articles across 124 applications individually, which would have taken hours.

    The bigger issue is consistency. ChatGPT’s context window expands as you add more content, and it becomes less reliable at following specific requirements. By the time dozens of articles have been processed, it may have lost the thread of the instructions and the results would no longer be reliable.

    2. How do you ensure the automated system doesn’t miss qualified candidates that a human would catch?

    Our three-authority evaluation criteria were designed based on extensive analysis of what distinguishes good candidates from poor ones. Rather than trying to identify everything we wanted (which is subjective), we focused on clear indicators of real expertise versus theoretical knowledge.

    Processing individual articles with consistent rubrics ensures our evaluation criteria don’t drift over time like manual review does. In addition, our iterative refinement process helped us handle edge cases systematically.

    3. Can this approach work for other types of hiring beyond content creators?

    Yes. The same approach, defining clear authority signals, building an example dataset, creating a rubric, and integrating the evaluation into your intake workflow, can be adapted to other roles where demonstrated experience matters.

  • How TestingPod Cut Down its Content Review time by 50% with TinyRocket

    How TestingPod Cut Down its Content Review time by 50% with TinyRocket

    TestingPod is a software testing publication operated by MagicPod, a no-code test automation platform. The publication features paid contributions from experienced software testers as part of an effort to build a software testing community and establish trust with its target audience.

    The Challenges

    TestingPod ran its community writing program with a single editor managing roughly 20 contributors. Because most writers were software testers first and writers second, the content required significant editorial work before it was ready to publish.

    To consistently publish quality content with a one-man editorial team, they needed to overcome these challenges:

    • No editorial standards: The publication had no style guide, contribution guidelines, or process documentation. Writers had no reference for what “publish-ready” looked like.
    • Voice vs. standards: The editor had to enforce brand quality standards without silencing each contributor’s authentic voice.
    • Slow review cycles: Each article took roughly four hours to review. Contributors would often take days to respond to feedback, stalling the publication process.
    • Feedback bottleneck: Crafting clear, constructive feedback took far longer than identifying issues. Even when contributors took days to apply the feedback, they would often introduce new errors, triggering a repeat of the entire cycle.
    • Platform friction: Content was managed through HubSpot. With one editor managing 20 writers, TestingPod needed automation to scale, but HubSpot wasn’t built for multi-author workflows and offered limited automation capabilities.

    Our approach

    Workflow audit and prioritization

    We started by timing the editorial workflow to identify where time was being lost. The data showed that crafting feedback, not finding issues, consumed the majority of review time. Hence, we prioritized solutions by impact and implemented them incrementally.

    Content management migration

    To support a multi-author workflow, we moved content management from HubSpot to GitHub, which provided:

    • Centralized documentation: Articles, style guides, and contribution guidelines were moved into a single, accessible repository.
    • Familiar tooling: Most writers were technical professionals, so GitHub was a familiar environment.
    • Process transparency: Writers had full visibility into the history of submissions and editorial feedback across their work, allowing them to learn from past reviews.
    • Automation infrastructure: GitHub provided the necessary foundation to integrate automated review tools directly into the submission process.

    Editorial standards and process documentation

    We identified recurring quality issues and helped establish the editorial standards and processes that TestingPod was missing, including:

    • A comprehensive style guide and contribution guidelines: These documents define the brand’s quality standards, tone, and publication conventions, and set clear editorial expectations for writers before they start drafting.

    As we spotted new issues, we documented them and refined these documents over time.

    AI-assisted feedback workflows

    We built an AI skill that addressed the feedback bottleneck with:

    Rough-to-clear feedback conversion: It translates rough editorial notes into polished, constructive feedback. The editor could input brief, blunt notes like “this section isn’t clear,” and the AI would convert them into complete, professional guidance.

    Consistent tone: The system ensured feedback remained constructive and encouraging across all interactions.

    Voice preservation: The system helped the editor balance strict quality enforcement with the preservation of each writer’s authentic voice.

    Automated content review with Vale

    With GitHub as our hub, we integrated Vale to automatically catch recurring issues such as colloquial language, low- and high-level redundancy, and other stylistic inconsistencies at the Pull Request level.

    We also added structural rules to limit Markdown headings to H1–H3 to keep articles scannable and to enforce consistent capitalization.

    Writers received this automated feedback the moment they submitted their work, allowing them to self-correct surface-level issues before the editor opened the file.

    The Outcome

    The combination of AI-assisted feedback and automated content review produced immediate results:

    50% reduction in review time: Articles that previously took four hours to review now took two.

    Recurring issues were caught automatically: Quality issues that often led to back-and-forth review cycles were flagged and fixed before reaching the editor.

    Transparent editorial process: Writers learned from previous feedback, improving submission quality over time.

    Editor freed for high-value work: With surface-level issues handled automatically, the editor could focus on structure, argument quality, and voice refinement.

    The content engineering system enabled TestingPod to maintain a cost-effective, community-driven content program without sacrificing quality or contributor voice.