Compact fragment header (1-char codec tag) - #71
Conversation
…<codec>.<dictVer>. Replaces the ~22-char legacy fragment header with a single URL-unreserved tag char that encodes (wire version, codec, dictVersion); arx-family tags imply dictVersion 1. The payload stays self-describing (base64url B. prefix, baseBMP U+FFF0 marker, base76 length prefix), so the alphabet is not encoded in the header. - Encode emits the compact form for every codec (e.g. `d<payload>`, `c<baseBMP>`). - Decode reads both: a fragment starting with `agent-render=` uses the legacy parser unchanged; otherwise char 0 is the codec tag. Collision-free, since the wire alphabets never contain `=`, so existing shared links keep decoding. - Saves the entire header (~18-23 chars) per fragment, which dominates short URLs (the common case) — the win the wire-format research found larger than arx3's own visible-char advantage. Regenerated the precomputed homepage sample links to the compact form and updated the URL-explainer / viewer format references. Pinned by tests/compact-header.test.ts (tag table, round-trip across all codecs, legacy back-compat, savings). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying agent-render with
|
| Latest commit: |
1ff15e7
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://66666d37.agent-render.pages.dev |
| Branch Preview URL: | https://codex-compact-header.agent-render.pages.dev |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c898d1f356
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const payloadEnvelope = { ...envelope, codec }; | ||
| const json = JSON.stringify(packed ? packEnvelope(payloadEnvelope) : payloadEnvelope); | ||
| const value = `${PAYLOAD_FRAGMENT_KEY}=v1.${codec}.${encodePayload(json, codec)}`; | ||
| const value = `${compactTagForCodec(codec)}${encodePayload(json, codec)}`; |
There was a problem hiding this comment.
Update e2e expectations for compact links
Because buildFragment now emits #p/#l/#d... bodies instead of #agent-render=..., the homepage link-creator E2E still asserts the generated textarea and copied value contain #agent-render= (tests/e2e/viewer.spec.ts:65-71). That test is part of npm run test:ci via package.json:32-34, so the CI path fails once the flow reaches link generation; update the Playwright expectations to accept the compact tag format.
Useful? React with 👍 / 👎.
| export const compactCodecTags = { | ||
| plain: "p", | ||
| lz: "l", | ||
| deflate: "d", | ||
| arx: "a", |
There was a problem hiding this comment.
Keep public protocol docs in sync
This tag table changes the public fragment contract to compact #<tag><payload> links, but the docs and agent skill that the homepage points users to still document only the legacy #agent-render=v1... shapes (docs/payload-format.md:11-15, docs/url-fragments.md:22-30, skills/agent-render-linking/SKILL.md:27-31). Users and OpenClaw agents following those files will see stale guidance and keep producing legacy links despite the UI/link creator emitting compact-only links, so update the public docs/skill alongside the protocol change.
Useful? React with 👍 / 👎.
|
| Filename | Overview |
|---|---|
| src/lib/payload/fragment.ts | Core encode/decode logic updated with compact header; back-compat branch for legacy agent-render= fragments is clean and the disambiguation is correctly positional |
| src/lib/payload/schema.ts | Adds compactCodecTags map and compactTagForCodec/codecForCompactTag helpers; tag table is correct and fully pinned by the characterization test |
| src/lib/payload/fragment-arx.ts | ARX candidate builders now emit compact #a/b/c prefix; splitArxFragmentRemainder versioning logic unchanged and handles both compact and legacy payloads correctly |
| src/lib/payload/link-creator.ts | JSDoc updated to reflect compact hash format; getFragmentCodec handles both legacy and compact headers; no issues |
| tests/compact-header.test.ts | New test file: pins the tag table as a characterization test, round-trips all 6 codecs, verifies legacy back-compat decode, and measures header savings |
| AGENTS.md | Updated for compact header format, but arx3 (tag c) is absent from the codec tag list and codec enumeration in both the product-contract and payload-protocol sections |
| docs/payload-format.md | Correctly updated to compact fragment shape including all six tags (p/l/d/a/b/c) |
| skills/agent-render-linking/SKILL.md | Correctly updated with compact fragment shape including all six tags and arx3 description |
| src/components/home/sample-link-data.ts | Precomputed sample links regenerated to compact format; arx showcase uses #c (arx3) |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["Fragment received\n#hash"] --> B{starts with\nagent-render=?}
B -- yes --> C["Legacy parser\nparseLegacyFragmentHeader"]
C --> D["Extract version, codec, encoded\nfrom v1.<codec>.<payload>"]
B -- no --> E["Compact parser\nfragment[0] = tag char"]
E --> F["codecForCompactTag(tag)\np→plain l→lz d→deflate\na→arx b→arx2 c→arx3"]
F -- unknown tag --> G["❌ invalid-format error"]
F -- known tag --> H["encoded = fragment.slice(1)"]
D --> I{arx family?}
H --> I
I -- no --> J["Sync decode\n(plain / lz / deflate)"]
I -- yes --> K["Async decode\ndecodeArxFragmentPayload"]
K --> L["splitArxFragmentRemainder\n(handles legacy dictVersion prefix)"]
J --> M["JSON.parse → envelope validation"]
L --> M
M --> N["✅ ParsedPayload"]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A["Fragment received\n#hash"] --> B{starts with\nagent-render=?}
B -- yes --> C["Legacy parser\nparseLegacyFragmentHeader"]
C --> D["Extract version, codec, encoded\nfrom v1.<codec>.<payload>"]
B -- no --> E["Compact parser\nfragment[0] = tag char"]
E --> F["codecForCompactTag(tag)\np→plain l→lz d→deflate\na→arx b→arx2 c→arx3"]
F -- unknown tag --> G["❌ invalid-format error"]
F -- known tag --> H["encoded = fragment.slice(1)"]
D --> I{arx family?}
H --> I
I -- no --> J["Sync decode\n(plain / lz / deflate)"]
I -- yes --> K["Async decode\ndecodeArxFragmentPayload"]
K --> L["splitArxFragmentRemainder\n(handles legacy dictVersion prefix)"]
J --> M["JSON.parse → envelope validation"]
L --> M
M --> N["✅ ParsedPayload"]
Reviews (2): Last reviewed commit: "Update docs and skills for the compact f..." | Re-trigger Greptile
|
|
||
| // Compact header: a single tag char encodes (version, codec, dictVersion); the payload follows. | ||
| // No compact fragment can begin with the `agent-render=` literal (the wire alphabets exclude | ||
| // `=`), so the two forms stay unambiguous on decode. |
There was a problem hiding this comment.
SUGGESTION: The collision-safety justification here is inaccurate.
The parenthetical "the wire alphabets exclude =" doesn't hold for base76: that wire shape uses = as its extended length marker (BASE76_EXTENDED_LENGTH_MARKER in arx-codec.ts), so a large arx base76 payload is emitted as a=… (i.e. = at payload position 0). The conclusion is still correct, but for a positional reason, not the stated one: a collision would need = at fragment position 12 (the end of agent-render=), while = can only appear at payload-position 0 (= fragment position 1, after the single tag char) for base76, and the other arx wires can't begin with gent-render anyway (B. prefix / non-ASCII base1k / U+FFF0 baseBMP marker). Worth rewording so a future wire variant that places = elsewhere isn't assumed safe.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Incremental review of 2 commits since Previously flagged — now resolved
Other Observations (not in diff)
Files Reviewed (9 files)
Previous Review Summary (commit c898d1f)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit c898d1f)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)SUGGESTION
Other Observations (not in diff)Two items were already flagged by a prior review pass — listing here for a consolidated picture, plus a few additional stale files not yet covered. 1. e2e test breakage (already flagged P1 on 2. Public protocol docs/skill stale (already flagged P2 on 3. Additional stale contract references not covered by the prior P2:
Selfhosted path: Files Reviewed (14 files)
Reviewed by GLM-5.2 · Input: 235.6K · Output: 30.1K · Cached: 832.6K |
The compact header (this PR) emits `#<tag><payload>` links, so the e2e assertions on `/#agent-render=/` for the generated and copied link were obsolete and failed `test:e2e` in CI (`npm run check` excludes e2e, so it passed locally). Assert the generated link is the compact form (not the legacy `#agent-render=`) and that the copied value equals the generated link — format-agnostic, so it survives future tag additions. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The compact header (#<tag><payload>) replaced the legacy agent-render=v1.<codec>.<dictVersion>. form as the emitted format; legacy links still decode. Update the skills external agents follow, the product contract in AGENTS.md, the payload/url-fragment/architecture docs, and the link-creator JSDoc. Also correct the fragment.ts collision-safety comment: base76 uses = as its extended-length marker, so unambiguity holds for a positional reason (tag at fragment[0]), not because the alphabets exclude =. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Collapses the legacy fragment header
agent-render=v1.<codec>.<dictVersion>.(~22 chars) into a single URL-unreserved tag char that encodes (wire version, codec, dictVersion). This is the improvement the wire-format research flagged as larger than arx3's own visible-char advantage — and unlike arx3 it helps every codec and every metric (visible and transport). Stacked on #70.Wire format
#agent-render=v1.deflate.<payload>#d<payload>#agent-render=v1.arx3.1.<baseBMP>#c<baseBMP>Tag table:
p/l/d= plain/lz/deflate;a/b/c= arx/arx2/arx3 (dictVersion 1 implied). The payload stays self-describing (base64urlB., baseBMPU+FFF0marker, base76 length prefix), so the alphabet isn't in the header.Back-compat (no migration)
Decode branches on whether the fragment starts with
agent-render=: if so, the legacy parser runs unchanged; otherwise char 0 is the codec tag. This is collision-free — no compact fragment can begin withagent-render=because the wire alphabets never contain=. So every existing shared link keeps decoding, and new links are compact.Savings
The entire header (~18–23 chars depending on codec) per fragment — a fixed win that dominates short URLs (the common case: a small snippet's header was a large fraction of the URL).
Tests
tests/compact-header.test.tspins the tag table (characterization), round-trip across all six codecs, legacy back-compat decode, and the savings. Existing codec/fragment/link-creator tests updated to the compact format; the legacy decode path stays covered by the back-compat test and the existing legacy-fragment decode tests. Regenerated the precomputed homepage sample links to compact and updated the URL-explainer / viewer format references.npm run checkgreen (lint + 224 tests + bench + typecheck + build + budgets; homepage 107.5 / 115 KiB).Follow-ups (not in this PR)
scripts/bench-codecs.mjsstill measures the legacy header overhead in its visible-char totals (it reimplements encoding independently; the codec comparison is unaffected). Worth refreshing to the compact header in a separate pass.--update-snapshotsrun (e2e isn't part ofnpm run check).🤖 Generated with Claude Code