2ldr;
tldr/v1 v1.0-draft EdProAI
Protocol Specification · Drafted 2026-05-11

The 2ldr; protocol — conformant by design.

An AI-collaborative presentation protocol owned and developed by EdProAI. This document is the canonical contract for how a deck conforms to v1: how it's authored, how humans consume it in the viewer, and how AI agents round-trip critique back into the live discourse.

Conformance string tldr/v1 Reference impl: Stages platform-website chris@teachupbeat.com
01

Eight product values

Every conformant 2ldr; deck honors all eight. These are not aspirations — they're how each surface decision gets made. If a feature violates one, it doesn't ship.

VALUE 01
Clarity over completeness
A v1 reader absorbs the deck in 5–10 minutes. Verbose surfaces are wrong. Every paragraph earns its place.
VALUE 02
Plain ↔ Tech parity
Every substantive surface ships in two voices that toggle from a single global control. Neither voice apologizes for the other.
VALUE 03
AI-collaborative by default
Every deck embeds a documented protocol that lets an external agent post per-slide critique back into the live discourse.
VALUE 04
Brevity as forcing function
Discourse posts cap at 280 characters. Long-form critique routes to a persistent capture surface (the team's tracker, doc store, or note system) referenced by ID from the 280-char post.
VALUE 05
Named-org license scope
Free for the orgs listed in the footer license modal. All other use requires written permission from EdProAI.
VALUE 06
The reader is the pilot
Every viewer boards the deck with name + role + lens + coach areas. The platform tailors itself to their perspective.
VALUE 07
Deck is the conversation; the tracker is the record
Comments are ephemeral panel notes. Decisions, edge cases, and substantive critique belong in the team's persistent capture surface — whatever ticket tracker, doc store, or note system the team uses.
VALUE 08
Cosmic-neon aesthetic
Visual identity is consistent across decks. Design tokens are non-negotiable. Light mode does not exist.
02

Anatomy of a conformant deck

The top-level deck object, the slide object, and the sanitization rules every renderer must apply.

Top-level deck object

Required fields are unmarked. Optional fields are noted as // optional in the comment. The notes_endpoint is the only network dependency in v1.

JSONC schema
{
  "protocol": "tldr/v1",          // required, exact string
  "title": "string",              // required, deck title
  "subtitle": "string",           // optional, appears next to title in chrome
  "generated_at": "ISO 8601",     // required, UTC timestamp of deck creation
  "reviewers": ["string", ...],   // required, predefined reviewer names (humans)
  "branding": {                   // required
    "name": "2ldr;",              // brand mark
    "by": "EdProAI",              // platform owner
    "license_orgs": ["string", ...]  // permitted orgs (footer modal)
  },
  "boarding_pass": {              // optional but recommended
    "enabled": true,
    "coach_options": ["risk", "voice", "missed", "pushback", "overconfidence"]
  },
  "glossary": { ... },              // optional, term → {plain, tech, link}
  "slides": [ ... ],
  "slide_tldrs": { ... },           // optional, per-slide TL;DR pill content
  "notes_endpoint": {             // required
    "url": "https://...",
    "profile": "<deck-slug>-notes",
    "auth_header": "x-my-cache-key",
    "auth_value": "..."            // public — viewers post; rate-limited server-side
  }
}

Slide object

Per-slide JSONC
{
  "id": "kebab-case-id",    // required, unique within deck
  "num": "01",                // required, zero-padded
  "title": "string",           // required, slide title
  "type": "hero|conventions|tldr|stack|why|phases|reqs|risks|code-style|ack|open-mic|agenda|wrap|custom",
  "body_html": "string",       // required, sanitized HTML; uses design tokens
  "plain_only_html": "string", // optional, plain-mode-only content
  "tech_only_html": "string",  // optional, tech-mode-only content
  "glossary_terms": ["..."]   // optional, terms to auto-link in body
}

HTML sanitization

ALLOW
Permitted tags & attributes
Tags: p, div, span, h1-h6, strong, em, code, pre, ul, ol, li, a, br, hr, table, thead, tbody, tr, th, td, blockquote, kbd, i, b, sup, sub, dl, dt, dd, figure, figcaption, img

Attributes: class, id, href (http/https/mailto only), src (http/https/data:image only), alt, title, target, rel, aria-*, data-*, lang, role
DENY
Conformance violations
Tags: <script>, <style>, <iframe>

Attributes: event handlers (onclick=), javascript: URIs, inline style=

The viewer must sanitize on render. Creators should pre-sanitize. Defense in depth.
03

The notes protocol

How discourse flows on a 2ldr; deck. Endpoint contracts, agent rules, threading, and the agenda surface.

Endpoint contracts

POST · agent → deck
POST {notes_endpoint.url}?profile={profile}
Headers:
  x-my-cache-key: {auth_value}
  Content-Type: application/json

Body:
{
  "comment":   string,   // ≤280 chars protocol cap
  "view":      "plain" | "tech",
  "slideId":   string,
  "reviewer":  string,   // human name
  "createdAt": ISO 8601 UTC,
  "parentId":  string    // optional, threading
}
GET · deck/agent → state
GET {notes_endpoint.url}?profile={profile}
Headers:
  x-my-cache-key: {auth_value}

Response:
[
  {
    "id":        "<uuid>",
    "slideId":   "<slide-id>",
    "view":      "plain" | "tech",
    "reviewer":  "<name>",
    "comment":   "<body>",
    "createdAt": "<ISO>",
    "parentId":  "<uuid>"  // replies only
  }, ...
]

Agent-author discourse rules (v1)

These rules apply to AI authors only. Humans post freely.

RULE 01
280-char cap per post
Server allows up to 2000; protocol asks for ≤280. Brevity is the forcing function.
RULE 02
No double-post per slide
Once an author posts to slideId: X, they cannot post to X again until another author posts there. Interleaving with humans is the discipline.
RULE 03
No chunking — overflow to long-form capture
If critique can't fit in 280 chars, file an entry in the team's persistent capture surface (see overflow_capture in §2.1) and reference the entry ID from the 280-char deck post.
RULE 04
AI prefix is [ai]
Literal four chars: open-bracket, lowercase ai, close-bracket, space. Reviewer name stays human (no .AI suffix). Deck strips prefix and flips the human/AI pill to violet.
RULE 05
Pick view deliberately
Plain mode targets non-engineer readers. Tech mode targets architectural critique. Choose the audience.
RULE 06
Combined prefix order
[ai] always first, urgency second: [ai] [urgent:high] <body>.

Threading (replies)

A reply points at a parent via the optional parentId field. Replies render nested below their parent, smaller (13.5px vs 16px) and indented by ~24px with a left-edge accent in the parent author's color.

The agenda slide — three slideIds

Categorical rule: Agents MAY draft agenda items. Agents MUST NOT post agenda items without explicit human direction. "Yes", "go ahead", "post it" qualify. "Maybe", "hmm", "let me think" do NOT.
slideId: "agenda-items"
The actual talking-points list rendered on the slide body — with urgency badges + voting buttons. Sorts by urgency tier first, then chronologically.
slideId: "agenda"
Discussion comments about the agenda — right-side panel chatter. The viewer defensively filters AI-prefixed notes out of this surface to prevent duplication.
slideId: "agenda-votes"
Vote records. Comment format <itemUuid>:up|down|neutral. Deduped client-side per (reviewer, itemId) pair.

Urgency marker

Prefix the comment with [urgent:high], [urgent:medium], or [urgent:low] followed by a space. The viewer parses the marker on render, strips it from the displayed body, and shows a colored urgency badge.

03b

Absorbing-agent polling

How the agent that ate the downloaded 2ldr.md keeps itself in sync as new notes, agenda items, and votes land on the live deck.

Default 120s. Minimum 60s. Never under 30s. The deck viewer polls at 5s because it's optimizing for human perception of liveness; agents have a different cost structure (every poll burns tokens). Sub-minute cadence has negligible signal advantage and meaningful cost.

Change-detection strategy

Track a last_seen_created_at watermark per profile. On each poll: GET the full notes set, filter to createdAt > last_seen_created_at, ingest the filtered items, update the watermark.

Coverage must include all three agenda slideIds — they're separate logical streams in the same profile. An agent that polls only top-level notes misses the talking-points and the vote signal.

Minimum-viable bash snippet

30-line polling loop
# Poll the deck for new activity. Defaults to a 120s cadence.
# Set LAST_SEEN to the most recent createdAt your agent has already ingested.
LAST_SEEN="${LAST_SEEN:-1970-01-01T00:00:00Z}"

while true; do
  RESP=$(curl -sS "$CACHE_ENDPOINT?profile=$PROFILE" \
       -H "x-my-cache-key: $CACHE_SECRET")

  NEW=$(echo "$RESP" | jq --arg ts "$LAST_SEEN" \
       '[.[] | select(.createdAt > $ts)]')

  if [ "$(echo "$NEW" | jq 'length')" -gt 0 ]; then
    echo "$NEW"      # or pipe to your agent's input
    LAST_SEEN=$(echo "$RESP" | jq -r 'max_by(.createdAt).createdAt')
  fi

  sleep 120
done
Sandboxed-agent caveat. Agents in environments without HTTP/curl access (Claude.ai web chat, ChatGPT web, similar sandboxes) cannot poll. The post-via-URL bridge handles agent → deck; there is no symmetric deck → sandbox-agent bridge in v1. The only refresh path is manual re-download — the user clicks "Get the 2ldr.md" again.

Authentication note

The CACHE_SECRET is embedded in the downloaded 2ldr.md by design. The my-cache endpoint enforces rate limits and write quotas server-side; the secret is the application identity, not a per-user credential. Agents do not need a separate read key.

04

Post-via-URL bridge

For sandboxed agents (Claude.ai web, ChatGPT) with no HTTP/curl access. The user clicks once; the deck applies the post under their identity.

1
Agent drafts critique on behalf of the human user
≤280-char body, with the [ai] prefix and any urgency marker.
2
Generates a fresh UUID v4 for the post
Used downstream for replay-attack defense via localStorage['2ldr-seen-post-ids'] (capped at 200 entries).
3
Builds the JSON payload
Fields: id, slideId, view, comment. The reviewer field is intentionally omitted — the deck always uses the clicker's STATE.reviewer, preventing forged-author URLs.
4
Base64-encodes the JSON
Standard or URL-safe base64; the deck handles both.
5
Constructs URL with a fragment — not a query param
<deck-url>#2ldr_post=<base64>. CloudFront signed URLs hash the query string, so ? params break the signature and produce HTTP 403. Fragments bypass server signing entirely.
6
User clicks the link
Deck decodes, validates against the slide enum, dedupes by UUID, applies under the clicker's identity, optimistically renders, POSTs to the notes endpoint, strips the fragment via history.replaceState.

Threat model

AttackDefense
Forged-author linkImpossible — the deck never trusts a reviewer field in the payload, always uses the clicker's boarded identity.
ReplayUUID dedupe via localStorage + fragment stripping after first apply.
Wrong-deck linkHarmless — payload validates against the slide enum; unknown slideId values are silently rejected.
Schema injectionRequired fields validated (id, slideId, comment); malformed payloads rejected.
05

Boarding pass + download for Claude

How the deck learns who's reviewing it, and how the absorbing agent gets enough context to be useful.

Boarding pass

When boarding_pass.enabled is true, the deck captures four fields locally. Boarding is private to the browser — no network POST. The downloaded markdown is the only export path.

FieldTypeStored whereUsed for
namestringlocalStorage[deck-reviewer]Note attribution + color signature
rolestringdeck-boarding-profile.roleGet-my-take prompt + downloaded markdown
lensstringdeck-boarding-profile.lensGet-my-take prompt + downloaded markdown
coach[]string[]deck-boarding-profile.coachGet-my-take prompt + downloaded markdown

Download-for-Claude markdown contents

Every conformant deck must expose a "Get the 2ldr.md" affordance that emits a single markdown file containing:

06

Conformance, license, versioning

Three sets of guardrails: declaring conformance, naming the license scope, and version-locking.

CONFORMANCE
Required <meta> declarations
<meta name="tldr-protocol" content="tldr/v1">
<meta name="tldr-protocol-conformance"
      content="full" | "partial">
<meta name="tldr-protocol-author"
      content="EdProAI">
LICENSE SCOPE
v1 reference deck — five named orgs
Stages Learning · TeachUpbeat · FableVision Studios · Exceptional Lives · IFAW.

All other use requires written permission from EdProAI. The footer modal must name orgs explicitly (no "etc."), reserve all rights not expressly granted, disclaim warranty, and flag the language as statement of intent, not formal legal counsel.

Versioning ladder

VersionMeaning
v1.0-draftCurrent. Surfaces still moving; spec is reference-only.
v1.0Locks once the Stages platform-website deck (canonical reference impl) is approved by Angela's team.
v1.1+Minor additions (new optional fields). Backwards-compatible.
v2.xBreaking changes. The protocol field in the deck object MUST match the spec version the deck conforms to.
07

Inviolable rules — quick reference

Hard rules. Violations are conformance failures, not preferences.

Hard rules at a glance

  • Brand: 2ldr; (lowercase, semicolon). The abbreviation "TL;DR" is the distillation concept — kept distinct. Brand surfaces never collapse to "tldr;" or "TLDR;".
  • Wire-format protocol identifier: tldr/v1 in the deck object's protocol field. Tooling reads this string; humans read the brand.
  • AI identifier: [ai] prefix on the comment text. Reviewer name stays human — no .AI suffix.
  • Bridge URL format: #2ldr_post=<base64> fragment, never ?2ldr_post= query. CloudFront signed URLs depend on this.
  • Note/glossary sanitization allowlist: b, i, strong, em, code, a, br + <span> with class only. NO scripts, NO inline styles, NO event handlers, NO javascript: URIs.
  • my-cache schema strictness: server rejects unknown fields. ALL metadata (urgency, AI marker, parentId, vote payloads) encoded as comment-text prefixes or magic slideIds.
  • Notes panel doesn't show AI chat on the agenda slide — defensive filter hides AI-authored notes from slideId='agenda' to prevent duplication with the agenda-items body.
  • Polling cadence: deck viewer 5s; absorbing agents default 120s, min 60s, never under 30s.
  • Approve/reject permission gate (Wave 2 proposal protocol): honor-system, STATE.reviewer === 'Chris'. Real auth is a future Wave.
  • Hardcoded hex values in body_html are a v1 conformance violation. Use the design tokens (cosmic-neon CSS custom properties).