Roadmap Product site

Overview

Core concepts

Red Pen is one idea wearing four coats. A note is the same object whether you left it in WordPress, an Express app, a static page, or Ableton - and that shared model is exactly what lets the Hub roll every project into one board. This page is the vocabulary; the surface pages show how each platform realizes it.

Spec-driven, not shared code The family has a single written contract (the family spec). Each surface implements it in its own native idiom - PHP on WordPress, middleware in Express, a browser script for static sites, a TypeScript extension in Ableton. Nothing is shared as code; the model is what is shared. When a capability changes, the spec changes first, then each port catches up. That is why some features below are fully present on one surface and still planned on another - see the per-feature notes and the Roadmap.

The three principles

Everything in Red Pen follows from three commitments, covered on the Home page and worth restating because they shape every feature:

The note model

A note is the core object. Every surface stores it differently (a WordPress post, a line in a JSON file, a localStorage entry) but the shape is the contract. These are the fields:

FieldTypeMeaningExample
idstringPort-assigned, opaque, stable for the life of the note. How every other tool (and the Hub) addresses it.n_mqnh6jofiegeo
bodystringThe note text. Plain text, stored raw, always rendered escaped.Header logo is 4px too low
typeenumThe kind of note - see Note types. Stored as the enum key.bug
priorityenumlow / normal / high - see Priorities.high
severityenum, optionalThe impact axis, distinct from priority (which is scheduling). blocker / critical / major / minor / trivial. Empty by default - see Severities.critical
statusenumopen / in_progress / resolved - see Workflow.open
contextstringWhat the note is scoped to, so a surface can show "notes here". On the web this is the page path; see Context./pricing
urlstringA human-resolvable location for the note - usually the page URL. Optional. The Hub uses it for "jump to source".http://localhost/pricing
anchorobject or nullThe element or position the note is pinned to, or null for a context-level note - see Anchors.{ sel: "#logo", x: 0.5, y: 0.5 }
assigneestringWho owns the note. A WordPress user id on WP, a free-text handle elsewhere. Optional - see Assignee.lincoln
agentstringAn AI agent slug when the note is delegated to an agent rather than a person. Empty means a human note - see Assignee & agent.claude
codeScopestringAn optional file or symbol reference attached to an agent note, so the agent knows where to look.src/header.php
repliesarrayA flat, one-level thread: [{ author?, body, createdAt }] - see Replies.[{ body: "Fixed in r482", ... }]
screenshotstring or nullA reference to an attached region capture, or null - see Screenshots.shot_4f2a.webp
createdAtstringISO 8601 timestamp of when the note was created.2026-06-21T07:38:51Z
editedAtstringISO 8601 timestamp of the last field edit, where a surface records it (for example Express stamps it on a body/type/priority edit). Optional.2026-06-21T08:02:10Z
resolvedAtstring, optionalISO 8601 timestamp stamped when a note is resolved, and cleared again on reopen. Feeds the Hub's Resolved column.2026-07-03T15:02:11Z
resolvedBystring, optionalWho resolved the note, where the surface has identity (WordPress records the user's display name; a Hub-originated resolve is left unattributed).Lincoln

Surfaces may carry a few extra platform-only fields (WordPress, for instance, stores a structured context key and template metadata), but the fields above are the portable core that the Hub normalizes against.

Note types

Every note has a type. There are four built-in types; the stored value is the enum key, and the label shown in the UI may differ (and may be localized):

Stored keyShown asUse it for
noteNoteA neutral observation or reminder.
suggestionIdeaA proposed change or improvement.
bugProblemSomething broken that needs fixing.
questionQuestionSomething to clarify or decide.

Custom note types are part of the free core: you can define your own types, each with an optional colour flag, and they merge into every type dropdown and render their colour on the note. This is shipped on WordPress today (defined as Label|#hexcolor lines in Display settings, stored with a ct_ key prefix). On the Express and static surfaces it is planned - see the Roadmap.

Priorities

A note carries one of three priorities: low, normal (the default, sometimes surfaced as "medium"), and high. Priority drives sorting and at-a-glance triage. High priority is rendered in the brand red (#D32F2F) across the surfaces and on the Hub board, so the things that matter stand out without you reading a word.

Severities

Severity is a second, optional axis that answers a different question than priority. Priority is about scheduling - when should this be done. Severity is about impact - how bad is it if it stays. The two are orthogonal: a low-priority, high-severity crash is a real thing (it will hurt badly, but not today), and so is a high-priority, low-severity typo on the launch page. Severity is unset by default and shown only when you deliberately choose one, so it never adds noise to notes that do not need it. There are five keys:

Stored keyShown asUse it for
blockerBlockerStops the work or the release entirely.
criticalCriticalSevere impact - data loss, a broken core flow.
majorMajorA significant problem with a workaround.
minorMinorA small, contained issue.
trivialTrivialCosmetic or nice-to-have.

Only WordPress authors severity today (set in the note form, dev-only). The Hub board and the CSV export display it, and the other surfaces can adopt it later - the field is part of the shared model regardless of which surface writes it.

Status and workflow

Notes move through a small, explicit workflow rather than just existing as sticky notes:

StatusMeaningMarker
openLogged, not started. Keeps its pin on the page.Brand red
in_progressBeing worked on. Keeps its pin.Amber
resolvedDone. Drops out of the active list and its pin is removed.(hidden from active)

Resolving a note clears it from the working view; reopening brings it back. The overlay's panel is organized into Open / (In Progress) / Resolved tabs with live counts so you always know what is left. Resolve also offers an undo in case you closed the wrong one.

A resolve now also records when it happened - a resolvedAt timestamp, cleared again on reopen - and, on surfaces that have identity, who did it (resolvedBy; WordPress stores the user's display name). The Hub board surfaces both as its Created and Resolved columns, so you can see and sort by when each note opened and closed.

Surface difference The full three-state model (Open / In progress / Resolved) is shipped on WordPress. The Express middleware and the static drop-in are two-state today (Open / Resolved); the third state is planned for Express v0.5.0, with the static surface tracking it. The Hub understands all three states regardless, treating anything that is not in-progress or resolved as open.

Context and scoping

Every note belongs to a context, which is how a surface answers "what notes are on this page / this thing?":

Anchors and pinning

A note can be pinned to a specific spot, or left at the context level (anchor: null). Pinning is what turns "the button near the header" into a note that points at the exact button.

On the web surfaces, an anchor is { sel, x, y }: a CSS-selector path to the element (it prefers an #id, otherwise builds an nth-of-type chain), plus a relative position x / y from 0 to 1 within the element's box. To create one you click Pin, then click the element. A numbered red marker then renders over that element and repositions as the page scrolls or resizes; Locate on a note scrolls to and briefly flashes its element.

In Ableton, an anchor is platform-specific - a beat range from an arrangement selection, or the identity of a clip, track, or scene. Locating there means jumping to or selecting that object through the Live API (native cue points for time anchors).

Threaded replies

Each note can carry a flat, single-level thread of replies - [{ author?, body, createdAt }]. You add a reply from the overlay, and the thread shows on the note and in the repository. It is enough to capture a back-and-forth ("is this still happening?" / "fixed in the last deploy") without turning Red Pen into a full discussion tool.

Screenshots

A note can carry an optional region capture: drag a box around any area of the page and the snip is attached to the note (captured with html2canvas, stored as a small WebP or data URL). The capture shows on the note and in the repository, and is served gated like everything else (a capability check plus nonce on WordPress; a local file under the notes directory on Express). Screenshots ship on WordPress today; they are planned for Express v0.3.0, with the static surface tracking the Express line.

Assignee and agent

Two related fields record who a note is for, and they are how Red Pen distinguishes manual work from automated work:

An agent consumes its queue locally, with no keys and nothing leaving the machine, in one of two ways: a filtered query (for example GET /notes?agent=claude) or an auto-maintained agent-<slug>.json brief file it reads off disk. In practice "check for red pens" means: pull the open notes (optionally one agent's), fix them, and mark each resolved.

Surface difference The assignee and agent model is fully implemented on WordPress today. On the Express and static surfaces, and on the Hub, treating people and AI agents as assignable owners is planned - the Hub will surface and set the assignee through its write-back path. Until then, the Hub shows whatever assignee data a connected WordPress source already carries. See the Roadmap.

Export and import

Your notes are never trapped. JSON export and import is the universal escape hatch and is never gated - it is a free-core promise, not a PRO feature. The static drop-in ships full JSON export and import today (the way to move browser-local notes between machines or share them); WordPress exports notes as well; the Express middleware has JSON export and import planned. The point of the principle is constant even while the implementations catch up: you can always get your notes out.

How the surfaces relate

Because all five surfaces speak the same note model, a fifth piece can aggregate them: the Red Pen Hub reads each surface's store through a small adapter, normalizes every note to the fields above, and shows them on one board - tagging each with its project and surface. The Hub is also where the model's two-way side lives today: you can resolve or reopen a note from the board and it writes back to the real source. Everything the Hub does rests on this shared vocabulary.

From here, head to the page for the surface you are using: