Skip to content
Merged
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
65 changes: 65 additions & 0 deletions .agents/skills/executor-selfhost-upgrade/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
name: executor-selfhost-upgrade
description: Rebase the Executor dev fork onto current upstream/main, promote the reviewed history safely, update the linked selfhost checkout, reconcile its Cloudflare host, and deploy with explicit production gates. Use for full upstream-to-production upgrades, not ordinary feature PRs.
---

# Executor selfhost upgrade

Upgrade the fork and hosted instance without conflating their three repositories or silently widening authorization.

## Choose the phase

Start in the least-mutating phase that satisfies the request:

- **Inspect** is read-only. Refresh remote-tracking refs when current upstream state is requested, run the preflight helper, and report drift.
- **Prepare** creates an isolated rebase candidate, resolves supported conflicts, and validates it. It does not change `dev`, selfhost, or production.
- **Promote** rewrites `dev` to the reviewed candidate. Require explicit confirmation immediately before the exact force-with-lease.
- **Deploy** updates the detached selfhost checkout, reconciles the host, handles required migrations, deploys, and verifies live. Require explicit confirmation immediately before migrations or production deployment.

An approval for one phase does not authorize a later phase. A request to discuss or inspect is not permission to mutate refs, files, provider state, or production.

## Required reading

Before any phase, read [references/topology.md](references/topology.md).

- For Prepare or Promote, also read [references/rebase.md](references/rebase.md).
- For Deploy, also read [references/deploy.md](references/deploy.md).

## Preflight

From any checkout in the Executor worktree family, run:

```bash
bun .agents/skills/executor-selfhost-upgrade/scripts/preflight.ts
```

Use `--json` when another tool will consume the result. The helper is deliberately read-only: it does not fetch, switch branches, install packages, migrate data, or deploy.

Treat every reported blocker as a stop condition. Resolve stale remote-tracking refs by fetching deliberately, then rerun preflight. Do not reinterpret a dirty checkout as safe.

## Shared invariants

- Keep the canonical `dev` checkout, detached selfhost checkout, and hosted-instance repository distinct.
- Use exact SHAs in reports and mutation commands. Re-resolve them immediately before promotion and deployment.
- Use `wt new` for isolated Executor worktrees.
- Preserve unrelated worktrees and user changes.
- Never resolve semantic conflicts with blanket `ours` or `theirs` choices.
- Never hand-merge `bun.lock`; regenerate it with the repository's Bun version after resolving manifests.
- Do not overwrite the hosted instance with `apps/host-cloudflare`. Reconcile intentional host composition instead.
- Use Wrangler for Cloudflare migrations, deployment, version inspection, and rollback.
- Use Executor only through MCP for live service inspection and verification. Never use the Executor CLI.
- Record the old `dev` SHA, selfhost SHA, hosted-instance SHA, and deployed Worker version before their respective mutations.

## Checkpoints and stopping conditions

Stop and ask for direction when:

- a conflict changes public contracts, storage semantics, authentication, execution runtime behavior, or plugin composition;
- any owned checkout is dirty;
- `origin/dev` changes after the promotion lease is captured;
- a required hosted-instance change cannot be represented by a separate reviewed host PR;
- migration ordering, backup coverage, or reversibility is unclear;
- a required verification gate fails;
- live validation shows a regression or cannot reach the authenticated service.

Do not merge pull requests. A rebase candidate PR is review-only; promotion uses the exact guarded ref update described in the rebase reference. A host PR is a separate repository change and blocks deployment until reviewed and landed.
82 changes: 82 additions & 0 deletions .agents/skills/executor-selfhost-upgrade/references/deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Selfhost update and deployment

Use this procedure only after the promoted `origin/dev` SHA is verified.

## Update linked package sources

1. Record the current detached selfhost SHA.
2. Require the selfhost checkout to be clean and detached.
3. Fetch the promoted ref and detach selfhost at its exact SHA.
4. Install with the checked-in lockfile rather than allowing dependency drift.
5. Build generated package output that the host cannot consume as TypeScript source, including `@executor-js/vite-plugin` when present.
6. Verify every hosted `link:@executor-js/*` dependency resolves inside the selfhost worktree and that no expected link is missing.

Do not make a repair commit directly in the detached selfhost checkout. Package fixes go through the fork history workflow.

## Reconcile the hosted instance

