Skip to content

Enforce package source safety policy - #525

Merged
kentcdodds merged 8 commits into
mainfrom
cursor/kody-package-source-safety-policy
Jun 6, 2026
Merged

kentcdodds merged 8 commits into
mainfrom
cursor/kody-package-source-safety-policy

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Jun 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Adds the canonical production package source safety policy at packages/worker/src/repo/source-safety-policy.ts.
  • Surfaces the full policy text in one capability/help location: package_save, the direct whole-source replacement entry point.
  • Keeps clone/publish/session capabilities concise while preserving the runtime gates for explicit destructive overwrite confirmation and restorable snapshot verification.

Enforcement notes

  • package_save verifies the existing package source snapshot before syncing replacement files and requires confirm_destructive_overwrite for existing package replacement.
  • If an existing package Artifacts repo was recreated and ensureEntitySource clears published_commit, package_save verifies the pre-recreation canonical package entity source snapshot before allowing confirmed recovery/bootstrap.
  • package_save verifies against the canonical package entity source, not a potentially stale saved-package source_id pointer.
  • package_publish_external_push / external publish rejects non-fast-forward force publishes unless allow_force and confirm_destructive_overwrite are provided and the current published snapshot is restorable.
  • Repo forced publish RPC paths call the shared policy guard only for package sources.
  • package_get_git_remote verifies a restorable package source snapshot before minting write access, so agents stop before clone/edit/publish if the original source cannot be recovered.

Validation

  • npx vitest run --project node-unit packages/worker/src/repo/source-safety-policy.node.test.ts packages/worker/src/repo/external-publish.node.test.ts packages/worker/src/mcp/capabilities/packages/publish-external-push.node.test.ts
  • npx vitest run --project workers-unit packages/worker/src/mcp/observability.workers.test.ts
  • npx vitest run --project node-unit packages/worker/src/mcp/capabilities/packages/get-git-remote.node.test.ts packages/worker/src/repo/source-safety-policy.node.test.ts
  • npx vitest run --project workers-unit packages/worker/src/mcp/observability.workers.test.ts && npx vitest run --project node-unit packages/worker/src/repo/source-safety-policy.node.test.ts
  • npx vitest run --project node-unit packages/worker/src/repo/source-safety-policy.node.test.ts packages/worker/src/repo/external-publish.node.test.ts
  • npx vitest run --project workers-unit packages/worker/src/mcp/observability.workers.test.ts && npx vitest run --project node-unit packages/worker/src/repo/source-safety-policy.node.test.ts packages/worker/src/repo/external-publish.node.test.ts
  • npm run format:check && npm run lint && npm run typecheck
  • npm run validate
  • PR CI after latest push: ✅ Validate passed, preview deploy passed, CodeRabbit passed, Cursor Bugbot passed.
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added explicit confirmation requirement for destructive package operations (overwrites, force publishes).
    • Implemented source snapshot backup validation to ensure package recovery capability before allowing destructive changes.
  • Improvements

    • Enhanced error messaging for non-fast-forward publish scenarios with clearer safety policy guidance.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented Jun 6, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces destructive-overwrite safety gating for package sources. It creates a source-safety-policy module, marks package mutation capabilities as destructive, adds explicit confirmation inputs, enforces snapshot-restorability and overwrite-authorization checks before non-fast-forward publishes, extends RPC and Durable Object contracts to thread confirmation through publish flows, and validates all changes with comprehensive test coverage.

Changes

Destructive Overwrite Safety Policy for Package Sources

