ProductionWriting tools2025

gocools write

Codename: gocools write

A writing and documentation workspace with grammar assistance, AI-text detection and document management.

Why it existsStudents write a lot of assessed prose and have no good tools. Commercial writing assistants are priced for salaries, not stipends.

Overview

gocools write is an online writing workspace. It stores documents, checks grammar and style, flags text that reads as machine-generated, and can rephrase machine-sounding passages into something more natural.

The grammar and detection capabilities are not mine. They come from third-party APIs. What I built is the workspace around them: document storage, revision handling, the editor, and the orchestration that makes several external services behave like one coherent feature.

Problem

Academic writing tools are priced in dollars per month, which is a real barrier for students in Kathmandu. The free tiers are crippled in exactly the places that matter, usually document length.

There is also a workflow problem that no single tool solves. Checking grammar, checking whether a passage will trip an AI detector, and rewriting a flagged passage are three separate products with three separate copy-paste round trips. The friction is the actual problem.

Approach

Treat the external capabilities as interchangeable providers behind one internal interface, and put the effort into the workspace.

Every external capability is wrapped in an adapter with a narrow contract: text in, structured findings out. The application never calls a vendor SDK directly. That kept vendor churn, and there was vendor churn, from reaching the editor.

Requests are batched and cached. A paragraph that has not changed is not re-checked. This started as a cost measure and turned out to be the single biggest responsiveness improvement in the product.

Architecture

Editor and workspace

Document editing with autosave, revision history and a document library. Findings render as inline annotations rather than a separate report, so a suggestion appears where the problem is.

Provider layer

One adapter per external capability: grammar, AI detection, rephrasing. Each adapter normalises vendor responses into a common finding shape with an offset range, a severity and a suggested replacement. Adding or swapping a vendor touches one file.

Cache and batching

Content-addressed cache keyed on a hash of the paragraph plus the check type. Unchanged paragraphs are served from cache. Requests to a provider are batched per document save rather than per keystroke.

Storage

Document text and revisions in a relational database. Attachments and exported files in object storage.

Technology

Containerised application services with Docker. GitHub Actions for build and deployment. AWS for hosting and object storage. Third-party APIs for grammar checking, AI-text detection and humanisation, each behind an internal adapter.

Implementation

The finding model was the first thing I designed and the thing that made the rest tractable. Once every provider produced the same shape, offset range, severity, replacement, category, the editor only had to learn one rendering path.

Rate limiting is enforced on our side of every adapter, not just handled when a vendor returns a 429. Each adapter carries a token bucket sized to its plan, and callers get a queued promise rather than a failure. A slow check is acceptable; a check that vanishes is not.

Text offsets survive editing through a mapping layer. When a user edits a paragraph while a check is in flight, the returned offsets are remapped against the current document or discarded if the paragraph has changed materially. Getting this wrong puts annotations on the wrong words, which destroys trust in the whole feature.

Challenges

Third-party APIs are a moving target. Response shapes changed under me twice during development. The adapter layer absorbed both changes without touching the editor, which retroactively justified the indirection I had been unsure about.

Cost scales with keystrokes if you let it. The naive implementation checked on every pause in typing and would have been unaffordable. Paragraph-level content hashing plus save-triggered batching cut the request volume to something a free tier could carry.

Offset drift. The hardest bug in the project was annotations landing on the wrong text after an edit. The fix was to stop treating offsets as absolute and start treating them as claims about a specific paragraph version.

Decisions

Rent the intelligence, own the workspace. Building a grammar engine was never realistic and never the point. The defensible work was the workspace.

Adapters over direct SDK calls. More code, more indirection, and it paid for itself the first time a vendor changed a field name.

Cache on content, not on time. A TTL cache would have re-checked unchanged text on a schedule for no reason. Content hashing means the cache is correct by construction.

Results

Deployed and in use. Grammar checking, AI-text detection and rephrasing work through the adapter layer, documents persist with revision history, and the caching layer keeps external API usage inside free and low-cost tiers.

The clearest signal is that people use it for real coursework rather than to test whether it works.

Stack

  1. Client

    • Document editor with autosave
    • Inline annotations
    • Revision history
  2. Provider layer

    • Grammar adapter
    • AI-detection adapter
    • Humanisation adapter
    • Normalised finding model
  3. Efficiency

    • Content-addressed paragraph cache
    • Save-triggered batching
    • Per-adapter token buckets
  4. Infrastructure

    • Docker
    • GitHub Actions
    • AWS hosting and object storage

Measurements

Status
DeployedIn regular use
External capabilities
3Grammar, AI detection, humanisation
Cache strategy
Content-addressedKeyed on paragraph hash, not TTL