Compare the old and new fork host contract with the hosted checkout selected by `--host` or `EXECUTOR_HOST_CHECKOUT`. Do not copy the upstream app over the hosted repository.

If no host change is required, record the comparison and continue. If a change is required:

1. Create an isolated branch in the host repository.
2. Implement only required host composition changes.
3. Run the host gates and open a separate conventional PR.
4. Stop until that PR is reviewed and landed. Never deploy uncommitted host changes.

Preserve intentional hosted behavior including access authentication, service-token actor aliases, QuickJS execution when no Dynamic Worker binding is configured, D1/R2 state, semantic-search indexing, queues, observability, and custom plugin composition unless the upgrade explicitly replaces it.

## Migration gate

Diff the previously deployed package and host SHAs against the proposed deployment for storage schemas, migrations, bindings, queues, indexes, and persistent-object contracts.

If no migration is required, say so explicitly. If one is required, prepare a concrete plan containing:

- affected D1 tables and migration identifiers;
- pre-migration exports or backups;
- R2 objects or prefixes involved;
- Durable Object compatibility implications;
- queue/index rebuild or reconciliation steps;
- verification queries and rollback limits.

Require confirmation before executing remote migrations. Use the hosted repository's checked-in migration command and Wrangler configuration. Do not enable per-request schema setup to substitute for a planned one-time migration.

## Host validation

From the clean hosted repository, run the relevant checked-in commands, normally including:

```bash
bun install --frozen-lockfile
bun run typecheck
bun run lint
bun run format:check
bun run build
bunx wrangler deploy --dry-run
```

Use the actual package scripts when names differ. A package-only change still requires a host build because linked TypeScript source is compiled at deployment time.

## Deploy and verify

Immediately before production deployment:

1. Confirm the hosted repository is clean and at the reviewed SHA.
2. Confirm selfhost is detached at the promoted `dev` SHA.
3. Capture the current Worker version and relevant binding inventory.
4. Present the migration and deployment commands, expected versions, and rollback target.
5. Obtain explicit deployment confirmation.

Deploy through the hosted repository's Wrangler-backed command. Capture the resulting Worker version and read it back from Cloudflare.

Validate the authenticated customer path through Executor MCP, not the Executor CLI:

- AI Search/index health;
- representative semantic searches, including namespace-filtered searches;
- exact tool description;
- one safe read-only live tool execution;
- service-token actor attribution when relevant;
- Worker errors, latency, and telemetry around the validation window.

Browser validation may supplement MCP validation for user-visible changes but does not replace it.

If live validation fails, stop further mutation, gather Worker logs and the exact failing request, and compare with the recorded old versions. Do not automatically roll back unless rollback was explicitly authorized. Use Wrangler rollback only against the recorded previous Worker version.
75 changes: 75 additions & 0 deletions .agents/skills/executor-selfhost-upgrade/references/rebase.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Rebase and promotion

Use this procedure for the Prepare and Promote phases.

## Prepare an isolated candidate

1. Fetch current `origin/dev` and `upstream/main` and record both full SHAs.
2. Require the canonical `dev`, selfhost, upstream, and hosted-instance checkouts to be clean.
3. Create a dedicated candidate from the captured dev SHA with `wt new`. Do not rebase the canonical `dev` checkout.
4. Run `bun run bootstrap` in the fresh candidate as required by the repository.
5. Rebase the fork series onto the captured upstream SHA with rerere enabled for the rebase commands. Do not enable or change global Git configuration.

The candidate branch name should identify the upstream date or SHA, for example `sync/upstream-2026-08-23`.

## Conflict policy

Resolve by ownership and intent, commit by commit:

- Preserve additive fork packages and plugins unless upstream now supplies an equivalent that is intentionally adopted.
- Prefer current upstream framework contracts, provider migrations, Durable Object/session behavior, and supported runtime seams.
- Reapply fork behavior through the new upstream seam instead of restoring removed upstream structure.
- Preserve service-token aliases, execution history, semantic search, host-specific OAuth health, and branded UI only where they remain deliberate fork features.
- For delete/modify and rename conflicts, inspect the upstream replacement and callers before choosing a destination.
- Resolve package manifests first, then regenerate `bun.lock`. Never edit lockfile conflict markers by hand.
- Search the candidate for conflict markers and inspect commits that became empty or changed scope.

Stop for an architectural decision when both sides deliberately changed the same contract or when a resolution would alter storage, authentication, execution isolation, or public APIs.

