Skip to content

Add Tangled rule-submission backend - #405

Closed
julietshen wants to merge 3 commits into
roostorg:mainfrom
julietshen:julietshen/rule-drafts-tangled
Closed

Add Tangled rule-submission backend#405
julietshen wants to merge 3 commits into
roostorg:mainfrom
julietshen:julietshen/rule-drafts-tangled

Conversation

@julietshen

Copy link
Copy Markdown
Member

Stacked on #402 and the GitLab backend PR. Review those first; this PR's diff will show their commits until they merge.

Adds TangledBackend targeting Tangled, an ATProto-native git host where pulls are records rather than REST resources. The adapter authenticates the configured Bluesky identity, then writes an sh.tangled.repo.pull record (carrying a gzipped git format-patch blob) to the user's PDS via com.atproto.repo.createRecord.

Current limits, both returning 501 with an explanatory message: new rules only (edits would require rendering a diff against the existing file) and no wire_into_main (would require a multi-file patch).

The hand-built patch has a single sanitization choke point: free-text summary lines that git-am would read as patch structure (---, diff -, Index:, From mbox boundaries) are quoted, and newlines/angle brackets are stripped from the From:/Subject: headers, so a crafted summary can't smuggle hunks for arbitrary files into the patch a maintainer applies. Covered by tests, and verified end-to-end with real git am.

Configuration: OSPREY_RULES_SUBMISSION_BACKEND=tangled plus OSPREY_TANGLED_HANDLE, OSPREY_TANGLED_APP_PASSWORD, OSPREY_TANGLED_REPO, OSPREY_TANGLED_REPO_DID (docs in docs/user/manage.md).

Checklist

  • Tests pass locally
  • uv run ruff check . passes
  • Updated CHANGELOG.md

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 64e5b85d-7626-40b9-a0e8-d059be9ff732

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

julietshen and others added 3 commits July 2, 2026 18:02
New ui-api blueprint for authoring SML rule drafts from the UI, with
submission routed through a pluggable backend so each deployment picks
where drafts go for review.

Endpoints (all gated by a new CAN_EDIT_RULE_DRAFTS ability, granted to
super_user): get-source, validate, vocabulary, submit, pending, and
parse-into-builder. Validate and submit splice the draft into the
engine's loaded sources and re-run the same AST validation the engine
uses; submit re-validates server-side before touching any backend.

Backends implement the RuleSubmissionBackend Protocol and are selected
by OSPREY_RULES_SUBMISSION_BACKEND:

- null (default): fails fast with 503 so an unconfigured install never
  writes anything
- github: opens a PR via the REST API; supports GitHub Enterprise
- local: writes into a mounted rules directory

Contract and safety details:

- SubmissionResult/PendingDraft.to_json spread extras first so a
  backend-specific extra can't shadow the canonical title/url/
  main_sml_updated fields the UI depends on
- Forge transport failures (connection refused, timeout) become the
  structured 502 the UI renders, not an unhandled 500, via a shared
  _rule_drafts_git_common.request() helper that also holds the
  branch-name and main.sml Require helpers
- main.sml is rejected as a draft path: wholesale-replacing the engine
  entry point is not a draft; wiring a rule in is the controlled
  wire_into_main append

Adopter docs for the env vars are in docs/user/manage.md. Follow-ups add
the rule-editor UI, a GitLab backend, and a Tangled (ATProto) backend.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZ4RQtuHCCgurfpjfPXXAM
GitLabBackend opens a merge request via the REST v4 API, mirroring the
GitHub adapter: create branch, commit the draft (plus an optional
main.sml Require line), open the MR. Works with gitlab.com and
self-hosted instances via OSPREY_GITLAB_URL. Configured with
OSPREY_RULES_SUBMISSION_BACKEND=gitlab, OSPREY_GITLAB_PROJECT, and
OSPREY_GITLAB_TOKEN.

Shares the branch-name / main.sml Require helpers and the transport-error
wrapper with the GitHub backend via _rule_drafts_git_common, so a GitLab
outage returns the structured 502 the UI renders rather than a 500.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZ4RQtuHCCgurfpjfPXXAM
TangledBackend targets Tangled, an ATProto-native git host where pulls
are records rather than REST resources: it authenticates the configured
Bluesky identity, then writes an sh.tangled.repo.pull record (carrying
a gzipped git format-patch blob) to the user's PDS via
com.atproto.repo.createRecord.

The hand-built patch has a single sanitization choke point: free-text
summary lines that git-am would read as patch structure (---, diff -,
Index:, mbox From boundaries) are quoted, and newlines/angle brackets are
stripped from the From:/Subject: headers, so a crafted summary can't
smuggle hunks for arbitrary files into the patch a maintainer applies.
Shares the branch-name helper and the transport-error wrapper with the
other backends via _rule_drafts_git_common.

Current limits, both returning 501: new rules only (edits would need a
diff against the existing file) and no wire_into_main (multi-file patch).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZ4RQtuHCCgurfpjfPXXAM
@julietshen
julietshen force-pushed the julietshen/rule-drafts-tangled branch from 9c0d4c2 to ea15ebe Compare July 3, 2026 18:25
@julietshen julietshen closed this Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant