docs: correct RFC 0002 stale references and migration claims - #47
Draft
omarshahine wants to merge 9 commits into
Draft
docs: correct RFC 0002 stale references and migration claims#47omarshahine wants to merge 9 commits into
omarshahine wants to merge 9 commits into
Conversation
The RFC's builder inventory, helper references, and step 1 migration claim drifted from openclaw/openclaw main. Corrects them against current source, adds the forwarder fallback path it omitted, and opens the native-path enforcement gap found while scoping implementation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
The added Motivation paragraph named eight channels as having no approval render adapter. Google Chat and QQ Bot were wrong: both declare native approval capabilities and never reach the forwarder fallback. The real group is the six auth-only capabilities built with createChannelApprovalAuth. Also drops the claim that all of them show raw markers. Mattermost renders markdown server-side, so it needs a markdown declaration despite carrying an auth-only capability, and migration step 1 now says to assess each channel against its transport rather than its capability shape. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
Scopes the losslessness claim to content rather than bytes: the projection trims the overall message edges, so conformance should assert the command, id, and instructions survive as substrings. Verified fenced content mid-body is preserved exactly, which is the shape approval builders emit. Resolves a contradiction between the migration order and the new open question: iMessage has a native runtime and sits at the plaintext default through step 1, so the unenforced path is reachable, not hypothetical. Narrows the Slack/Discord rationale, which author native approval payloads and are never reached by the forwarder default either way. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
Shows a real exec approval prompt as core emits it today alongside the
verified output of the specified downgrade, so reviewers can see what the
plaintext default actually produces rather than infer it.
Makes the content-lossless guarantee concrete: zero residual backticks, and
the pending command survives byte-for-byte including the quoting in
-w "%{http_code}" that a naive regex stripper would corrupt.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
…n escaping rule Adds a rendered before/after of the worked example on iMessage, placed in the sidecar folder the repo README specifies for RFC assets. iMessage is the illustration because it shows opting in does not mean reproducing the markdown: its typed-run vocabulary cannot express a fenced block at all, so a faithful translation drops the construct and promotes the labels to bold instead. Building the illustration surfaced a gap. The auto-review rationale is model-generated text, so bolding it makes core wrap markers around content it does not control. Adds the rule that emphasis over non-fixed content must escape the payload first, plus a matching test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
Delivery proof as previously written was absolute, which cannot detect the dominant risk in this work: a silent regression on a channel that already renders. Specifies baseline-vs-change capture from the transport side, with an empty diff required for markdown channels and a markers-only diff for defaulted ones. Also records that iMessage has no reachable CI lane and never will, since it needs macOS and a local bridge. Its proof is a human gate on a development gateway, which the migration should plan for rather than assume away. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
Complements the mock with the two states delivered to a real iMessage: step-1 plaintext downgrade and step-2 typed-run bold labels, both through the normal send path. The step-2 image uses the exact ranges extractMarkdownFormatRuns produces, and the command text survives verbatim in both. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Q7d86Ww4vJwxJwY4z1AVx6
Real-device render of the approval prompt before (main, plain labels) and after (bold headers and labels via the profile-driven formatter).
|
ClawSweeper status: review started. I am starting a fresh review of this pull request: docs: correct RFC 0002 stale references and migration claims This is item 1/1 in the current shard. Shard 0/1. This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking. Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related: openclaw/openclaw#85954
What Problem This Solves
RFC 0002 is
status: accepted, so it is the specification anyone implementsagainst. Scoping that implementation against current
openclaw/openclawmainturned up four places where the RFC no longer matches the code, one of which
would produce a user-visible regression if followed literally.
buildFence. That helper was removed inrefactor: consolidate markdown code fences, error coercion, and byte-identical helper pairs openclaw#99932. Core now uses
formatFencedCodeBlockandformatInlineCodeSpanfromsrc/shared/markdown-code.ts.src/infra/exec-approval-forwarder.ts. That is the path every channel withan approval capability but no render adapter uses, which means the RFC omits
the path actually carrying the problem it describes.
reproduces today's plaintext." That holds only for channels that render
nothing. Telegram, Matrix, Signal, WhatsApp, Slack, and Discord render the
subset today, so defaulting them to plaintext would strip formatting they
currently ship.
markdownas "wiring the approvalpath to skip the downgrade and reuse the existing converter." The existing
converter handles bold, italic, underline, and strikethrough but ignores
inline code and fences, so that step needs converter work first.
Why This Change Was Made
Corrects each of the four against current source and records two implementation
findings that belong in the spec rather than in a reviewer's head.
The migration section is rewritten so the channels that already render declare
approvalText: "markdown"in step 1 alongside the contract, instead of in alater step. This is the substantive change: it is what keeps step 1 from
regressing six channels, and it is now stated plainly that step 1 is not
behavior-neutral rather than left as a claim a future implementer would
discover was false.
Two additions to the Proposal capture things that are easy to get wrong and
look correct in review:
resolveChannelApprovalCapability, not theresolveChannelApprovalAdapterprojection, which copies a fixed field listand returns nothing for auth-only capabilities. Most channels this contract
is meant to fix are auth-only.
stripMarkdownand pinsmode: "plain-text"andlinkStyle: "label-and-url". The first prevents thespeech-mode punctuation cleanup from rewriting a shell command inside its own
fence. The second keeps a link destination visible to the approver, which is
a security property of an approval prompt rather than a formatting choice.
One question is reopened. Core can enforce the downgrade on the forwarder path,
but the native approval runtime path returns channel-specific payload types
with no shared text field, so channels there honor their declared mode
themselves and a conformance test can only prove a mode was declared, not that
it was obeyed. The alternative is threading an explicit text mode into the two
shared pending-prompt builders. The gap is currently unreachable because every
channel on that path renders markdown, so it does not block step 1, but it
should be settled before any channel on that path declares plaintext.
No change to the accepted design: the canonical subset, the
approvalTextcapability, the default, and the three previously resolved questions all stand.
User Impact
No user-visible impact. This is specification text.
For implementers, following the RFC as previously written would have regressed
approval prompt formatting on Telegram, Matrix, Signal, WhatsApp, Slack, and
Discord, and would have sent someone looking for a helper that no longer
exists.
Evidence
Every corrected reference verified by reading current
openclaw/openclawmainat
025e6ceee0a:src/shared/markdown-code.ts:22,29—formatInlineCodeSpan,formatFencedCodeBlock.buildFenceabsent; removed in49cc59b1e88.src/infra/exec-approval-forwarder.ts:230,293,299,406— the omitted fallbackbuilders and the
buildApprovalRenderPayloaddispatch.src/channels/plugins/approvals.ts:12,28-44— the capability resolver versusthe adapter projection that drops unknown fields and returns
undefinedforauth-only capabilities.
src/shared/text/strip-markdown.ts:88-105,109—cleanSpeechTextgated tomode: "speech", and thestripMarkdownentry point.src/infra/approval-handler-runtime.ts:188— the native runtime factory whoseTPendingPayloadgeneric prevents a core-side downgrade.extensions/imessage/src/markdown-format.ts:147—extractMarkdownFormatRunscovering bold, italic, underline, and strikethrough only.
extensions/*/src/channel.ts:fifteen declare
approvalCapability; onlytelegramcarries arenderadapter.
Prose-only change, so no tests or CI beyond the repo's markdown rendering.
Frontmatter keys and the required section set are unchanged, and all lines stay
within the 80-column wrap used by the rest of the document.