## Validate the candidate

Run focused tests after each meaningful conflict cluster. When the tree is settled, run the merge-ready repository gates:

```bash
bun run format:check
bun run lint
bun run typecheck
bun run test
```

Do not silently omit a failing suite. Report an environmental limitation separately from a product failure and get approval for any exception.

Prepare a review report containing:

- captured old dev and upstream SHAs;
- new candidate SHA and range-diff;
- empty, dropped, or materially rewritten commits;
- conflict files and resolution rationale;
- upstream-only changes that affect the fork;
- full gate results;
- expected host-contract changes and migration risk.

## Review-only candidate PR

When review on GitHub is requested, push the candidate and open a PR against `dev` that explicitly says it is review-only and must not be merged. GitHub merging would retain the old base history instead of performing the intended ref promotion.

Required checks and reviews must apply to the exact current candidate head. A later force-push invalidates earlier evidence.

## Promote with an exact lease

Promotion is a separate destructive phase. Immediately before it:

1. Fetch `origin/dev` again.
2. Confirm it still equals the captured old dev SHA. Stop if it moved.
3. Create a dated backup ref containing the old dev SHA and push that backup when authorized.
4. Verify the candidate tree and reviewed tree are identical.
5. Update `dev` with an explicit lease tied to the old SHA:

```bash
git push --force-with-lease=refs/heads/dev:<old-dev-sha> origin <candidate-sha>:refs/heads/dev
```

6. Fetch and verify `origin/dev` is exactly the candidate SHA.
7. Update the canonical checkout without destructive reset commands.

Report the backup ref, old SHA, new SHA, and remote readback. Do not merge or close the review-only PR unless separately authorized.
48 changes: 48 additions & 0 deletions .agents/skills/executor-selfhost-upgrade/references/topology.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Executor upgrade topology

Use live Git and filesystem state as the authority. The preflight helper discovers the Executor worktree family and accepts explicit path overrides.

## Checkouts

| Role | Discovery or override | Ownership |
| ----------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
| Fork history | Worktree on `dev`, or `--main` | Git history, ordinary feature PRs, and upstream-rebase promotion |
| Linked packages | Worktree named `selfhost`, or `--selfhost` | Detached checkout whose `packages/**/src` files are consumed by the hosted instance through `bun link` symlinks |
| Upstream snapshot | Worktree named `upstream`, or `--upstream` | Clean detached view of the exact fetched `upstream/main` SHA |
| Hosted instance | `EXECUTOR_HOST_CHECKOUT`, or `--host` | Cloudflare composition deployed for this fork |

The hosted repository consumes `@executor-js/*` as TypeScript source through links into the selfhost checkout. A successful build in the fork history checkout does not prove that those links or the hosted composition are correct.

## Source-of-truth rules

- Package and plugin changes belong in the Executor monorepo, initially in an isolated candidate and ultimately on `dev`.
- Host-only bindings, routes, secrets wiring, migrations, queues, and deployment configuration belong in the configured hosted repository.
- The selfhost worktree is an exact detached package source. Do not develop unique changes there during an upgrade.
- The upstream worktree is an inspection surface. Do not create fork commits there.

## Read-only refresh

When current upstream state is required:

1. Inspect all worktrees and the four owned checkouts.
2. Fetch `origin` and `upstream`. If local tag conflicts would make an ordinary fetch unsafe, fetch branch tips with `--no-tags` instead of modifying tags.
3. Capture `origin/dev` and `upstream/main` as full SHAs.
4. Run preflight before changing either detached worktree.
5. If the upstream worktree is clean, detach it at the captured upstream SHA.
6. Rerun preflight and preserve its output in the upgrade report.

Refreshing remote-tracking refs is not permission to rebase, promote, migrate, or deploy.

## Hosted-instance contract

Treat `apps/host-cloudflare` as a reference composition, not a directory to copy. Compare it with the configured hosted repository for changes in:

- environment and binding contracts;
- Durable Object and hibernation/session wiring;
- execution runtime and QuickJS preload behavior;
- MCP transport and authentication;
- plugin construction and provider presets;
- storage schema and migration machinery;
- queues, AI Search, R2, D1, and observability.

Classify each difference as upstream-required, fork-required, host-specific, or stale. Only upstream-required changes should be ported automatically into a host change proposal.
Loading
Loading