Layer / File(s) Summary
Source safety policy module
packages/worker/src/repo/source-safety-policy.ts
Exports production safety policy constants, destructive-overwrite confirmation metadata, and message builders; implements assertRestorablePackageSourceSnapshot to validate published commits and manifests are restorable; implements assertPackageSourceOverwriteAllowed to enforce explicit confirmation before overwrites.
Safety policy test helpers and coverage
packages/worker/src/repo/source-safety-policy.node.test.ts
Provides entity source and environment mocks for test scenarios; tests overwrite confirmation enforcement, snapshot-restorability validation across missing/malformed/success cases, and verifies policy text placement in capability descriptions.
RPC contract extension
packages/worker/src/repo/repo-session-rpc.ts
Updates RepoSessionRpc type to add optional destructiveOverwriteConfirmed field to publishSession and publishFromExternalRef RPC method payloads.
Durable Object enforcement and forwarding
packages/worker/src/repo/repo-session-do.ts
Extends publishSession and publishFromExternalRef input contracts with destructiveOverwriteConfirmed flag; enforces overwrite authorization for forced package publishes; wraps external-ref checkout in try-catch with recovery messages; forwards confirmation into downstream publish execution.
Source-sync confirmation forwarding
packages/worker/src/repo/source-sync.ts
Extends syncArtifactSourceSnapshot input to accept optional destructiveOverwriteConfirmed flag and conditionally forwards it to session.publishSession.
Save-package capability safety integration
packages/worker/src/mcp/capabilities/packages/save-package.ts
Marks capability destructive; adds confirm_destructive_overwrite optional input; includes production safety policy text in description; enforces overwrite permission check on existing package updates; forwards confirmation to snapshot sync.
Save-package test coverage
packages/worker/src/mcp/observability.workers.test.ts
Expands test mock to include full entity source metadata and bootstrap access; verifies confirm_destructive_overwrite: true is passed through and syncArtifactSourceSnapshot receives destructiveOverwriteConfirmed: true with bootstrap metadata.
Get-git-remote write-scope check
packages/worker/src/mcp/capabilities/packages/get-git-remote.ts, packages/worker/src/mcp/capabilities/packages/get-git-remote.node.test.ts
Adds write-scope restorable-snapshot assertion; updates description; enriches test environment mock with BUNDLE_ARTIFACTS_KV that returns structured bundle metadata for snapshot requests.
External push capability confirmation
packages/worker/src/mcp/capabilities/packages/publish-external-push.ts
Marks capability destructive; adds confirm_destructive_overwrite optional input with confirmation description; updates capability description to reference destructive non-fast-forward requirement; wires input to publishFromExternalRef call.
External push test verification
packages/worker/src/mcp/capabilities/packages/publish-external-push.node.test.ts
Updates test to verify confirm_destructive_overwrite input is forwarded as destructiveOverwriteConfirmed alongside allowForce.
External publish non-fast-forward enforcement
packages/worker/src/repo/external-publish.ts
Extends publishFromExternalRef input with destructiveOverwriteConfirmed field; refactors fast-forward logic: returns updated safety-policy message on non-fast-forward without allowForce, or calls assertPackageSourceOverwriteAllowed with confirmation when allowForce is set.
External publish test coverage
packages/worker/src/repo/external-publish.node.test.ts
Adds loadPublishedSourceSnapshot mock with default setup; extends non-fast-forward test coverage for refusal message, allowForce-without-confirmation rejection, missing-snapshot rejection with recovery error; updates success test to explicitly include destructiveOverwriteConfirmed: true.
Repo publish session metadata
packages/worker/src/mcp/capabilities/repo/repo-publish-session.ts
Marks repo_publish_session capability as destructive.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • kentcdodds/kody#427: Updates publish-external-push capability and publishFromExternalRef error handling for non-fast-forward scenarios; main PR adds confirmation-based gating to the same flow.
  • kentcdodds/kody#253: Persists published-workspace snapshots into BUNDLE_ARTIFACTS_KV via repo_publish_session; main PR loads and validates those snapshots for destructive-overwrite gating.
  • kentcdodds/kody#251: Extends syncArtifactSourceSnapshot to manage published source snapshots in BUNDLE_ARTIFACTS_KV; main PR extends the same function to forward destructiveOverwriteConfirmed into publish execution.

Poem

🐰 A Safety Net for Package Keeps

With confirmation locks now in place,
No thoughtless overwrites disgrace,
The source-sync pipeline stands more strong—
Each destructive change shows right from wrong,
A bunny's blessing on safety done! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Enforce package source safety policy' directly and clearly summarizes the main change: implementing a safety policy mechanism for package sources with confirmation requirements and restorable snapshot validation.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/kody-package-source-safety-policy

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 and usage tips.

