Files
orca/docs/agent-skill-sharing-installation-plan.md
T

85 KiB
Raw Blame History

Agent skill sharing and installation plan

Status: implementation and validation in progress.

Last updated: 2026-08-12.

Implementation checklist: Agent skill sharing implementation checklist.

Architecture decision: Agent skill sharing upstream boundary.

Provider registry: Agent skill provider paths.

Decision summary

Orca will own a focused Skill Bundle packaging and installation pipeline for private sharing. A bundle contains one or many skills; sharing one skill is the same flow with one selected item.

The community vercel-labs/skills project will remain a behavioral reference, not a runtime dependency or source donor. Its npm package exposes a CLI rather than a supported programmatic API, and its install/update behavior does not provide the transaction, provenance, or private-package semantics Orca needs.

Orca will:

  1. Package one or many local skills into one immutable, content-addressed artifact and durable link.
  2. Store private artifacts behind unlisted, revocable Orca Cloud share records.
  3. Treat possession of an active share link as recipient authorization, then resolve it into a short-lived download grant.
  4. Execute installation on the machine that will use the skill.
  5. Validate, stage, commit, and verify the package without silently overwriting local work.
  6. Let the recipient install all or a selected subset, with conflicts and results reported per skill.
  7. Install each selected skill once into .agents/skills and add aliases only for detected agents that need provider-specific paths.
  8. Record bundle/version provenance independently from the community CLI's lockfiles.
  9. Keep every share unlisted: bundles are reachable only through their durable link and never appear in search, browse, organization-library, or marketplace surfaces.
  10. Give authenticated owners a private active-link inventory for copy and revocation; this is a management surface, not recipient discovery.

The portable archive root follows Agent Plugins 1.0.0 for a skills-only package. Orca does not present Skill Bundles as a new executable plugin system: MCP servers, hooks, processes, connectors, and permissions are out of scope. Loose-skill installation remains the universal/default delivery path, with provider-native plugin adapters generated only where they improve compatibility.

The first release will support Orca package sources only. Arbitrary Git, npm, and community registry sources remain delegated to existing tools until there is a product need to own that larger package-manager surface.

Current execution status

The Orca implementation is on skills-share through 2a0b7b2acf; no Orca pull request exists. The local working tree also contains the install-IPC compatibility fix and the in-progress Skills UI overhaul. Cloud bundle ingestion, bearer links, recovery, load testing, production bootstrap, OIDC smoke, and monitor ownership merged through stablyai/orca-cloud#361. Final infrastructure hardening merged in #364 as 57c4958979fc32ed4753959cea45edd3a7c8775c.

Production is live. Two reviewed targeted Terraform phases added the dedicated app deploy identity, restricted both GitHub WIF providers to exact workflows, added resource-scoped API/Auth/monitor and Relay bindings, then removed five broad legacy bindings. A separate exact plan updated only the bearer request-log exclusion and all eight skill alert policies; the alerts use the dedicated Orca skill sharing alerts email channel. No full production plan was applied because it contains unrelated Relay drift.

Production deploy run 31661421728 promoted orca-cloud-api-00025-qup at 100% traffic from merged main, using immutable digest sha256:e4f044105ff2345574bdceb36eec1629761428cc2edf9d743939390b857d61e0. Candidate and canonical authenticated artifact and skill smoke passed, /health and /ready are green, and the direct unlisted landing route returns only generic install copy plus the Orca deep link with no-store, no-referrer, and restrictive CSP headers. Monitor execution orca-cloud-skill-storage-monitor-lfd26 passed on the same digest and emitted only aggregate inventory. The implementation checklist records the remaining desktop and physical-host gates.

The final reliability hardening gives every skill Cloud request a default deadline, makes bundle extraction cancellable and recoverable through the durable extraction journal, bounds package and preview fanout, atomically caps concurrent share preparation, removes abandoned private staging, and waits for SSH transaction recovery before install management. Paired clients advertise the additive install-result capability so cancellation remains cancellation across mixed versions. Regression coverage includes a real killed child process with partially extracted private bytes and bounded 17-skill remote preview fanout. Full Node, CLI, and web typechecks plus repository lint and reliability gates pass at that baseline.

The final combined physical windows 2 run at 44d1266641 passed 449 tests across 67 files with 17 intentional platform skips while native-Windows, real-process, and Ubuntu 24.04 WSL coverage were enabled together. Windows harness fixes at 97b831dd17 made recovery evidence path-semantic and time-deterministic. The run exposed and fixed a WSL alias edge at 44d1266641: when native UNC lstat misses an existing distro symlink, Orca now verifies the alias through WSL and uses ln -sT for creation. The Windows checkout was clean and WSL /tmp had no test debris. Only Ubuntu 24.04 is installed; second-distro permutations are post-launch rather than a first-release gate.

The release workflow now runs the exact unpacked Linux package under Electron-as-Node in an Ubuntu 20.04 container and requires packaged node-pty to spawn /bin/sh. A physical x64 build at f1dccb4f42 passed the existing 18-binary ABI scan and this load/spawn smoke. A native ARM64 build at abe92d565b then passed the same scan for all 18 bundled binaries and emitted orca-node-pty-floor-ok from an ARM64 Ubuntu 20.04 container on native aarch64 hardware. The isolated ARM64 GCE builder had no service account or scopes, remained clean at the exact source commit, and was deleted with its auto-delete boot disk after verification. The physical runs also caught and corrected assumptions about the Linux executable name and packaged runtime-module location before the gate protects a real release.

Cloud verification now requires a disposable PostgreSQL 16/17 migration-and-restore drill. An old migration process remains connected while a future-additive process advances the schema; both write successfully, the database is dumped and restored, and both write again against the restored copy. PR run 31624484826 and merged-main run 31624717796 passed all code, Terraform, and database jobs. The drill is localhost-only, cleans both schemas and its backup, and does not touch staging or production services.

The local redesign now has an independently implemented Agent Plugins 1.0.0 skills-only bundle manifest, deterministic one-or-many archive creation, bounded bundle extraction, additive bundle install contracts, per-skill conflict/results orchestration, and bundle provenance on installed skill receipts. The recipient dialog now recognizes bundle versions, defaults to all skills, supports subset selection, previews aggregate destination state, keeps conflicts local by default, and groups per-skill outcomes with failed-only retry. Local and paired-runtime bundle grants use the additive bundle RPC with staged-upload fallback. SSH now uses a separately advertised additive bundle relay method with the same direct-download and staged-upload fallback; older hosts are rejected before transfer. The original single-skill path remains active for legacy shares while bundle management migrates.

Cloud bundle ingestion accepts both envelopes during migration and stores the detailed bundle manifest with the immutable version. Active share IDs are the recipient credential, owner operations remain authenticated, and legacy ACL rows remain only as migration storage. A Terraform-managed Cloud Logging exclusion prevents per-link Cloud Run request URLs from being stored while privacy-safe route-template telemetry remains available.

The latest resilience pass adds bounded convergence after a lost final install response for both paired runtimes and SSH. A staged retry creates a new upload instead of reusing a consumed upload. SSH now carries only schema-validated structured skill failures through optional JSON-RPC error.data, while older peers continue to ignore the field and newer clients fall back safely when it is absent. Invalid gzip input has a stable archive category, and deterministic EACCES and ENOSPC injection proves failed updates preserve the previous installed version.

Desktop skill operations now have privacy-bounded local diagnostic spans for package creation, Cloud upload and finalization, grant download, client-mediated runtime and SSH transfer, single and bundle installation, provider placement, transaction rollback settlement, and startup recovery. They record aggregate bytes/files, phase duration, OS, destination and transport, conflict/topology/mechanism outcomes, copy fallback, capability absence, recovery/orphan counts, and bounded error categories without paths, skill names, contents, share URLs, grants, host IDs, or credentials. Bundle summaries are aggregate and cap error-category cardinality at 32. This is not product telemetry and changes no RPC, persisted state, or remote opcode, so old clients and hosts remain compatible. The release suite passes 427 tests, full typecheck/lint pass, and the real-process macOS crash-recovery matrix passes all 17 boundaries; physical platform reruns remain tracked in the checklist.

The dedicated staging bucket, IAM, database, principal, enabled secret version, metrics, dashboard, and alerts exist in onorca-cloud-staging. The complete skill-infrastructure target is zero-diff. After #314, the targeted Auth/API plan also reports zero intended changes. Known shared Cloud SQL and artifact-bucket drift was excluded and never applied. Staging was awakened only through guarded run 31534564230. Sleep run 31536547916 returned all three cells to zero; read-only status run 31537525219 independently confirmed SQL policy NEVER, zero MIG targets, and zero managed Cloud Run active-revision minimums.

The API release workflow now deploys an immutable no-traffic candidate with the complete artifact and skill environment plus exactly one approved skill-database secret. It verifies the inherited Terraform runtime identity, Cloud SQL attachment, scaling, resources, volumes, mounts, ports, and probes before promotion, and rolls back to a re-smoked prior revision on failure. Staging now has all four controls enabled; production keeps all four disabled. Database migration startup uses a transaction-scoped advisory lock; transactional rollback and eight concurrent callers pass against PostgreSQL 16 and 17.

Cloud PR #344 passed both required checks and merged as fcf8655a. It adds privacy-bounded migration-ready and migration-failure metrics, a migration lifecycle dashboard panel, and a zero-tolerance migration-failure alert. A read-only targeted staging plan creates only those metrics and alert, updates the existing skill dashboard, reruns descriptor propagation, and destroys no infrastructure; staging remained asleep and nothing was applied.

Cloud PR #345 passed both required checks and merged as 06a5c729. It completes the initial API dashboard coverage with explicit finalization-saturation and archive-rejection series and displays successful and failed operations as rates. Malformed compression errors now become the bounded skill_package_archive_invalid category before they reach persistence, responses, or telemetry.

Cloud PR #346 passed both required checks and merged as 8199c048. The Cloud Run dashboard and alerts now cover route-template-scoped p99 skill latency, server errors, CPU, memory, and active instance pressure. Alerts require five minutes above 80% p99 CPU/memory, more than 80% of the configured instance ceiling, five-second interactive p99, or 30-second finalization p99; no bearer URL or identifier becomes a metric label.

Cloud PR #347 passed both required checks and merged as 65320475. It adds a six-hour aggregate storage inventory job, fixed-namespace bytes and object-count metrics, overdue-quarantine and job failure alerts, and storage dashboard panels. The monitor identity has only storage.objects.list; its scheduler identity can invoke only that job. A reviewed targeted staging apply added 18 observability resources, updated the existing dashboard, and replaced only the inert metric-propagation timer. The post-apply targeted plan is zero-diff. A manual execution completed successfully and emitted only aggregate published and quarantine measurements, with zero overdue objects and no identifiers or paths. SQL remained NEVER/STOPPED, all three Relay MIG targets remained zero, and production remained disabled and untouched.

A separate read-only production prerequisite check confirmed that onorca-cloud-skill-packages is currently unallocated, the production skill database and secret names do not collide, and the intended API service and runtime identity already exist. Cloud Run quota headroom exceeds the existing 20-instance API ceiling; V1 adds no database instance and requires no quota increase. No production resource was planned or changed.

Auth deploy run 31535179937 promoted orca-cloud-auth-staging-00017-dug with exact staging-only GitHub OIDC constraints, healthy JWKS, and zero deployment-window errors. API run 31535438327 promoted orca-cloud-api-staging-00042-hef with authenticatedSmoke: true and skillSmoke: true. The ten-minute, non-refreshable smoke principals exercised artifact CRUD and skill upload, finalize, immutable versions, recipient/outsider authorization, local and remote grants, rollback, expiry, revocation, deletion, and signed-object cleanup. Structured skill logs exposed only privacy-safe request metadata and produced zero sensitive-value matches.

Cloud PR #320 passed PR run 31564069382, merged-main run 31564235724, and a targeted staging logging-exclusion plan of one addition, zero changes, and zero deletions. Guarded wake run 31564370807 prepared staging. Deploy run 31564803943 promoted orca-cloud-api-staging-00051-yoq at 100% traffic with immutable image digest sha256:511c0196511d2079bd9138092ad3cf065304b46a089b02d8df9318e0ae2e656a. Candidate and canonical smoke covered owner upload/finalize/share creation/inventory/revocation and anonymous preview, local/remote download grants, version selection, expiry, uniform unavailable responses, package deletion, and cleanup. Requests with no Authorization header and an invalid header returned the same non-cached 404; the serving revision produced zero errors, and Cloud Logging retained zero per-link platform request logs. Cloud PR #329 and desktop run 31569902499 subsequently passed the complete browser-free publish/install/conflict/update/rollback/revoke/remove/delete journey. Cloud PR #330 merged as 8045c85dad; deploy 31579844413 promoted revision orca-cloud-api-staging-00057-kat, and recovery smoke 31580071168 proved generation-aware GCS soft-delete restoration, transactional reference repointing, bearer download, and cleanup. Guarded sleep 31580339694 restored SQL to NEVER/STOPPED and all Relay MIG targets to zero. Load run 31585710645 then exercised 12 concurrent 30-skill bundles at roughly 3.95 MiB extracted per bundle. Explicit saturation bounded ten requests while two completed; API, Cloud SQL, instance, and latency metrics stayed far below their reviewed thresholds. PR #335 made retry settlement cleanup-safe, and run 31586684354 removed the exact failed-wave package set before two manifest-proven quarantine generations were deleted with GCS preconditions. Guarded sleep 31587083752 then returned SQL to NEVER/STOPPED, all three stable Relay MIGs to zero, and every active Cloud Run revision minimum to zero. Guarded wake 31589384191 later restored only the two configured Relay cells, and Auth deploy 31589963244 promoted orca-cloud-auth-staging-00025-zuz. The browser-free physical windows 2 staging journey then passed publish, native Windows install, update, independent local version selection, rollback, revocation preservation, removal, and Cloud deletion using encrypted credential run 31591275227; its ciphertext artifact and one-time local key material were deleted immediately. Guarded wake 31603249983 later restored only the two configured cells. A disposable no-service-account Ubuntu 20.04/glibc 2.31 VM passed the full live SSH staging lifecycle in 31.3 seconds, including host-owned install, update, rollback, revocation preservation, removal, and Cloud deletion. The encrypted credential artifact, one-time keys, Orca SSH target, remote install, and VM were removed. Guarded sleep 31604391897 passed and independent reads confirmed SQL NEVER/STOPPED plus all three Relay MIGs at stable target zero. Guarded wake 31605729090 then enabled the same topology for an isolated headless paired host with a separate home/profile. The full paired-runtime staging lifecycle passed in 12.5 seconds without local fallback, and its environment, install, Cloud package, encrypted credential artifact, and one-time keys were removed. Guarded sleep 31606600532 passed with the same independently verified low-cost state. The owner accepted the additional live physical WSL Cloud journey as duplicate release evidence on 2026-08-12 after the combined 449-test Windows/WSL matrix and native-Windows Cloud lifecycle passed; this does not collapse WSL semantics into macOS. Remaining staging gates are physical SSH macOS/Windows and the time-gated quarantine lifecycle deletion. The Windows/WSL release matrix is green. Guarded wake retry 31630802215 succeeded before that decision. The first cleanup attempt 31631288043 failed closed during Terraform provider download on an upstream 503, before its mutation step; guarded sleep retry 31631379891 succeeded. Independent reads verified SQL NEVER/STOPPED, all three Relay MIGs stable and reached at target zero with no active actions, and zero minimum instances on each active API, Auth, and Relay revision. Guarded wake 31634214856 later restored the configured topology for an isolated native macOS ARM64 OpenSSH target whose home, keys, and relay state lived under one temporary root. The full publish/install/update/rollback/revoke/remove/delete staging lifecycle passed in 20.1 seconds without local fallback. The run also corrected the test oracle to support valid absolute POSIX SSH homes outside /home. The encrypted GitHub artifact was deleted immediately; the SSH service, relay, install, temporary home, and one-time key material were removed. Guarded sleep 31635145830 passed, and independent reads confirmed SQL NEVER/STOPPED, every MIG stable at zero with no active actions, and API/Auth/Relay minimum scale zero. Supported Windows SSH and the time-gated quarantine deletion remain open.

Cloud PR #355 removed internal publisher and organization identifiers from recipient responses, passed code, Terraform, and PostgreSQL 16/17 checks, and merged as b3213bd34d1b224d8a3b11527eceaac883965400. Guarded wake 31639920301 prepared staging. Deploy 31640677572 promoted orca-cloud-api-staging-00060-qay at 100% traffic with immutable digest sha256:31cb0a91a7abf1f82e4de08bd31e98fbd71519adc731a005fc95f60480658f73; authenticated and skill candidate/canonical smoke passed. Its unrelated post-promotion storage-monitor image update lacked iam.serviceAccounts.actAs; the prior monitor image remains serving and unchanged. Guarded sleep 31640935616 passed in 8m51s; independent reads verified SQL NEVER/STOPPED, all three Relay MIGs stable and reached at target zero, and the API at minimum scale zero while revision 00060-qay retained 100% traffic.

Production deployment completed on 2026-08-12. The exact skill-only Terraform apply created the private bucket, database, secret, least-privilege identities, request-log exclusion, metrics, alerts, and dashboard with 40 additions and zero updates, replacements, or deletions. Disabled-route bootstrap run 31648015091 migrated the schema and promoted orca-cloud-api-00016-yem while all four controls remained false. Cloud PR #357 enabled all four controls in one launch. Cloud PR #358 replaced the missing long-lived production smoke secret with an exchange restricted to the exact production main workflow, GitHub environment, dispatch event, repository/owner IDs, and audience; issued principals expire in ten minutes and have no refresh credentials. Auth run 31649381596 passed candidate and canonical health. API run 31650178315 passed candidate and canonical authenticated artifact plus skill lifecycle smoke, promoted orca-cloud-api-00022-maq to 100% traffic, and completed the aggregate monitor image update. All four skill controls are true, the serving revision reported zero deployment-window errors, and both API and Auth health are green.

Cloud PR #359 codified the deploy identity's roles/iam.serviceAccountUser grant only on the read-only skill storage monitor identity. Its exact production apply added one resource with zero changes or deletions, and the repeat targeted plan was zero-diff. Manual execution orca-cloud-skill-storage-monitor-bmm4q completed successfully. Cloud PRs #360 and #361 keep Terraform ownership of the monitor shape while assigning its immutable image and Cloud Run client metadata to the release workflow; the exact production monitor plan is zero-diff after the live image advance. The development Orca instance skill-sharing-manual now points at login.onorca.dev and cloud-api.onorca.dev; sign-in and the desktop/real-host production lifecycle remain user-driven validation.

A final renderer lifecycle review fenced managed-install inventory by request generation so a slower previous machine cannot overwrite the newly selected machine's list. It also moved bundle busy propagation into the initiating event instead of mirroring state through an effect. The renderer skill/settings slice passed 122 tests across 18 files plus all Node/CLI/web typechecks, focused lint, changed-code quality, max-lines, diff, and localization gates.

Research baseline

The upstream assessment used vercel-labs/skills commit c6f69c631292444cc541ac6d91e2226b0ff247da.

The portable bundle assessment used agentplugins/agent-plugins-spec commit bd383552095128f6effe895b9257cfd580a6d179, specifically spec/1.0.0.md. The local reviewed clone is /Users/jinwoo/refs/misc/agent-plugins-spec; the example repository is /Users/jinwoo/refs/misc/agent-plugins-example. Orca independently implements the reviewed behavior. The specification prose is CC BY 4.0 and its schemas/software are Apache 2.0, so Orca will not copy the prose or vendor the schemas unless the corresponding notices are deliberately handled.

Useful upstream behavior:

  • A canonical .agents/skills/<name> location.
  • A data set of agent-specific global and project paths.
  • Relative symlink handling, Windows junction behavior, and copy fallback.
  • Archive path, entry-count, and extracted-byte limits.
  • Tests for aliases, broken links, and provider-specific placement.

Behavior Orca will not inherit:

  • Deleting the destination before the replacement is ready.
  • Updating without checking whether installed files were modified.
  • Direct read/modify/write lockfile updates without durable publication.
  • Reinstalling the canonical directory once per selected agent.
  • Treating an expiring signed artifact URL as package identity.
  • Coupling installation to prompts, terminal output, telemetry, and process exits.

Orca will not copy upstream source, tests, fixtures, or registry entries. Provider paths will be implemented independently from official provider documentation and verified installations. Under that constraint, Orca does not incorporate upstream copyrightable material and needs no upstream attribution. Revisit this decision if implementation work ever proposes copying material.

Goals

  • Share one or many private skills with a teammate through one durable, intuitive link.
  • Select and review large bundles, including groups of 30 skills, without repetitive dialogs.
  • Install on the local computer or any compatible connected Orca runtime.
  • Support global scope and folder-workspace/project scope.
  • Work on macOS, Linux, and Windows.
  • Preserve executable bits and all files in the skill package.
  • Prevent archive traversal, symlink escapes, special files, case collisions, and resource exhaustion.
  • Never silently replace an unowned or locally modified skill.
  • Recover from interruption during package download, extraction, placement, alias creation, or provenance publication.
  • Keep share authorization separate from short-lived blob access.
  • Support immutable versions, updates, removal, and eventual team-wide reconciliation.
  • Remain compatible with independently updated desktop clients and remote Orca servers.
  • Treat ordinary folder workspaces as first-class; Git is not required.
  • Preserve enough portable metadata for export, SSH/remote transfer, and offline validation.

Non-goals for the first release

  • Reimplementing all skills CLI source parsing and provider integrations.
  • Supporting all upstream agent paths on day one.
  • Publishing package bytes through a permanent or directly addressable blob URL.
  • Automatically installing a shared skill on every organization machine.
  • Merging local modifications with a newer shared package version.
  • Treating installation as a security sandbox. A skill contains instructions and scripts and must be presented to the user as code from its author.
  • Shipping a full plugin runtime, MCP servers, hooks, processes, connectors, or portable permissions.
  • Requiring a provider-native plugin installer; unsupported agents still receive loose skills.
  • End-to-end encryption from Orca Cloud operators in the initial trust model. Private means unlisted and accessible through an active bearer link, with authenticated owner management. Application-level package encryption can be added later without changing package identity.

Product experience

Sharing

The existing Skills page has three header actions: Share skills, Install from link, and Manage. Share skills enters selection mode across installed and workspace skills. Search and filter changes retain selections; Select all results is explicit and Orca never silently selects everything. The existing per-card share action remains a one-skill shortcut.

Ineligible skills are disabled with a visible reason. Duplicate skill names must be resolved before publication because they would collide in both the archive and destination roots.

The review dialog shows:

  • Bundle name and selected skill list.
  • Skill, file, and byte counts.
  • Included scripts and executable files, with an expandable review for each skill.
  • The signed-in profile that will own and manage the share.
  • A clear warning that anyone with the unlisted link can inspect and install the bundle.
  • Optional version label and release notes.

After confirmation, Orca validates and packages the exact bytes shown in the preview. Progress is named Preparing skills, Uploading, Verifying, and Publishing link. Completion returns one durable URL such as:

https://app.orca.dev/skills/share/<share-id>

The URL identifies a revocable bearer share record, not a blob-storage object or permanent GCS grant. Recipients do not sign in: possession of an active, unexpired link authorizes inspection and a short-lived download grant. Revocation blocks future resolution and grants, while already installed copies remain. Publishing, listing owned shares, version management, revocation, and deletion still require the owner to sign in.

Installing

Opening a deep link launches Orca and inspects the bundle without installing it. Preview identifies the immutable version, release notes, skill count, scripts, and executable files. V1 deliberately omits publisher identity from the recipient response and UI; internal creator and tenant records remain private authorization and management data. The recipient can select all or a subset of the contained skills.

The destination picker supports the local machine, paired runtimes, WSL, and SSH, in global or workspace scope. Before commit, the preview groups selected skills as new, unchanged, updates, or conflicts and shows detected-agent coverage. Conflicts are handled per skill in one review surface, not one dialog per conflict. Keep local is the default; replacement is explicit. The primary action says Install N skills.

Installation shows aggregate progress plus the current skill. Results are grouped as installed, unchanged, kept local, and failed; failed items can be retried without repeating successful work. An incompatible selected runtime receives an update-required result before transfer.

Manage separates:

  • Installed bundles: update, rollback, install on another machine, inspect skills, and remove.
  • Shared bundles: copy link, revoke, publish version, and delete the Cloud package.

Settings includes a Share Skills section, parallel to Artifacts, explaining unlisted-link behavior, retention, revocation, and the fact that installed copies are unaffected. It links to the Skills page for publishing and management; it does not introduce a searchable catalog or a second sharing workflow.

Bundle update or removal never silently destroys locally modified skills.

The UI must follow docs/STYLEGUIDE.md and use existing design tokens and shadcn primitives.

Target architecture

Selected skill folders
    |
    v
Package builder -- validates and creates immutable artifact
    |
    v
Orca Cloud -- private blob + version metadata + revocable bearer share
    |
    v
Download grant -- short-lived and scoped to one immutable digest
    |
    v
Destination runtime
    |
    +-- package ingress
    +-- package inspection
    +-- per-skill selection and install planning
    +-- staged transaction
    +-- provider placement reconciliation
    +-- bundle and per-skill provenance publication
    +-- post-install discovery

Cloud download, client-mediated transfer, and a local package file all terminate at the same validated package-ingress boundary. Installation logic does not know which transport supplied the bytes.

Package format

Use a versioned tar archive so executable modes can be represented without a platform-specific side channel. The extracted archive root is an Agent Plugins 1.0.0-compatible, skills-only plugin:

plugin.json
skills/
├── skill-a/
│   └── SKILL.md
├── skill-b/
│   └── SKILL.md
└── ...
dev.orca.skill-sharing/
└── manifest.json

Conceptual manifest:

type SkillBundleManifestV1 = {
  schemaVersion: 1
  packageId: string
  versionId: string
  bundleName: string
  description: string
  createdAt: string
  skills: Array<{
    id: string
    name: string
    description: string
    digest: string
    files: Array<{
      path: string
      size: number
      executable: boolean
      sha256: string
    }>
  }>
  bundleDigest: string
}

Rules:

  • packageId is stable across versions; versionId identifies one immutable publication.
  • plugin.json uses the canonical Agent Plugins 1.0.0 $schema, a valid portable plugin name, bundle version, description, and optional standard metadata. Orca validates from locally owned rules and never fetches the schema while loading.
  • Every immediate skills/<name>/SKILL.md is required and must parse successfully.
  • Each skill digest uses normalized relative paths, executable state, classification, and file identity. The bundle digest commits to the ordered skill identities and their globally unique archive paths.
  • The installed folders receive only the selected children of skills/.
  • Bundle identity, access, immutable versions, upload/download, update/rollback, and Cloud deletion are bundle-level. Conflict handling, provenance, selection, local-modification protection, and results are skill-level.
  • Paths use / in the manifest and are converted with the executing host's path API.
  • LF and CRLF non-executable text share one normalized package identity, while each immutable archive retains and hashes its exact source bytes; executable and binary files always use exact bytes for identity.
  • Names are normalized once during publication. Installation never silently renames a conflict.
  • The archive has no outer bundle/ wrapper, so its root remains directly consumable by agents that implement Agent Plugins.
  • Orca-specific integrity and version data lives in dev.orca.skill-sharing/manifest.json rather than a top-level custom field or GCS metadata alone. It therefore survives export, SSH/remote transfer, and offline validation and can describe every skill and file.
  • GCS custom metadata stays compact and operational. PostgreSQL stores only the package, share, version, ownership, and lifecycle records needed to resolve a known link or manage an owned bundle. Legacy ACL records may remain during migration but never gate bearer-link access.
  • Orca constructs a fresh staging root. If imported content already contains dev.orca.skill-sharing, Orca accepts only an appropriate recognized schema and rejects unknown, malformed, or conflicting contents; it never overwrites the namespace silently.
  • V1 rejects symlinks and special files. A later package-builder feature may safely dereference internal links after proving they remain within the source root.
  • Existing limits remain the starting contract: depth 16, 2,048 entries, 512 files, 4 MiB per file, and 32 MiB total extracted bytes. Compressed download size also receives an explicit cap.
  • Archive and manifest schema changes are additive or introduced as a new schema version.

The package builder observes every selected source, copies it into a fresh private staging root, observes the staged copies again, and only packages them if every identity agrees. The preview shown to the user is bound to that final bundle digest.

The original unpublished manifest.json + skill/ staging format has no production compatibility commitment. Orca will replace it before launch and migrate or discard staging-only records. Remote bundle RPCs use a new skills.install.bundle.v1 capability and additive methods so older peers do not interpret bundle requests as single-skill requests.

GCP deployment plan

Existing production baseline

Read-only inspection of the active onorca-cloud project on 2026-08-11 found:

Resource Existing state relevant to skill sharing
Cloud Run orca-cloud-api, orca-cloud-auth, orca-cloud-relay, and orca-cloud-relay-fence run in us-central1
API service orca-cloud-api uses its own service account, scales from 0 to 20 instances, has a 300-second timeout, and already owns artifact-sharing endpoints
Object storage onorca-cloud-artifacts is a US bucket with uniform bucket-level access, public-access prevention, exact CORS for https://share.onorca.dev, and seven-day soft delete
Database orca-cloud-auth-db is PostgreSQL 17 in us-central1, regional/high-availability, with backups and point-in-time recovery
Database contents The instance currently contains orca_auth and orca_relay databases; there is no skill database
IAM orca-cloud-api@onorca-cloud.iam.gserviceaccount.com owns objects in the existing artifact bucket
APIs Cloud Run, Cloud Storage, Cloud SQL Admin, IAM Credentials, Secret Manager, Logging, Monitoring, and Pub/Sub are enabled
Excluded services Firestore and Cloud Asset Inventory are disabled; Cloud Tasks is not enabled

The GCP inspection was read-only. Commands that offered to enable disabled APIs were declined, and no resources or IAM policies were changed.

V1 infrastructure decision

Use the existing project, API service, authentication service, PostgreSQL instance, deployment pipeline, and Terraform state. Add a dedicated package bucket and database instead of putting private skill packages into the existing general artifact namespace.

The V1 control plane remains in orca-cloud-api. Package validation is bounded and streaming, so a separate worker service is not justified at the initial 40 MiB compressed-package ceiling. Protect the existing API workload with a small per-instance package-finalization semaphore and return a retryable response when that lane is full.

Split package processing into a dedicated Cloud Run service later if finalize latency or CPU usage interferes with artifact sharing. Do not reduce the entire API service's current concurrency merely to accommodate one endpoint family.

Firestore is not required. Skill metadata belongs in PostgreSQL beside the existing Orca Cloud identity model. Cloud Tasks and Pub/Sub are not required for V1 because upload expiry is enforced by a GCS lifecycle rule and package finalization stays synchronous and bounded.

Required GCP changes

All production changes are declared in the existing Orca Cloud Terraform configuration. Do not create durable resources manually with gcloud.

Change Proposed production value
GCS bucket onorca-cloud-skill-packages, subject to Terraform name validation
Location US, matching existing shared-artifact storage; revisit per-region buckets when data residency becomes a product requirement
Access Uniform bucket-level access and public-access prevention enforced
Soft delete Seven days, matching the current artifact bucket
Object versioning Disabled; package keys are immutable and GCS generations are recorded
Temporary lifecycle Delete uploads/ objects after one day
CORS Exact approved Orca share/app origins; no wildcard origin
Database orca_skills on orca-cloud-auth-db
Database principal Dedicated orca_skills_app user with access only to orca_skills
Database secret orca-cloud-skills-database-url in Secret Manager
Cloud Run service Extend orca-cloud-api; mount the existing Cloud SQL instance and inject only the skill database secret
Package signer Reuse orca-cloud-api@onorca-cloud.iam.gserviceaccount.com for V1
Metrics/logging Extend existing Cloud Logging and Monitoring configuration with skill endpoint dashboards and alerts

The bucket is separate because skill packages need different authorization, retention, signed download, and lifecycle rules from public/shared artifacts. It also provides a clean IAM kill switch without disrupting existing artifact links.

Bucket layout

gs://onorca-cloud-skill-packages/
  uploads/<upload-id>/package.tar.gz
  packages/v1/tenants/<tenant-hash>/sha256/<first-two-hex>/<archive-sha256>/package.tar.gz

Rules:

  • uploads/ is quarantine storage and is never downloadable through a share.
  • Upload IDs are random, single-use, tenant-bound, and expire in PostgreSQL as well as GCS.
  • Final package keys are derived from a one-way owner-tenant hash and the validated archive SHA-256. Raw tenant identifiers never appear in object names.
  • The database records the final object's GCS generation, compressed size, archive SHA-256, and package digest.
  • Final objects are never overwritten. Promotion uses a generation-match precondition.
  • If a tenant's final key already exists, finalization verifies its archive SHA-256 and logical package digest metadata before reusing it.
  • Deduplication is tenant-scoped in both GCS and PostgreSQL, so another tenant's matching archive cannot change publication timing or reveal that the digest already exists.
  • GCS object versioning remains off; immutable keys plus stored generations prevent accidental replacement, while seven-day soft delete provides operator recovery.
  • Deleting the final database reference deletes the object only after a transaction proves no package version still references it. GCS soft delete then supplies the recovery window.

Upload implementation

Use a V4 signed POST policy rather than a signed unrestricted PUT. The POST policy enforces:

  • Exact quarantine object key.
  • application/vnd.orca.skill+tar+gzip content type.
  • A content-length range capped at 40 MiB.
  • Required upload ID and expected archive SHA-256 metadata.
  • A 15-minute expiration.

The compressed limit is slightly above the 32 MiB extracted-file limit to allow tar metadata and incompressible input. The package builder still enforces the lower extracted-content limits.

Upload sequence:

  1. orca-cloud-api authenticates the user through the existing auth integration.
  2. The API checks organization membership, package quota, per-user rate limits, and concurrent upload limits.
  3. It inserts a pending upload row and returns a signed POST policy for the unique quarantine key.
  4. The client uploads directly to GCS; package bytes do not traverse Cloud Run.
  5. The client calls finalize with the upload ID and package manifest identity.
  6. The API reads GCS object metadata and rejects unexpected size, content type, key, generation, or tenant binding.
  7. The API streams the object once to calculate archive SHA-256 and validate the archive envelope, manifest, path set, file limits, and package digest. It never buffers the whole package.
  8. The API promotes the validated object to its immutable content-addressed key with an if-absent generation precondition.
  9. A PostgreSQL transaction publishes the immutable package version and marks the upload complete.
  10. The quarantine object is deleted. The one-day lifecycle remains the backstop for abandoned uploads.

Run at most a small fixed number of finalizations concurrently per API instance. A full lane returns 429 or 503 with Retry-After; it does not queue unbounded package bytes or work.

Download grants

After resolving an active bearer share, orca-cloud-api creates a V4 signed GET URL with:

  • Exact final object key and stored generation.
  • Five-minute expiration.
  • Response content type and attachment filename.
  • No list or write permission.

The URL is the short-lived grant. The durable share URL is never signed directly and cannot access GCS. Revocation cannot invalidate an already-issued GCS URL, so the five-minute lifetime is the maximum revocation delay.

The destination runtime accepts download URLs only from the configured GCS origin for the Orca skill bucket, rejects credential-bearing redirects to any other host, enforces the expected byte count while streaming, and verifies both archive SHA-256 and package digest before installation.

IAM

Apply least privilege at the dedicated bucket and service-account level:

  • Grant the API service account roles/storage.objectUser on the skill-package bucket, not a project-wide storage role.
  • Grant the API service account roles/cloudsql.client for the existing instance.
  • Allow the API service account to use IAM Credentials signBlob for itself so it can generate V4 policies and URLs without a downloaded service-account key. The Terraform binding is scoped to that service account.
  • Grant Secret Manager accessor only for orca-cloud-skills-database-url and any future skill-specific secret.
  • Keep bucket IAM free of allUsers and allAuthenticatedUsers.
  • Do not give the desktop, remote runtime, or user identity direct bucket IAM. They receive only a time-bound signed operation after application authorization.
  • Keep the existing deployment service account's impersonation/deploy permissions unchanged except where Terraform needs to manage the new resources.

No long-lived GCP key is shipped in Orca or stored on a remote runtime.

PostgreSQL schema

Create migrations for:

  • skill_packages: stable bundle identity, owner organization, slug/name, creator, timestamps, and deletion state.
  • skill_package_versions: immutable version, package digest, archive SHA-256, GCS object key and generation, byte and skill counts, release notes, creator, publication state, and the validated bundle manifest needed to inspect a known share without downloading its private archive.
  • skill_package_uploads: tenant/user binding, quarantine key and generation, expected identities, expiration, finalization state, and failure category.
  • skill_package_acl: legacy organization or user access records retained for migration until a later schema cleanup; these do not authorize or deny bearer-share resolution.
  • skill_share_records: unpredictable share ID, package ID, optional pinned version, expiration, revocation state, creator, and timestamps.
  • skill_package_audit_events: bounded security/lifecycle event metadata without package contents or signed URLs.

Required constraints and indexes include:

  • Unique package slug within its owning organization.
  • Unique immutable version ID and package digest identity.
  • Tenant-scoped archive identity and final GCS object key/generation pair.
  • Share lookup by unpredictable ID and active/revoked state.
  • No package, version, or contained-skill search/list index; share links are intentionally unlisted.
  • Owner lookup for authenticated management operations.
  • Pending-upload lookup by owner and expiration.
  • Foreign keys that prevent removing a blob reference while a published version uses it.

Share resolution and share-scoped download grants accept no user credential: an unpredictable, active, unexpired share ID is the bearer credential. Anonymous requests receive the same non-disclosing 404 for missing, expired, revoked, or deleted shares and remain subject to distributed per-IP abuse limits. Package/version management, share creation, owner listing, revocation, and deletion require an authenticated owner.

Cloud Run changes

Add skill endpoints to orca-cloud-api and configure:

ORCA_SKILL_PACKAGE_BUCKET=onorca-cloud-skill-packages
ORCA_SKILL_PACKAGE_MAX_COMPRESSED_BYTES=41943040
ORCA_SKILL_PACKAGE_UPLOAD_TTL_SECONDS=900
ORCA_SKILL_PACKAGE_DOWNLOAD_TTL_SECONDS=300
ORCA_SKILL_PACKAGE_FINALIZE_CONCURRENCY=<small fixed value>
ORCA_SKILLS_DATABASE_URL=<Secret Manager reference>

Use the existing auth base URL and CORS-origin configuration. Do not add a second authentication implementation for skills.

Every API image rollout must stamp the complete Terraform-owned literal environment and exact ORCA_SKILLS_DATABASE_URL secret reference in one no-traffic candidate. Before smoke or promotion, compare the candidate with both the reviewed release values and the serving Terraform runtime shape. Reject any unexpected secret or environment entry, changed service account, Cloud SQL attachment, scaling bound, resource limit, volume, mount, port, or probe. This keeps ordinary image deploys from clearing the skill database secret or silently detaching Cloud SQL.

The API streams upload validation with fixed buffers under its existing 512 MiB memory limit. Load test the finalize lane before choosing its fixed concurrency. Keep the current Cloud Run instance scaling bounds initially, then adjust only from observed CPU, latency, database connection, and error metrics.

Recommended endpoint family:

POST   /v1/skill-packages/uploads
POST   /v1/skill-packages/uploads/<upload-id>/finalize
POST   /v1/skill-packages
GET    /v1/skill-packages/<package-id>
GET    /v1/skill-packages/<package-id>/versions
POST   /v1/skill-packages/<package-id>/shares
DELETE /v1/skill-shares/<share-id>
GET    /v1/skill-shares/<share-id>
POST   /v1/skill-shares/<share-id>/download-grants

Finalize may create the package/version in one call; the separate package endpoint remains useful when publishing a new version under an existing stable package identity. All mutating endpoints accept idempotency keys.

CORS and public routing

  • Route the endpoint family through the existing Orca Cloud API hostname and deployment path.
  • Add only exact production and approved development app/share origins to the skill bucket's CORS policy.
  • Allow POST for signed upload policy submission and GET/HEAD for signed download.
  • Expose only required response headers such as Content-Type, Content-Length, ETag, x-goog-generation, and x-goog-hash.
  • Do not expose the GCS bucket through a public custom domain.
  • Keep Cloud Run ingress and authentication consistent with existing API endpoints; package authorization remains mandatory at the application layer.

Retention, deletion, and recovery

  • Pending upload database rows expire after 15 minutes and are safe to delete after one day.
  • GCS deletes quarantine objects after one day regardless of database cleanup success.
  • Published objects have no age-based deletion rule.
  • Package deletion first marks metadata deleted and revokes shares, then deletes an object only when no retained version references it.
  • Seven-day GCS soft delete allows operator recovery from accidental object deletion.
  • PostgreSQL backups and point-in-time recovery cover metadata; restoration procedures must restore database rows and object generations consistently.
  • Organization retention and legal deletion requirements override product rollback retention.

Monitoring and operational gates

Add dashboards and alerts for:

  • Upload grant, finalize, share resolution, and download-grant request rate.
  • Authorization denials and rate-limit outcomes.
  • Finalize duration, semaphore saturation, archive rejection category, and digest mismatch.
  • Cloud Run 5xx rate, CPU, memory, instance count, and request latency for skill routes.
  • GCS quarantine bytes, published bytes, object count, and lifecycle deletion failures.
  • PostgreSQL connection count, storage, query latency, migration status, and failed transactions.
  • Signed URL creation failures and IAM Credentials errors.
  • Orphan metadata/object reconciliation count.

Budget alerts cover GCS stored bytes and egress, Cloud Run CPU/request growth, and Cloud SQL storage. Logs contain package/version IDs and error categories, not manifests, filenames, share URLs, signed policies, signed URLs, or ACL membership.

Provisioning and deployment sequence

  1. Confirm the existing Orca Cloud Terraform worktree and staging environment are current.
  2. If there is no isolated staging GCP project, create or designate one before testing package upload; do not exercise new lifecycle/IAM behavior first in onorca-cloud production.
  3. Add the bucket, lifecycle, CORS, IAM, database, database user, secret, Cloud SQL attachment, API configuration, dashboards, alerts, and budget thresholds to Terraform.
  4. Run Terraform formatting, validation, and a reviewed plan. The expected production plan contains no replacement of the existing artifact bucket, Cloud SQL instance, or Cloud Run services.
  5. Apply the reviewed skill-only infrastructure plan in staging without shared-resource drift.
  6. Deploy orca-cloud-api with all skill controls disabled. When the database secret is present, startup applies PostgreSQL migrations without registering the skill routes.
  7. Verify the migration-ready event, zero error logs, ordinary artifact behavior, and 404 skill route boundary before changing any control.
  8. Enable route registration for the staging identity and run upload/finalize/download tests, including expired policies, anonymous bearer resolution, oversized uploads, corrupt archives, deduplication, revocation, and object cleanup.
  9. Run a staging desktop-to-runtime installation and verify logs contain no grants or private contents.
  10. Apply the reviewed production Terraform plan.
  11. Run migrations and deploy the API with availability disabled.
  12. After every release gate passes, enable the feature for all accounts in one launch.
  13. Observe at least one complete soft-delete, upload-expiry, update, rollback, and revoke journey, retaining separate kill switches for upload grants, download grants, and remote installation.

Production verification uses read-only commands such as:

gcloud storage buckets describe gs://onorca-cloud-skill-packages --project=onorca-cloud
gcloud run services describe orca-cloud-api --region=us-central1 --project=onorca-cloud
gcloud sql databases list --instance=orca-cloud-auth-db --project=onorca-cloud
gcloud iam service-accounts get-iam-policy \
  orca-cloud-api@onorca-cloud.iam.gserviceaccount.com --project=onorca-cloud

Never print Secret Manager payloads or signed policies/URLs during verification.

Installation scopes and destinations

Global scope

The canonical root is resolved on the destination host:

<home>/.agents/skills/<skill-name>

Provider-specific aliases are created only for detected agents that do not consume the canonical root.

Workspace scope

The canonical root is:

<workspace>/.agents/skills/<skill-name>

The workspace may be a Git worktree or a plain folder. Resolution uses the workspace identity owned by the executing runtime; a client-provided path alone is not trusted for a remote target.

Project installation does not create or modify a checked-in desired-state lockfile in V1. A separate team-sync feature may later add an explicit, reviewable project manifest.

WSL scope

WSL is a distinct execution target. Home resolution, path operations, package extraction, and installation run inside the selected distro. The Windows client must not construct Linux home paths or mutate the distro through translated Windows paths.

SSH-only scope

An SSH target without an Orca runtime cannot execute the runtime RPC directly. Before GA, add a host-side installation command invoked through the existing SSH execution and file-transfer providers. The desktop uploads the immutable package through SFTP, invokes the bundled Orca installer on the SSH host, and receives the same structured result as runtime RPC.

If the required host component is unavailable, Orca reports the limitation and provides a local package download or command; it never installs into the desktop's home as a fallback.

Provider destination strategy

Orca owns a small data-only registry for agents Orca supports. Each entry describes:

  • Orca agent ID.
  • Whether it reads the universal .agents/skills root.
  • Global provider-specific path resolver when required.
  • Project provider-specific path resolver when required.
  • Detection evidence required before creating the path.
  • Supported alias mechanism by platform.

The registry is authored from official agent documentation and Orca's own verified installations. Upstream may reveal that a compatibility case exists, but its implementation, path table, and tests are not copied or transformed into Orca code.

Policy:

  1. Always create one canonical copy.
  2. Do nothing else for universal agents.
  3. Create an alias for a detected non-universal agent.
  4. On Windows, prefer a directory junction when supported.
  5. Fall back to a verified independent copy only when aliases are unavailable.
  6. Record every placement and its topology.
  7. Never create configuration roots for dozens of undetected agents.
  8. Never replace an unowned provider-specific copy without an explicit decision.

Provider releases and official documentation are reviewed periodically. Orca's registry changes only through normal review and platform tests; no upstream synchronization script owns it.

The portable root does not imply every agent can install it as a native plugin. Cursor can consume the root plugin.json package directly. Claude expects .claude-plugin/plugin.json; Codex and ChatGPT expect .codex-plugin/plugin.json; the Codex IDE extension does not currently support plugins. Orca therefore installs loose skills by default and may generate provider-native adapters for detected compatible clients:

  • Cursor: use the portable package directly.
  • Claude: generate .claude-plugin/plugin.json from validated bundle metadata.
  • Codex/ChatGPT: generate .codex-plugin/plugin.json from validated bundle metadata.
  • Other or unsupported agents: install the selected loose skills.

Native plugin installation never becomes the only path. Provenance connects every loose installed skill to its source bundle and immutable version.

Installer components

Create narrow modules with explicit responsibilities:

Shared contracts

  • src/shared/skill-package-manifest.ts: bundle manifest, portable plugin manifest, and canonical validation.
  • src/shared/skill-install-contract.ts: bundle selection, per-skill preview, conflict, placement, and result types.
  • src/shared/skill-install-capability.ts: runtime capability name and compatibility message.

Main/runtime implementation

  • src/main/skills/skill-package-creation.ts: source observation, stable staging, and archive creation.
  • src/main/skills/skill-package-extraction.ts: bounded archive inspection and extraction.
  • src/main/skills/skill-package-download.ts: grant validation, host allowlisting, streaming, and compressed-byte limits.
  • src/main/skills/skill-install-destinations.ts: global, workspace, WSL, and provider path resolution.
  • src/main/skills/skill-provider-destinations.ts: Orca-owned provider registry.
  • src/main/skills/skill-install-planner.ts: current-state inspection and conflict decisions.
  • src/main/skills/skill-install-transaction.ts: locking, staging, commit journal, rollback, and recovery.
  • src/main/skills/skill-placement-reconciliation.ts: aliases, junctions, and verified copy fallback.
  • src/main/skills/skill-install-provenance.ts: bounded receipts and recovery data.
  • src/main/skills/skill-install-service.ts: orchestration and structured results.

Reuse observeSkillPackage and the existing topology/freshness logic directly. Reuse the design of plugin staging, provenance, lock serialization, and Windows rename retries, but do not import plugin-domain modules into the skill domain. Promote a primitive only when both domains can name and test the same contract accurately.

Cloud client

  • Skill upload grant creation and finalization.
  • Authenticated share creation and revocation; anonymous share resolution.
  • Download grant creation.
  • Owned-package management and exact package/version lookup by ID; no browse or search API.
  • Authenticated owner-only active-link inventory for cross-device copy and revocation; no public or recipient inventory.
  • Manager-only package details include ownership and active, unexpired share records; anonymous recipients never receive management metadata.

Exact files follow the repository that owns Orca Cloud APIs; desktop contracts stay provider neutral.

Runtime and IPC

  • Extend the existing skill RPC registration with preview/install/update/remove methods.
  • Register the same operations through desktop IPC.
  • Route every request to the runtime that owns the selected machine and workspace.
  • Keep package transfer separate from installation so direct download and chunked relay converge on one staged file.

Renderer

  • Multi-select bundle share review and unlisted-link warning.
  • Share completion dialog with copyable durable link.
  • Active-link copy/revocation, immutable-version deletion, and Cloud-package deletion with explicit confirmation and copy explaining that installed copies remain local.
  • Settings → Share Skills owner inventory so newly published links remain manageable even when the source skill has no managed-install receipt.
  • Selective install preview with destination, scope, coverage, and per-skill conflict state.
  • Aggregate install progress and grouped per-skill outcomes.
  • Installed/shared bundle management, update, rollback, removal, and incomplete-coverage actions on the Skills page.

Install request and result contract

Conceptual request:

type SkillBundleInstallRequest = {
  operationId: string
  package: {
    packageId: string
    versionId: string
    bundleDigest: string
    compressedBytes: number
  }
  selectedSkillIds: string[]
  ingress:
    | { kind: 'download-grant'; url: string; expiresAt: string }
    | { kind: 'staged-upload'; uploadId: string }
    | { kind: 'local-file'; path: string }
  destination:
    | { scope: 'global'; environmentId?: string }
    | { scope: 'workspace'; worktreeId?: string; folderWorkspaceId?: string }
  conflictResolutions?: Record<
    string,
    'keep-local' | 'replace-unmodified' | 'replace-and-discard-local'
  >
}

local-file.path is accepted only across an in-process trusted boundary. It is not exposed as an arbitrary remote RPC path.

Conceptual result:

type SkillBundleInstallResult = {
  operationId: string
  packageId: string
  versionId: string
  bundleDigest: string
  status: 'complete' | 'partial' | 'failed'
  skills: Array<{
    skillId: string
    name: string
    status: 'installed' | 'updated' | 'unchanged' | 'kept-local' | 'failed'
    canonicalPath?: string
    placements: Array<{
      provider: string
      path: string
      topology: 'canonical-copy' | 'provider-alias' | 'independent-copy'
      status: 'installed' | 'unchanged' | 'skipped' | 'failed'
      errorCategory?: string
    }>
    conflict?: {
      kind: 'modified' | 'unowned' | 'external-link' | 'name-collision'
      existingDigest?: string
    }
    errorCategory?: string
  }>
}

The response never includes a download grant or credentials.

Installation algorithm

1. Admission

  • Validate all request fields, package identifiers, selected skill IDs, and per-skill decisions.
  • Resolve the destination through host-owned runtime state.
  • Confirm the requested scope is writable and contained in an allowed home or workspace root.
  • Reject an expired grant before network access.
  • Deduplicate retries using operationId, package/version, selected skill set, and destination.

2. Lock

  • Acquire locks for selected canonical destinations in deterministic skill-name order.
  • Use an atomic lock-directory or exclusive-file creation supported on all target platforms.
  • Record a random owner token and start time.
  • Recover a stale lock only after validating its journal and owner liveness policy.
  • Bound lock wait time and return a retryable busy result.

An in-process promise chain alone is insufficient because the desktop, headless runtime, CLI, or SSH helper may run concurrently.

3. Ingress

  • Stream the archive into a bounded temporary file.
  • For grants, require HTTPS when the configured cloud endpoint is HTTPS and restrict redirects and final hosts to approved Orca storage origins.
  • Abort when compressed bytes exceed the manifest contract.
  • Hash while streaming and compare the archive identity supplied by Cloud.
  • Delete partial bytes on cancellation, expiration, disconnect, or failure.

4. Extract and inspect

  • Create extraction staging on the same filesystem as the canonical destination.
  • Reject absolute paths, .., drive prefixes, NUL bytes, links, devices, FIFOs, sockets, encrypted entries, duplicate normalized paths, and case-fold collisions.
  • Enforce compressed, extracted, entry, file, depth, and per-file limits during extraction.
  • Validate manifest.json before trusting file metadata.
  • Observe skill/ with observeSkillPackage and compare every file and the package digest.
  • Parse SKILL.md and require its identity to agree with the package name.

5. Inspect current state

Classify the canonical destination and all requested provider placements.

Canonical outcomes:

  • Missing: install is allowed.
  • Same requested digest: no-op; continue to placement repair.
  • Matches Orca receipt and remains unmodified: update is allowed.
  • Differs from its Orca receipt: return a modified conflict.
  • Exists without Orca provenance: return an unowned conflict.
  • External or broken link: return a topology conflict.

Provider outcomes:

  • Correct alias or matching Orca-owned fallback copy: no-op.
  • Missing: create after canonical commit.
  • Broken Orca-owned alias: repair.
  • Unowned or modified placement: leave untouched and report incomplete coverage unless the user explicitly chooses replacement.

The preview and final install repeat current-state inspection. A state change between preview and commit invalidates the preview and requires a new decision.

6. Prepare commit

  • Copy extracted skill/ into a hidden sibling staging directory.
  • Preserve executable modes.
  • Observe the copy and require the expected digest again.
  • Write a durable transaction journal before moving the current destination.
  • Keep the replacement and backup on the destination filesystem so directory renames do not cross volumes.

7. Commit canonical copy

  • If an existing destination is approved for replacement, rename it to the journal's backup path.
  • Rename the verified staging directory into the canonical path.
  • Use bounded Windows retry behavior for antivirus/indexer EPERM, EACCES, and EBUSY races.
  • Observe the installed path and require the requested digest.
  • On failure, restore the backup and retain enough journal state for startup recovery.

Directory replacement is crash-recoverable rather than assumed to be a single atomic overwrite on every platform.

8. Reconcile provider placements

  • Create aliases relative to their real parent directory on POSIX.
  • Use directory junctions with absolute targets on Windows.
  • Detect parent directories that are already symlinked to canonical storage.
  • If an alias mechanism fails, create and verify an independent copy when policy allows.
  • Reconcile each placement idempotently.

Canonical success is retained when one provider placement fails. The result is partial, and the UI offers retry. Rolling back a valid universal installation because one optional alias failed would make recovery less reliable.

9. Publish provenance

Write a bounded, versioned receipt outside the installed skill folder containing:

  • Package and version IDs.
  • Expected package digest.
  • Scope and destination identity.
  • Canonical path identity.
  • Provider placements and topologies.
  • Previous version identity for interrupted-update recovery.
  • Installation timestamp and Orca host/runtime identity.

Do not store credentials, download URLs, share bearer values, or package contents.

Serialize receipt updates, write them durably through a temporary file and rename, and support reconstruction from per-install provenance if the aggregate index is corrupt.

After the receipt is durable, mark the journal complete and delete transactional backups and staging bytes.

10. Verify and publish result

  • Run skill discovery on the destination target.
  • Confirm the canonical skill and successful provider placements are observable.
  • Return observed status and error categories rather than relying on process exit alone.
  • Invalidate renderer skill caches and refresh the Skills page.

Update behavior

  1. Resolve the latest accessible immutable version from Cloud.
  2. Compare its digest with the receipt.
  3. Observe installed bytes before offering the update.
  4. If bytes match the receipt, use the normal installation transaction.
  5. If bytes were modified, offer:
    • Keep local version.
    • Publish local bytes as a new immutable version when exactly one non-missing Orca-managed install matches the skill name and scope; Cloud rechecks ownership of that stable package ID.
    • Replace and discard local changes after explicit confirmation.
  6. Reconcile all recorded aliases and fallback copies.
  7. Preserve the previous package version in Cloud; rollback is a normal install of that immutable version.

Do not invoke npx skills update for Orca-owned packages or write entries that cause the community CLI to claim ownership of them.

Removal behavior

  1. Read Orca provenance and observe every recorded placement.
  2. Remove only aliases that still point to the recorded canonical path.
  3. Remove independent copies only when their bytes still match their recorded digest, unless the user explicitly confirms discarding modifications.
  4. Remove the canonical copy only when it is Orca-owned, unmodified, and no retained placement or receipt depends on it.
  5. Publish the provenance change durably.
  6. Leave an unowned or changed destination untouched and report what remains.

Cloud package deletion and local removal are separate actions. Revoking a share prevents new downloads but does not silently delete already installed local files.

Remote, SSH, and mixed-version compatibility

Add a static runtime capability:

skills.install.v1

Clients check it before sending installation RPCs. Older servers continue supporting discovery but do not show remote install actions. A missing capability produces an update-required message.

Adding new RPC methods and a static capability does not require a runtime protocol bump. New fields remain optional until all supported peers understand them. No new terminal stream opcode is needed.

Recommended RPC surface:

  • skills.install.preview
  • skills.install.beginUpload
  • skills.install.uploadChunk
  • skills.install.commitUpload
  • skills.install.cancelUpload
  • skills.install.execute
  • skills.install.update
  • skills.install.remove

Upload sessions are bounded by count, bytes, idle lifetime, and chunk size. Offsets are monotonic; retries either repeat an acknowledged chunk idempotently or restart the upload. Disconnect and cancellation release staging bytes. Installation RPC retries are also bounded. Because operation IDs make commit idempotent, a direct install can converge after its response is lost; a staged install rebuilds the upload before retrying because the first host attempt may already have consumed it.

Client cancellation is carried through the local runtime-call queue and every paired request transport. A queued call is removed before it starts; an in-flight one-shot request closes only its socket; cached and shared-control requests release only their own request state so unrelated users of the connection continue. Late responses for cancelled shared requests are retired and ignored. This is local transport behavior and does not change the mixed-version wire contract; the existing operation-ID cancellation RPC remains responsible for converging host-side installation work.

SSH Relay errors retain JSON-RPC numeric codes on the wire. Known skill failures add optional, schema-validated error.data; arbitrary handler data is never published. This is additive for mixed versions and gives SSH the same stable error categories as native and paired installation without exposing package contents or credentials.

The runtime that executes installation owns:

  • Home and config-directory resolution.
  • Workspace/folder identity resolution.
  • WSL distro selection.
  • Agent detection and provider paths.
  • Filesystem mutation and recovery.

The calling client owns:

  • User authentication and share authorization.
  • Destination selection.
  • Obtaining a grant or providing package chunks.
  • Rendering preview, progress, conflicts, and results.

Security and privacy controls

The detailed threat register and residual release gates live in docs/reference/agent-skill-sharing-threat-model.md.

  • Treat SKILL.md and packaged scripts as executable code for trust messaging.
  • Show version, digest, file summary, and executable files before install without exposing internal publisher or organization identifiers.
  • Require the exact active bearer share ID for recipient resolution and every download grant; require authentication for publication and owner management.
  • Bind grants to one package version, digest, maximum byte count, and short expiration.
  • Validate grant and redirect hosts to prevent server-side request forgery.
  • Never execute package scripts during installation.
  • Reject links and special files before they can be published or extracted.
  • Keep package staging owner-only where platform permissions support it.
  • Avoid logging file contents, share tokens, signed URLs, or organization-private names.
  • Audit authorization and lifecycle events without storing skill contents in telemetry.
  • Apply organization deletion and retention policy to metadata and blobs.
  • Rate-limit uploads, downloads, share resolution, and remote transfer sessions.
  • Use constant-shape authorization failures so private package existence is not disclosed.

Failure and recovery model

The transaction journal records enough state to classify interrupted operations:

  • Download only: delete partial archive.
  • Extracted but not committed: delete staging.
  • Existing destination moved to backup: restore backup.
  • New destination placed but receipt absent: verify new digest, then either finish receipt publication or restore backup according to journal state.
  • Receipt published but journal incomplete: verify receipt and installed digest, then finalize.
  • Alias reconciliation interrupted: preserve canonical installation and retry reconciliation.

Recovery runs before a new operation for the same destination and during bounded startup cleanup. It never removes an unknown path based only on a filename pattern; the journal owner token, destination containment, and expected identities must all agree.

Testing strategy

Package tests

  • Deterministic manifest and digest generation.
  • Source changes during packaging.
  • CRLF/LF identity behavior.
  • Executable mode preservation.
  • Missing or malformed SKILL.md.
  • Excessive depth, entries, files, individual size, total size, and compressed size.
  • Traversal, absolute paths, Windows drive paths, Unicode/case collisions, duplicate paths, symlinks, hardlinks, devices, FIFOs, sockets, and encrypted entries.
  • Truncated and checksum-invalid archives.
  • Invalid gzip bytes with a stable non-retryable archive failure.

Transaction tests

  • Fresh install, identical reinstall, clean update, and explicit replacement.
  • Modified and unowned conflicts.
  • Existing canonical or provider paths that are files, directories, links, or broken links.
  • Failure before and after every journal transition.
  • Backup restoration and idempotent recovery.
  • Concurrent desktop, runtime, and CLI attempts.
  • Cancellation during download, extraction, copy, commit, and alias reconciliation.
  • Antivirus-style Windows rename contention.
  • Permission failures and read-only destinations.
  • Permission and disk-capacity failure injection that preserves the prior installed version.
  • Alias failure with verified copy fallback.
  • Independent copy drift during update and removal.
  • Lost final-response retry for direct installs and staged-transfer rebuild before retry.

Target matrix

  • macOS ARM64 and x64 behavior where available.
  • Linux at the supported Ubuntu 20.04/glibc 2.31 floor.
  • Windows with junction success, junction denial, copy fallback, and long paths.
  • WSL with multiple distros and distro-owned home resolution.
  • Local Git worktree and plain folder workspace.
  • Paired remote runtimes in both client-newer and server-newer combinations.
  • SSH-only macOS/Linux/Windows targets where supported by existing providers.
  • Remote target with no outbound Cloud connectivity using chunked transfer.

Cloud tests

  • Anonymous active-link resolution, expiry, revocation, and non-disclosing missing-link failures.
  • Owner authentication for package and share management.
  • Upload finalization digest mismatch.
  • Blob deduplication without cross-tenant information leakage.
  • Quota and rate-limit behavior.
  • Durable share resolving to the intended immutable version.
  • Version update and rollback.

End-to-end journeys

  1. Share on machine A, install globally on machine B, launch a detected agent, and discover the skill.
  2. Share on machine A, install into a folder workspace on a connected remote runtime, and discover it only in that workspace.
  3. Modify the installed copy, publish an update, and prove Orca refuses silent replacement.
  4. Disconnect during commit, reconnect, recover, and obtain either the complete old or complete new version.
  5. Revoke a share, prove new installation fails, and prove an existing local installation remains.

Observability

Record bounded operational metrics:

  • Package byte/file counts and stage durations.
  • Download versus client-mediated transfer selection.
  • Install outcomes by category.
  • Conflict categories.
  • Alias, junction, and copy-fallback rates.
  • Recovery and rollback counts.
  • Runtime capability absence.
  • Error categories by operating system and target kind.

Do not record skill contents, file names beyond approved aggregate categories, private share URLs, download grants, access lists, or raw local paths.

User-facing logs show phase, destination label, placement outcome, and actionable error. Sensitive network values are redacted at creation rather than scrubbed after logging.

Delivery phases

Phase 0: contracts and vertical spike

Deliver:

  • Package manifest schema.
  • Local package builder and bounded extractor.
  • A programmatic install call from a validated staging directory into a temporary canonical root.
  • Fresh install and modified-conflict tests on macOS, Linux, and Windows CI.
  • Decision record confirming upstream is behavioral-reference-only and no material is copied.

Exit criteria:

  • No npx or Node installation dependency outside Orca's own runtime.
  • Same bytes produce the same digest on every target platform.
  • Invalid archive classes fail before destination mutation.

Estimate: 23 engineer-days for the spike, followed by design review.

Phase 1: production local installer

Deliver:

  • Cross-process lock.
  • Durable journal and recovery.
  • Canonical install, update, and removal.
  • Provenance receipts and aggregate index recovery.
  • Provider registry for Orca's primary detected agents.
  • POSIX aliases, Windows junctions, and verified copy fallback.
  • Structured preview/result contracts.
  • CLI-only developer harness for deterministic integration tests.

Exit criteria:

  • Failure injection at every commit boundary preserves either the previous or requested complete package.
  • Local modifications are never silently replaced.
  • Folder workspaces and global scope pass the platform matrix.

Estimate: 58 engineer-days.

Phase 2: private Cloud sharing

Deliver:

  • Reviewed Terraform for the dedicated private GCS bucket, lifecycle, CORS, bucket-scoped IAM, service-account signing, orca_skills database, database secret, Cloud SQL attachment, monitoring, and budgets.
  • PostgreSQL migrations for package, version, upload, share, ownership, and audit records, with legacy ACL storage tolerated during migration.
  • Upload/finalize APIs using bounded V4 signed POST policies and private content-addressed GCS objects.
  • Version, bearer-share, revocation, five-minute download grant, quota, and audit behavior.
  • Share preview and owner-management UI.
  • Install preview and local-machine installation UI.
  • Durable links and short-lived grants.
  • Update availability and version rollback.

Exit criteria:

  • A copied active durable link can be inspected and installed without recipient sign-in.
  • Revocation immediately blocks new grants.
  • The installed receipt identifies the immutable package without persisting a grant.
  • Production provisioning changes are Terraform-owned and do not replace existing artifact, Cloud SQL, or Cloud Run resources.

Estimate: 12 engineer-weeks across desktop and Cloud work.

Phase 3: paired Orca runtime installation

Deliver:

  • skills.install.v1 capability.
  • Runtime preview/install/update/remove methods.
  • Direct runtime download.
  • Bounded client-mediated upload fallback.
  • Destination-machine and remote-workspace selection.
  • Mixed-version UI and compatibility tests.

Exit criteria:

  • Installation executes on the selected host and uses that host's home, workspace, and detected agents.
  • Older hosts are not called and receive a clear update-required state.
  • A host without outbound internet installs through the authenticated chunked transfer path.

Estimate: 47 engineer-days.

Phase 4: WSL and SSH completion

Deliver:

  • Distro-owned package ingress and installer execution.
  • SSH package upload and host-side structured installer invocation.
  • Cross-target cancellation and cleanup.
  • WSL/SSH provider detection and path coverage.
  • Real-host end-to-end coverage.

Exit criteria:

  • No desktop path is substituted for a WSL, SSH, or runtime path.
  • SSH and WSL return the same result contract as native installation.
  • Failure and cancellation leave no untracked staging bytes outside bounded recovery retention.

Estimate: 47 engineer-days, depending on host-helper availability.

Phase 5: multi-machine management and reconciliation

Deliver:

  • “Install on another machine” and multi-machine progress.
  • Optional desired-version policy for selected personal or organization machines.
  • Drift and missing-install reconciliation.
  • Explicit project desired-state manifest if validated by product usage.
  • Direct machine-to-machine transfer as an alternative to Cloud persistence if required.

Exit criteria:

  • Reconciliation remains opt-in and never overwrites local modifications.
  • Offline machines converge after reconnect without sharing durable credentials.
  • Organization removal, user departure, and package retention have documented semantics.

Estimate: separate product milestone after first-release usage data.

Release gates

Before enabling Cloud or remote installation by default:

  • Threat-model review covers package ingestion, grants, SSRF, archive extraction, local path containment, and instruction/script trust.
  • Cross-platform CI covers the package and transaction suites.
  • Real Windows validates junction and copy fallback.
  • Real WSL and SSH validate host-owned paths.
  • Mixed-version remote tests cover old client/new server and new client/old server.
  • Download/upload cancellation and app/runtime crash recovery are exercised.
  • Telemetry and diagnostic bundles are verified not to contain grants or private contents.
  • Share deletion, revocation, organization departure, and retention behavior are documented.
  • The UI identifies the author and executable content before installation.
  • A kill switch can disable new Cloud grants and remote installs without affecting discovery or already installed skills.

Effort summary

For one engineer familiar with Orca:

Scope Estimate
Disposable canonical-copy prototype 12 days
Production local installer 58 days
Cloud sharing and local install UX 12 weeks
Paired runtime support 47 days
WSL and SSH completion 47 days
Polished first release Approximately 35 engineer-weeks
Full community CLI parity 610 weeks plus ongoing registry maintenance

The recommended first release ends after Phase 4. Phase 5 should follow observed demand rather than delaying private sharing for organization-wide policy features.

Implementation principles

  • One validated installer core, regardless of source or destination transport.
  • One canonical copy, with provider placements reconciled separately.
  • Immutable Cloud versions and mutable local installations are distinct concepts.
  • An unpredictable durable share ID is a revocable bearer credential, not a permanent blob URL.
  • Installed bytes, not child-process exit codes, determine success.
  • Unknown or modified local state fails closed.
  • Remote hosts own their paths and mutations.
  • Upstream behavior informs compatibility but does not define Orca's internal architecture.