Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions docs/rcp/v1.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Runtime Context Protocol — RCP v1.0.0

> **RCP v1.0.0 — published from `@domscribe/protocol@1.0.0`**
> **RCP v1.0.0 — published from [`@domscribe/protocol@1.0.0`](https://www.npmjs.com/package/@domscribe/protocol/v/1.0.0)**
>
> Status: **stable**. Specifies the agent-facing contract that an IDE, coding agent, or other tool consumes to read Domscribe's manifest and annotation state at runtime.
>
> Release tag: [`protocol-v1.0.0`](https://github.com/patchorbit/domscribe/releases/tag/protocol-v1.0.0). CHANGELOG: [`packages/protocol/CHANGELOG.md`](../../packages/protocol/CHANGELOG.md). Publish runbook: [`docs/release/v1.0.0-protocol-publish-runbook.md`](../release/v1.0.0-protocol-publish-runbook.md).

RCP is the protocol that Domscribe ships against. The implementation in this repository is one conformant implementation; the protocol is the unit IDE vendors, agents, and downstream tools integrate against. The shapes, names, and stability policy in this document are versioned by `@domscribe/protocol`. Any RCP consumer can depend on `@domscribe/protocol` directly to get the typed wire shapes — no transitive dependency on Domscribe's relay or runtime is required.

Expand Down Expand Up @@ -277,7 +279,7 @@ If a contributor is unsure, they should treat the change as breaking and route i

## 8. Reference

- Source of truth for shapes: package `@domscribe/protocol@1.0.0` on npm.
- Source of truth for shapes: package [`@domscribe/protocol@1.0.0`](https://www.npmjs.com/package/@domscribe/protocol/v/1.0.0) on npm; release tag [`protocol-v1.0.0`](https://github.com/patchorbit/domscribe/releases/tag/protocol-v1.0.0).
- Reference server implementation: `@domscribe/relay` (this repository).
- Architecture and decision record: [`docs/rfcs/0001-rcp-as-versioning-unit.md`](../rfcs/0001-rcp-as-versioning-unit.md).
- MCP specification: <https://modelcontextprotocol.io>.
Expand Down
73 changes: 73 additions & 0 deletions docs/release/v1.0.0-protocol-changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# `@domscribe/protocol` CHANGELOG

> This file is the seed of `packages/protocol/CHANGELOG.md`. It lives in `docs/release/` while the package extraction (#32) lands in parallel. The publish operator (see `v1.0.0-protocol-publish-runbook.md` step 3) relocates it into `packages/protocol/CHANGELOG.md` on the publish branch.

## 1.0.0 — unreleased

Initial public release of the typed wire contract for the **Runtime Context Protocol (RCP)**.

### Added

- **Wire schemas**: Zod schemas and exported TypeScript types for `ManifestEntry`, `RuntimeContext`, `Annotation`, `AnnotationSummary`, `SourcePosition`, `StyleInfo`, and the RFC 7807 `ProblemDetails` error envelope. Stability classes (`stable` vs `experimental`) per field documented in `docs/rcp/v1.md` §5.
- **`MCP_TOOLS`**: the frozen v1 tool descriptor table — `{ canonical, aliases, input_schema, output_schema, description }` per entry. All 13 tools canonicalised on the underscore grammar (`/^[a-zA-Z0-9_-]{1,64}$/`) with dotted-form aliases (`domscribe.resolve`, …) retained through the v1.x minor cycle for migration. See `docs/rcp/v1.md` §3 and §7.4.
- **`DomscribeErrorCode`**: the frozen v1 error vocabulary as a TypeScript string-literal union and a runtime constant array. Twenty-two codes; see `docs/rcp/v1.md` §6.
- **`WS_EVENTS`**: the websocket event-name constants used for relay → consumer push semantics where transport supports it. Names frozen for v1; v1 transport binding remains MCP/stdio (`docs/rcp/v1.md` §2), so `WS_EVENTS` is informational on the v1.0 surface and reserved for v1.x bindings if they ship.
- **Prompt-name constants**: `process_next`, `check_status`, `explore_component`, `find_annotations` (see `docs/rcp/v1.md` §4).
- **`SourcePosition` required** on every `resolve_*` and `query_*` output schema. Calls that cannot produce a source location are non-conformant for v1; the schema rejects responses missing the field. This is the load-bearing differentiation against runtime-only MCPs.
- **Stability policy** documented and falsifiable in `docs/rcp/v1.md` §7. Additive minor changes (§7.2), patch scope (§7.3), the dotted-alias migration window (§7.4), and the dual-version deprecation policy for v2 (§7.5) are all normative.

### Not included (by design)

- **No `DomscribeError` runtime class.** The error _envelope_ (`ProblemDetails`) is frozen here; the runtime class that constructs envelopes stays in `@domscribe/core` so that internal refactors of error construction do not trigger a protocol bump. See RFC 0002 §3.2.
- **No ID generators** (nanoid wrappers, manifest-entry ID alphabets). Same reason — implementation detail, not wire contract.
- **No `FrameworkAdapter` SDK.** Explicit out-of-scope for v1 per RFC 0001 and RFC 0002. The framework-extension surface lives behind `@domscribe/runtime` internals and is not part of the v1 conformance target.
- **No transports other than MCP/stdio.** v1 binds to MCP only; gRPC/JSON-RPC/WebSocket bindings, if they ship, will be in `@domscribe/protocol@1.x.0` per §7.2 or `@domscribe/protocol@2.0.0` per §7.5 depending on whether the wire shapes need to change.

### Migration from v0.5.x consumers

If you were depending on schema types via `@domscribe/core`:

```diff
- import type { ManifestEntry } from '@domscribe/core';
+ import type { ManifestEntry } from '@domscribe/protocol';
```

`@domscribe/core` re-exports the schemas from `@domscribe/protocol` through the v1.x minor cycle for backwards compatibility, with a deprecation warning at import time in development builds. Cut the dependency over at your convenience; the re-export is not guaranteed past v1.x.

Tool name migration (see `docs/rcp/v1.md` §7.4):

```diff
- "tools": ["domscribe.resolve", "domscribe.manifest.query"]
+ "tools": ["domscribe_resolve", "domscribe_manifest_query"]
```

Dotted names continue to resolve through v1.x with a server-side deprecation log; canonical underscore names should be used in all new `.mcp.json` configs.

### Telemetry

`@domscribe/protocol` itself does not emit telemetry. The reference relay (`@domscribe/relay@>=0.6.0`) ships fire-and-forget opt-in telemetry default-off; configured via `.domscribe/config.json` `telemetry.enabled`. Payload shape and endpoint policy are documented in `docs/rcp/v1.md` §… (see relay docs for the exact path) and the v1.0.0 publish runbook. The protocol package is wire-only and has no runtime side effects.

### Compatibility matrix at release

| Package | Version compatible with `@domscribe/protocol@1.0.0` |
| ---------------------- | --------------------------------------------------- |
| `@domscribe/relay` | `>=0.6.0` (the release coordinated with #32–#34) |
| `@domscribe/core` | `>=0.6.0` |
| `@domscribe/runtime` | `>=0.6.0` |
| `@domscribe/mcp` | `>=0.6.0` |
| `@domscribe/next` | `>=0.6.0` |
| `@domscribe/react` | `>=0.6.0` |
| `@domscribe/vue` | `>=0.6.0` |
| `@domscribe/nuxt` | `>=0.6.0` |
| `@domscribe/overlay` | `>=0.6.0` |
| `@domscribe/transform` | `>=0.6.0` |
| `@domscribe/cli` | `>=0.6.0` |

The other packages are not promoted to 1.0.0 in this release. RCP is the unit being stamped; the implementation continues at the 0.6.x line until separate, explicit decisions promote each package's own SemVer line. See RFC 0001 §"versioning unit" for the reasoning.

### References

- Specification: `docs/rcp/v1.md`
- Decision record: `docs/rfcs/0001-rcp-as-versioning-unit.md`, `docs/rfcs/0002-protocol-v1-execution.md`
- Sprint context: `docs/sprints/2491.md`
- Source: https://github.com/patchorbit/domscribe
212 changes: 212 additions & 0 deletions docs/release/v1.0.0-protocol-publish-runbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# `@domscribe/protocol@1.0.0` — publish runbook

> **Audience:** the operator (Kaushik or a designated maintainer) who executes the actual publish.
> **Owned by:** issue #39.
> **Prereqs:** every item below must be true before step 5. The runbook intentionally separates the reversible steps (1–4) from the one-way step (5).

This runbook is the gated operator procedure for shipping `@domscribe/protocol@1.0.0` to npm and meeting the sprint-2491 trip-wire acceptance criteria. The PR that introduces this file is **not** the publish event — the publish event is a manual run of steps 5–8 below.

---

## 0. Prereqs (must all be merged into `main` before step 5)

| Issue | Provides | Verified by |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| #32 — extract `@domscribe/protocol` | `packages/protocol/` exists; six locked exports per RFC 0002 §3.2; `nx run protocol:build` green | `ls packages/protocol && cat packages/protocol/package.json` shows `"version": "1.0.0"` |
| #33 — snake_case canonical + aliases | All 13 tool names canonicalised; dotted aliases registered at the MCP SDK layer; deprecation log on alias hit | `nx run domscribe-relay:test` covers both name variants; `domscribe-test-fixtures` e2e green |
| #38 — `SourcePosition` required | Zod output schemas for `resolve_*` and `query_*` require `source_position`; integration tests fail if relay emits a response without it | `nx run protocol:test` covers the negative case |
| #34-infra — Cloudflare Worker + KV | Telemetry endpoint live and load-tested; URL captured in `.env`/CI; `2s` write-side timeout enforced | `curl -X POST <endpoint>` returns `204` for a valid payload |
| #34-client — relay startup POST | `.domscribe/config.json` schema has `telemetry.enabled`; `npx domscribe init` prompts with payload inline; flag default off | Integration test confirms zero network call when flag is false |
| #35 — `docs/rcp/v1.md` stability spec | Already on `main` as of c3fe5d1 (PR #36) | `docs/rcp/v1.md` §7 present |

If **any** row is unchecked, **stop**. Per PE RFC 0002: partial v1 is strictly worse than late v1. Slip the sprint close before shipping a partial.

The PR that introduced this runbook intentionally does not gate-check the prereqs in CI — they belong to other PRs and would create circular merge dependencies. The operator confirms the table above manually before step 5.

---

## 1. Pre-publish sanity (reversible)

Run from a freshly-cloned `origin/main`:

```bash
git clone https://github.com/patchorbit/domscribe.git /tmp/domscribe-publish
cd /tmp/domscribe-publish
pnpm install --frozen-lockfile
pnpm run build:all
```

Expected: green. If red, fix the underlying issue and re-merge to `main` before continuing — do not publish from a broken `main`.

Then inspect the package surface that will ship:

```bash
ls dist/packages/protocol
cat dist/packages/protocol/package.json | jq '.name, .version, .exports'
node -e "console.log(Object.keys(require('./dist/packages/protocol')))"
```

Confirm against RFC 0002 §3.2 — the export shape must be exactly: wire schemas, `MCP_TOOLS`, `DomscribeErrorCode`, RFC 7807 envelope, `WS_EVENTS`, prompt-name constants. **No DomscribeError runtime class, no ID generators** — those stay in `@domscribe/core` per the design.

If the export shape drifted, **stop** — file a follow-up issue and rebase #32 before re-attempting.

---

## 2. Update version banner in `docs/rcp/v1.md`

Per the issue #39 acceptance criterion "docs/rcp/v1.md version banner links to tag," the v1 spec's version banner should resolve to the GitHub release page once the tag exists.

This PR introduces the banner-link change. The link will 404 until the tag is pushed in step 5 — that is intentional and matches the publish ordering.

---

## 3. Update `packages/protocol/CHANGELOG.md`

The CHANGELOG entry for v1.0.0 lives in `docs/release/v1.0.0-protocol-changelog.md` in this PR. When #32 lands and `packages/protocol/` exists in `main`:

1. Move the file: `git mv docs/release/v1.0.0-protocol-changelog.md packages/protocol/CHANGELOG.md`.
2. If a CHANGELOG already exists in `packages/protocol/` from #32, merge the entries — v1.0.0 goes at the top.
3. Commit on the publish branch (step 4).

This sequencing avoids merge conflicts between #39 and #32: this PR adds the entry in `docs/release/`; the publish operator relocates it.

---

## 4. Cut the publish branch

```bash
git checkout -b chore/publish-protocol-v1.0.0
# Step 3 file move + any final wording tweaks
git commit -m "chore(protocol): prep 1.0.0 release"
git push -u origin chore/publish-protocol-v1.0.0
```

Open a PR from this branch with the **Kaushik-signed-off** release post (from `docs/release/v1.0.0-protocol-release-post.md`) in the description. Squash-merge.

---

## 5. Publish to npm — **one-way step**

> Beyond this point is irreversible without an `npm unpublish` (subject to npm's 72-hour cliff and the irreversible 7-day post-publish hold). Get Kaushik's explicit "go" before tagging.

The repo's `.github/workflows/publish.yml` triggers on `v*` tags and publishes via `nx release publish` with OIDC trusted publishing. For the protocol-package release we use a project-scoped tag pattern; the operator picks **one** of the two paths below depending on how #32 wired the release config.

### Path A — independent project versioning (preferred, per RFC 0002)

If `nx.json`'s `release` block configures `projectsRelationship: "independent"` (added by #32):

```bash
# From a fresh main with prereqs merged
nx release version 1.0.0 --projects=protocol --git-commit --git-tag --tag-version-prefix='@domscribe/protocol@v'
git push origin main --follow-tags
```

The tag pushed will look like `@domscribe/protocol@v1.0.0`. **Confirm the publish workflow's tag filter matches this pattern** before pushing — if `publish.yml` still filters only on `v*`, the workflow will not fire and a manual `pnpm publish --filter @domscribe/protocol` is required.

### Path B — fallback per-package manual publish

If independent versioning was not configured by #32:

```bash
cd dist/packages/protocol
npm publish --access public --provenance
```

This requires `NODE_AUTH_TOKEN` in the local env, **or** running this step from a temporary CI workflow that uses the same OIDC config as `publish.yml`. **Path B is the fallback** — it does not produce a GitHub Release and skips provenance attestation if run outside CI. Prefer Path A.

After either path, push the documentation tag:

```bash
git tag protocol-v1.0.0 -m "RCP v1.0.0 — see docs/rcp/v1.md"
git push origin protocol-v1.0.0
```

This is the tag the `docs/rcp/v1.md` version banner links to.

---

## 6. Verify resolvable on npm (acceptance criterion 1)

From a **non-author machine** (not the publish operator's workstation — borrow a teammate's machine, a fresh GitHub Codespaces container, or a Vercel Sandbox):

```bash
mkdir /tmp/domscribe-protocol-smoke && cd /tmp/domscribe-protocol-smoke
echo '{ "name": "smoke", "version": "0.0.0" }' > package.json
pnpm add @domscribe/protocol@1.0.0
```

Expected:

- Resolves to `1.0.0` (not a prerelease or dist-tag).
- Zero `WARN` lines from pnpm.
- `node_modules/@domscribe/protocol/package.json` shows `"name": "@domscribe/protocol"` and `"version": "1.0.0"`.

Smoke-test the exports:

```bash
node -e "const p = require('@domscribe/protocol'); console.log(Object.keys(p).sort().join(', '))"
```

Expected: the six locked exports from RFC 0002 §3.2 — wire schemas, `MCP_TOOLS`, `DomscribeErrorCode`, the RFC 7807 envelope helpers, `WS_EVENTS`, prompt-name constants. **If you see `DomscribeError` (the runtime class) or ID generators, stop** — the build leaked internals; file an issue and unpublish if still inside npm's 72-hour window.

---

## 7. Telemetry smoke (acceptance criterion 3)

From the same fresh non-author machine, set up a minimal Domscribe install with telemetry opted in:

```bash
mkdir /tmp/domscribe-telemetry-smoke && cd /tmp/domscribe-telemetry-smoke
pnpm dlx create-next-app@latest . --typescript --no-eslint --no-tailwind --app --src-dir --import-alias '@/*'
pnpm add @domscribe/relay @domscribe/next
pnpm dlx domscribe init
```

When `domscribe init` prompts for telemetry, **answer yes**. Confirm the payload preview in the prompt matches `{ relay_version, week_iso, session_count }` per RFC 0002 §3.5 — if the preview is misleading or missing, abort the smoke and re-open the npx UX issue from #34-client before counting the falsifier as instrumented.

Start the relay:

```bash
pnpm dlx domscribe start
```

Wait 5–10 seconds for the startup POST. Then confirm receipt at the Cloudflare Worker by tailing the Worker logs (Cloudflare dashboard → Workers → `domscribe-telemetry` → Logs → Live tail) or via `wrangler tail` if you have the operator credentials.

Expected: **exactly one** POST arrives from the smoke install with the expected payload shape. If zero sessions arrive, the instrumentation is broken (not the bet); block the release post and debug the `npx domscribe init` UX before publication per PM replanning trigger.

---

## 8. Publish the release post (acceptance criterion 4)

Once steps 6 and 7 are green:

1. Confirm Kaushik signoff on `docs/release/v1.0.0-protocol-release-post.md` is recorded in the PR review thread for this runbook's publish PR.
2. Post the LinkedIn long-form first, then the X thread, then the patchorbit.com canonical blog. Order matters — LinkedIn is the discovery surface, X mirrors, blog anchors.
3. Update the GitHub Release for the tag with the LinkedIn URL in the body.

---

## 9. Close-out

- Mark issue #39 closed with a link to the npm package page (`https://www.npmjs.com/package/@domscribe/protocol/v/1.0.0`).
- Capture the first telemetry session ID in a comment on the issue so future verifiers can correlate.
- Flag in the sprint review whether the 2026-08-20 inherited DOP falsifier (≥1 IDE-vendor doc reference OR ≥1 third-party framework adapter merged OR ≥200 weekly active relay sessions OR published RCP spec) needs a tracking issue opened — published RCP spec is now satisfied (criterion d), so the falsifier is met regardless of the other three, but instrumentation for c remains useful for the next memo.

---

## 10. Rollback (if something is wrong post-publish)

`npm` allows unpublish within 72 hours of publication for packages that have no dependents. The protocol package will have no public dependents until at minimum the next Domscribe release pins to it, which is a separate PR — so the 72-hour window is real.

If a rollback is needed:

```bash
npm unpublish @domscribe/protocol@1.0.0
```

Then:

- Delete the GitHub Release and the `@domscribe/protocol@v1.0.0` / `protocol-v1.0.0` tags.
- Revert the version-banner link change in `docs/rcp/v1.md` (so it does not point to a deleted release page).
- Open a follow-up issue capturing the rollback cause; do not re-publish `1.0.0` — bump to `1.0.1` after the fix per npm's no-republish-version policy.
- Pull the release post from LinkedIn / X / blog. The framing was load-bearing; a published-then-retracted post damages the positioning the sprint bet hinges on.
Loading
Loading