AGENTS.md — KSN-01

Purpose

KSN-01 is a proof of concept for a persistent personal layer on top of the web.

The current brick:

Add persistent personal links to text on any webpage without changing the page itself.

A user's annotations live outside the source page. A compatible client renders that layer at read time.

Principles

Architecture

The system is intentionally static-file based:

web page
   +
KSN-01 annotation JSON
   +
client-side renderer
   =
personalized view

Annotation lookup:

raw URL
canonical URL
   ↓ cleanUrl()
normalized canonical URL
   ↓ SHA-256
<hash>.json
static HTTP GET

The source page is never modified.

Annotation format

Use W3C Web Annotation concepts where practical, particularly TextQuoteSelector.

Example:

[
  {
    "selector": {
      "type": "TextQuoteSelector",
      "exact": "impossible dream",
      "prefix": "looked like an ",
      "suffix": ". The only car"
    },
    "href": "https://youtu.be/6FmXjxdDBRI"
  }
]

The resolver currently uses exact, prefix, and suffix to locate text and maps the match back to a native DOM Range.

Do not invent a proprietary selector format without a concrete need.

URL identity

Keep these concepts distinct:

API requests include both URLs as query parameters so ordinary webserver logs provide diagnostic information:

api/<hash>.json?rawUrl=...&canonicalUrl=...

Do not make rawUrl part of identity.

cleanUrl() is deliberately small and replaceable. It currently removes fragments and common tracking parameters while preserving potentially meaningful query parameters.

Do not move URL normalization server-side unless the client-side model demonstrably stops being sufficient.

API

The "API" is currently a directory of static JSON files.

Example:

api/
└── <sha256-of-canonical-url>.json

A missing annotation file is a normal condition:

404 + empty body

Do not turn absence into an application-level error.

Source and builds

src/pw.js is the single implementation source.

Its default base URL is:

const PW_BASE_URL = "http://localhost:8000/";

This allows the project to work with:

cd KSN-01
python3 -m http.server

build.py creates disposable projections.

Current build targets:

local  → https://cx22.localhost/cygnus_x1/labs/KSN-01/
public → https://cx22.ns-x.net/cygnus_x1/labs/KSN-01/

Outputs include bookmarklet and browser-extension versions.

The bookmarklet projection simply flattens newlines. It is not a JavaScript minifier.

Do not edit generated files in dist/.

Dependencies

Default stance: none.

Prefer:

Avoid introducing:

A dependency must solve a demonstrated problem that is unreasonable to solve with existing platform primitives.

Browser clients

Bookmarklet and browser extension are projections of the same core JavaScript.

Future Safari/iOS packaging should remain another projection, not a separate implementation.

Platform-specific packaging is acceptable. Forking core annotation behavior by platform is not.

Scope discipline

Do not prematurely design:

These are future layers.

They may influence today's interfaces, but they should not become today's implementation until the current brick requires them.

Working rule

When considering a change, ask:

What is the smallest change that proves the next behavior while keeping files, protocols, and implementations replaceable?

Prefer one understandable function or file over a new subsystem.