cursoragent and others added 2 commits June 6, 2026 20:31
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kody-bot
kody-bot marked this pull request as ready for review June 6, 2026 20:41
@github-actions

github-actions Bot commented Jun 6, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-525.kentcdodds.workers.dev

Worker: kody-pr-525
D1: kody-pr-525-db
KV: kody-pr-525-oauth-kv

Mocks:

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/repo/repo-session-do.ts`:
- Around line 1566-1573: The call to assertPackageSourceOverwriteAllowed is
being applied unconditionally on forced publishSession flows, causing
non-package sources (e.g., syncArtifactSourceSnapshot) to hit a package-only
safety gate; modify the logic around the publish flow so that
assertPackageSourceOverwriteAllowed(...) is only invoked when the source is a
package (check source.type or the appropriate package-identifying field on
source) and skip it for non-package sources, preserving use of input.force and
input.destructiveOverwriteConfirmed for package publishes only; update code
paths in publishSession (where input.force is checked) to branch on source being
a package before calling assertPackageSourceOverwriteAllowed.

In `@packages/worker/src/repo/source-safety-policy.ts`:
- Around line 87-99: The code assumes snapshot.files is an object and calls
Object.keys(files) which throws on malformed snapshots; update the guard to
validate snapshot.files before reading it: check that snapshot is defined and
that typeof snapshot.files === 'object' && snapshot.files !== null (or
Array.isArray check if appropriate), then assign const files = snapshot.files
and compute fileCount and manifestContent; if the validation fails, throw the
same buildSourceRecoveryProblemMessage (using input.source and input.operation)
with a reason like 'the published source snapshot is missing or malformed' so
malformed payloads yield the structured recovery error instead of a raw
TypeError. Ensure references to snapshot.files, files, fileCount,
manifestContent, input.source.manifest_path and
buildSourceRecoveryProblemMessage are used as described.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 88d95629-e0c0-4379-9048-6eaad981cda8

📥 Commits

Reviewing files that changed from the base of the PR and between d70670a and 54e7a6a.

📒 Files selected for processing (15)
  • packages/worker/src/mcp/capabilities/packages/get-git-remote.node.test.ts
  • packages/worker/src/mcp/capabilities/packages/get-git-remote.ts
  • packages/worker/src/mcp/capabilities/packages/publish-external-push.node.test.ts
  • packages/worker/src/mcp/capabilities/packages/publish-external-push.ts
  • packages/worker/src/mcp/capabilities/packages/save-package.ts
  • packages/worker/src/mcp/capabilities/repo/repo-publish-session.ts
  • packages/worker/src/mcp/capabilities/repo/repo-run-commands-text.ts
  • packages/worker/src/mcp/observability.workers.test.ts
  • packages/worker/src/repo/external-publish.node.test.ts
  • packages/worker/src/repo/external-publish.ts
  • packages/worker/src/repo/repo-session-do.ts
  • packages/worker/src/repo/repo-session-rpc.ts
  • packages/worker/src/repo/source-safety-policy.node.test.ts
  • packages/worker/src/repo/source-safety-policy.ts
  • packages/worker/src/repo/source-sync.ts

Comment thread packages/worker/src/repo/repo-session-do.ts Outdated
Comment thread packages/worker/src/repo/source-safety-policy.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Comment thread packages/worker/src/mcp/capabilities/packages/save-package.ts
cursoragent and others added 3 commits June 6, 2026 20:57
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3e9f503. Configure here.

Comment thread packages/worker/src/mcp/capabilities/packages/save-package.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/worker/src/mcp/capabilities/repo/repo-publish-session.ts (1)

16-21: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Restore the canonical package-source safety policy in this description.

repo_publish_session is now marked destructive, but its description no longer surfaces the canonical package-source safety guidance that this PR says should appear on this capability. That leaves this publish entry point out of sync with the new overwrite policy and removes the recovery/confirmation instructions from the agent-facing contract. Please wrap this description with the shared policy helper used by the other package mutation capabilities.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/mcp/capabilities/repo/repo-publish-session.ts` around
lines 16 - 21, The capability's description string for repo_publish_session was
replaced but must be wrapped with the shared package-source safety policy helper
used by other package mutation capabilities; update the description field in
repo-publish-session.ts to pass the existing helper
(withPackageSourceSafetyPolicy) the canonical guidance string so the publish
entry point surfaces the recovery/confirmation instructions and remains
consistent with the new overwrite policy while leaving
readOnly/idempotent/destructive flags as-is.
🧹 Nitpick comments (1)
packages/worker/src/repo/source-safety-policy.node.test.ts (1)

130-146: 💤 Low value

Consider clarifying the test description.

The test description "package mutation capabilities surface the canonical production source safety policy" could be misread as implying all capabilities surface the policy, when in fact it's testing that only savePackageCapability does. Consider a more explicit description such as "only savePackageCapability surfaces the canonical production source safety policy" to improve maintainability and clarity for future developers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/repo/source-safety-policy.node.test.ts` around lines 130
- 146, Update the test's description string to explicitly state that only
savePackageCapability should surface the canonical production source safety
policy (e.g., "only savePackageCapability surfaces the canonical production
source safety policy") so the intent is clear; locate the test block that
asserts expectations against savePackageCapability,
publishExternalPushCapability, getGitRemoteCapability,
repoPublishSessionCapability, repoRunCommandsCapabilityDescription and
productionPackageSourceSafetyPolicy and replace the current description text
with the more explicit wording.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/worker/src/mcp/capabilities/repo/repo-publish-session.ts`:
- Around line 16-21: The capability's description string for
repo_publish_session was replaced but must be wrapped with the shared
package-source safety policy helper used by other package mutation capabilities;
update the description field in repo-publish-session.ts to pass the existing
helper (withPackageSourceSafetyPolicy) the canonical guidance string so the
publish entry point surfaces the recovery/confirmation instructions and remains
consistent with the new overwrite policy while leaving
readOnly/idempotent/destructive flags as-is.

---

Nitpick comments:
In `@packages/worker/src/repo/source-safety-policy.node.test.ts`:
- Around line 130-146: Update the test's description string to explicitly state
that only savePackageCapability should surface the canonical production source
safety policy (e.g., "only savePackageCapability surfaces the canonical
production source safety policy") so the intent is clear; locate the test block
that asserts expectations against savePackageCapability,
publishExternalPushCapability, getGitRemoteCapability,
repoPublishSessionCapability, repoRunCommandsCapabilityDescription and
productionPackageSourceSafetyPolicy and replace the current description text
with the more explicit wording.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 799881cc-44b0-47b8-90d7-bb8f1e4a79a5

📥 Commits

Reviewing files that changed from the base of the PR and between aa0fa62 and 3e9f503.

📒 Files selected for processing (8)
  • packages/worker/src/mcp/capabilities/packages/get-git-remote.ts
  • packages/worker/src/mcp/capabilities/packages/publish-external-push.ts
  • packages/worker/src/mcp/capabilities/packages/save-package.ts
  • packages/worker/src/mcp/capabilities/repo/repo-publish-session.ts
  • packages/worker/src/repo/external-publish.node.test.ts
  • packages/worker/src/repo/external-publish.ts
  • packages/worker/src/repo/source-safety-policy.node.test.ts
  • packages/worker/src/repo/source-safety-policy.ts
💤 Files with no reviewable changes (1)
  • packages/worker/src/repo/source-safety-policy.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/worker/src/mcp/capabilities/packages/publish-external-push.ts
  • packages/worker/src/mcp/capabilities/packages/save-package.ts
  • packages/worker/src/repo/external-publish.node.test.ts

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit 4c52504 into main Jun 6, 2026
5 checks passed
@kody-bot
kody-bot deleted the cursor/kody-package-source-safety-policy branch July 21, 2026 18:58
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.

3 participants