mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-02 08:28:48 +01:00
Merge master into native backup expiration
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
commit
882ece69cd
126 files changed
+5887
-1286
No files matched your search
+82
-21
@@ -146,19 +146,19 @@ New workflow versions merged into master then receive runner access without a
|
||||
separate SHA allowlist update. Dependabot leaves this first-party reference on
|
||||
master.
|
||||
|
||||
Runner selection calls `ci-routing.yml@master` on the dedicated
|
||||
`paperclip-ci-routing-x64` AWS Fleet. The `paperclip-ci-routing` runner group
|
||||
admits only `paperclipai/paperclip/.github/workflows/ci-routing.yml@refs/heads/master`
|
||||
and repository ID `1170821064`. GitHub evaluates the canonical repository, author, and sender checks before
|
||||
allocating reserved capacity. The validated admission snapshot (`AWS_CI_ROUTING_USER_IDS_SOURCE` and
|
||||
`AWS_CI_ROUTING_USER_IDS`) must match `AWS_CI_TRUSTED_USER_IDS`. Refresh it through
|
||||
the runner-group configuration helper when the roster changes. Missing, stale,
|
||||
or malformed settings keep hosted routing available without evaluating JSON
|
||||
in the job's placement expression. Unapproved PRs use hosted metadata routing;
|
||||
approved manual canaries on master can use the reserved pool. The routing
|
||||
workflow reads GitHub metadata without checking out or executing PR code. Its author, sender, rerun actor,
|
||||
repository, head, and merge validation still decide whether tests can use AWS.
|
||||
Unapproved test workloads continue to use GitHub-hosted runners.
|
||||
Runner selection calls `ci-routing.yml@master` on a GitHub-hosted runner. It
|
||||
verifies authorization before allocating any AWS capacity and never checks out
|
||||
or executes PR code. The author, event sender and rerun actor must each be both
|
||||
in `AWS_CI_TRUSTED_USER_IDS` and a current owner of `.github/**` in CODEOWNERS.
|
||||
The resolver and CODEOWNERS are read from the same protected master revision;
|
||||
PR edits cannot change the trusted owner list. Documentation-only owners,
|
||||
unsupported owner rules and failed identity lookups do not authorize AWS.
|
||||
Repository, head and merge validation also apply. Missing or malformed settings
|
||||
and unverifiable authorization use GitHub-hosted runners. A maintainer rerunning
|
||||
an outside contributor's PR does not grant it AWS access.
|
||||
Authorized test jobs and the final `verify` and `e2e` aggregates use the selected
|
||||
AWS fleet. The metadata authorization job remains hosted even for maintainers,
|
||||
so stale admission snapshots cannot allocate an AWS runner before verification.
|
||||
|
||||
The routing workflow also selects the CI scope. Middle PRs in a stack and PRs
|
||||
whose diff changes only release notes (`releases/v*.md` or
|
||||
@@ -213,7 +213,11 @@ coverage without paying for another graph traversal. Filesystem, subprocess, net
|
||||
dynamic-loader, unresolved, and unapproved external-package consumers are
|
||||
retained conservatively, including indirect consumers through local helpers.
|
||||
The selector explicitly tracks setup/configuration dependencies as well as test
|
||||
imports. The small pure-dependency allowlist lives in
|
||||
imports. Ordinary source names such as `session-config-metadata.test.ts` or
|
||||
`setup-state.ts` remain eligible; the words `config` and `setup` alone do not
|
||||
force full CI. Conventional Vite/Vitest config and setup files remain broad
|
||||
inputs. Other resolved setup/config dependencies invalidate their entire project.
|
||||
The small pure-dependency allowlist lives in
|
||||
`scripts/ci/vitest-selection-graph.mjs`; new external packages remain opaque
|
||||
until reviewed. This is deliberately broader than `vitest related` alone.
|
||||
For conservative retention, explicit complete local mock factories cut the
|
||||
@@ -236,6 +240,9 @@ existing selection/execution rules. The job summary reports files and jobs
|
||||
selected per lane, and the `vitest-selection` artifact records the manifest and
|
||||
dependency audit. Selected jobs execute exact Vitest test specifications, so
|
||||
similarly named `.test.ts` and `.test.tsx` files cannot overlap between shards.
|
||||
The wrapper consumes and validates the selection before launching Vitest, then
|
||||
removes selection environment variables from the test process. Nested runner
|
||||
fixtures therefore use their own checkout and test inventory.
|
||||
|
||||
Missing/deleted/renamed source files, non-exempt non-source inputs, unrecognized graph inputs,
|
||||
setup/config changes, failed dependency installs, graph errors and timeouts use
|
||||
@@ -288,13 +295,10 @@ explicit. When changing shard layout, update `.github/ci-task-matrix.json` and
|
||||
the full fallback matrices in `pr-trusted.yml`; the contract tests require them
|
||||
to agree. Add new cache-affecting environment settings to `globalEnv`.
|
||||
|
||||
The routing Fleet has two warm On-Demand runners and a four-runner ceiling.
|
||||
Test fleets cannot consume its runner slots. Hosted test queues therefore do
|
||||
not block AWS runner selection. A manual dispatch of `ci-routing.yml` on master
|
||||
checks placement without launching the test matrix; its non-PR event returns
|
||||
the hosted test-runner output. Configure and verify the group and Fleet before
|
||||
merging this caller. To roll back, restore the hosted gate and retain the routing
|
||||
workflow authorization until assigned jobs finish.
|
||||
The former reserved routing Fleet is no longer selected by this workflow.
|
||||
Keep its existing authorization until older assigned jobs finish. A manual
|
||||
dispatch of `ci-routing.yml` on master exercises the hosted metadata job without
|
||||
launching the test matrix; its non-PR event returns the hosted test-runner output.
|
||||
|
||||
Keep the `.github/**` rule in `.github/CODEOWNERS` and the active master ruleset's
|
||||
code-owner review requirement enabled. This covers the caller, the trusted
|
||||
@@ -1507,6 +1511,45 @@ Configure storage provider/settings:
|
||||
pnpm paperclipai configure --section storage
|
||||
```
|
||||
|
||||
### Managed cloud prerequisites
|
||||
|
||||
A nonblank Cloud tenant token or the presence of `PAPERCLIP_MANAGED_CONFIG`
|
||||
selects the managed-cloud profile. A supplied blank or invalid managed feature
|
||||
document refuses startup. Without either signal, the instance remains self-hosted.
|
||||
The managed profile also requires:
|
||||
|
||||
- `PAPERCLIP_STORAGE_PROVIDER=s3` or `storage.provider: "s3"` in the canonical
|
||||
database snapshot. An invalid explicit environment value refuses startup even
|
||||
if the snapshot selects S3.
|
||||
- An explicit nonblank `PAPERCLIP_STORAGE_S3_BUCKET` or `storage.s3.bucket`.
|
||||
The self-hosted `paperclip` bucket default does not qualify. The region defaults
|
||||
to `us-east-1`; an explicit blank region refuses startup. An optional endpoint
|
||||
must be an HTTP(S) URL without embedded credentials.
|
||||
- An external PostgreSQL URL from the environment `DATABASE_URL`.
|
||||
The managed profile never falls back to embedded PostgreSQL.
|
||||
- A stable `PAPERCLIP_SECRETS_MASTER_KEY` supplied by the deployment secret store.
|
||||
Use the same value across replacements. The existing provider accepts 32-byte
|
||||
base64, 64-character hex, or a raw 32-byte UTF-8 string. A key file alone does
|
||||
not qualify because a replacement web server may not have that file.
|
||||
|
||||
Bootstrap validates the environment database URL and encryption master key before
|
||||
opening the database or creating local state. Effective storage validation follows
|
||||
canonical snapshot resolution, before signing keys, first-party Telemetry or app
|
||||
construction. Raw canonical rows and legacy S3 imports cannot obtain a missing
|
||||
bucket from schema defaults. Already-stored nonblank bucket values remain
|
||||
canonical, including the deliberate name `paperclip`; prior normalization cannot
|
||||
reliably establish their original provenance.
|
||||
It does not contact S3 or verify credentials, bucket access, database connectivity,
|
||||
or that a key matches existing encrypted data. Operators must qualify ordinary
|
||||
S3 put/read/delete with deployment credentials and preserve the existing key.
|
||||
AWS credentials continue to use the provider's normal SDK credential chain.
|
||||
Local and self-hosted storage and key-file defaults remain unchanged.
|
||||
|
||||
These are prerequisites for shared storage and secrets. They do not establish
|
||||
that the whole web server is disposable or that all execution and recovery paths
|
||||
survive web-server replacement. Run-log/trace storage and producer retention are
|
||||
separate changes.
|
||||
|
||||
## Agent Artifact Uploads
|
||||
|
||||
When an agent generates a file that a board user or reviewer should inspect as
|
||||
@@ -2694,6 +2737,24 @@ and hard restarts with live and dead runners, the result-finalization race,
|
||||
incomplete bootstrap, repeated crashes with steering, and fail-closed process
|
||||
identity mismatches.
|
||||
|
||||
## Version-based skill authoring and delivery
|
||||
|
||||
Managed content uses `managed-skill-content.ts`: prepare and verify outside the
|
||||
publication transaction, then compare the captured head and publish version,
|
||||
projections, audit and applicable receipt together. `skill-execution-content.ts`
|
||||
owns disposable filesystem bindings. Do not write managed installed directories
|
||||
or infer missing content from an absent cache. Keep linked-local behavior explicit.
|
||||
|
||||
The [conversion and qualification guide](skill-ephemeral-web-servers.md) documents
|
||||
bounded eligibility/verification commands and the one-time writer maintenance
|
||||
boundary. `managed-skill-content.test.ts` covers the focused domain behavior;
|
||||
`ephemeral-skills-process.test.ts` requires independent disposable Postgres and
|
||||
S3 fixtures and starts separate Node processes. The optional
|
||||
`PAPERCLIP_TEST_POSTGRES_ADMIN_URL` creates a random test database per suite.
|
||||
On hosts with unavailable Tailscale, set `PAPERCLIP_TAILNET_BIND_HOST=127.0.0.1`
|
||||
for local fixtures to avoid repeated CLI discovery. Do not use fixture timings
|
||||
collected during builds as hosted performance evidence.
|
||||
|
||||
## App-Shipped Skills Catalog
|
||||
|
||||
Skill-library reads still reconcile bundled releases, folders, and direct local
|
||||
|
||||
@@ -184,6 +184,16 @@ Source feeds and project task lists retain their existing access rules.
|
||||
|
||||
Company skills are shared operating capabilities, not privileged objects by default. Every authenticated agent in a company can create, import, install, edit, update, test, reset, and remove that company's skills unless the company has configured an explicit restriction.
|
||||
|
||||
Paperclip-managed skills are immutable saved versions. Studio and API authoring
|
||||
publish complete content before acknowledging a save; stale edits return a version
|
||||
conflict and Studio retains the draft. Installed repository skills use the same
|
||||
version-based reads and execution selection. Web-server files are disposable caches
|
||||
and staging, so compatible replacement servers can read, edit and deliver protected
|
||||
versions from the same database and remote object storage. Explicit linked-local
|
||||
sources retain local behavior. Active or recovering run pins prevent deletion even
|
||||
after an agent detaches the skill. See [ephemeral-server skills](skill-ephemeral-web-servers.md)
|
||||
for conversion, compatibility and qualification boundaries.
|
||||
|
||||
The governing rule is: **skill permissions are opt-in restrictions, not opt-in capabilities**. Missing skill grants never create a denial in an otherwise unconfigured company, and ordinary skill work does not require board confirmation, a draft-only workflow, or an activation approval.
|
||||
|
||||
Core Paperclip owns the skill runtime, company-boundary enforcement, policy evaluation contract, API denials, validation, path containment, secret redaction, and activity logging. Those safety invariants cannot be disabled by policy. Open-by-default skill work never authorizes arbitrary host-path reads, unsafe executable content, or policy edits: local imports and scans must stay within Paperclip-known workspace or managed-skill roots, remote sources must resolve to validated immutable content, and platform safety denials must stay distinct from optional administrative restrictions. Paperclip EE may provide detailed administration for per-agent, per-role, per-action, per-source, and protected-skill rules, but EE is not required to use skills and is not an enforcement boundary. Without EE, companies remain open by default and any already-configured restrictions continue to be enforced by core.
|
||||
|
||||
@@ -2375,6 +2375,15 @@ unavailable. Preserve current ownership and newer-work fences. See
|
||||
is automatic and bounded. Unused Git caches can expire and reacquire the recorded
|
||||
commit after current authorization and hash checks; authored/unproven legacy bytes
|
||||
remain durable. See [skill package storage](skill-package-storage.md).
|
||||
- Paperclip ownership is `managed`, with a null source locator and an immutable
|
||||
current version. Content mutations prepare durable bytes before a short,
|
||||
authorization-checked compare-and-swap publication. Acknowledged changes do not
|
||||
depend on an installed web-server directory. Repository installations use the
|
||||
same committed-version read and execution boundary; linked-local sources are
|
||||
explicitly outside the empty-disk guarantee. Execution selections, including
|
||||
empty selections, persist before delivery; recovery reconstructs exact admitted
|
||||
digests and active/recovering pins prevent deletion. See
|
||||
[conversion and compatible upgrades](skill-ephemeral-web-servers.md).
|
||||
- Refresh is serialized per source, checks saved selection revisions, and publishes
|
||||
valid skills plus per-entry outcomes with required activity records in one transaction.
|
||||
Failed packages retain prior versions; access/scan/download failures retain all content.
|
||||
@@ -2382,7 +2391,7 @@ unavailable. Preserve current ownership and newer-work fences. See
|
||||
- Match by repository identity and exact path. Preserve IDs, keys, assignments, folders,
|
||||
and history. New key collisions cannot overwrite unrelated skills. Only changed package
|
||||
bytes or executable modes create versions. Library reads, tests, and subsequent unpinned
|
||||
runs use local installed snapshots; pinned/active runs retain their versions.
|
||||
runs use immutable installed snapshots; pinned/active runs retain their versions.
|
||||
- Runtime version directories are disposable caches. An hourly, bounded sweep may
|
||||
evict non-current copies unused for one hour, preserving active and unresolved
|
||||
execution pins. Selection, materialization, and pin persistence serialize with
|
||||
|
||||
+4
-3
@@ -24,10 +24,11 @@ Ordinary PRs do not write timing artifacts or export traces. The exporter job is
|
||||
skipped for ordinary run names. Adding another label does not run the CI matrix.
|
||||
|
||||
Profiling preserves the existing trusted AWS runner routing. Eligible PR jobs
|
||||
use `paperclip-public-pr-x64`; the routing gate uses `paperclip-ci-routing-x64`.
|
||||
use `paperclip-public-pr-x64`; the routing gate uses `ubuntu-latest` to verify
|
||||
current CI CODEOWNERS before allocating any AWS capacity.
|
||||
The existing fail-closed GitHub-hosted fallback still applies if AWS routing
|
||||
cannot be authorized. Only the separate post-run Honeycomb exporter uses
|
||||
`ubuntu-latest` directly; it is outside the measured PR suite.
|
||||
cannot be authorized. The separate post-run Honeycomb exporter also uses
|
||||
`ubuntu-latest`; it is outside the measured PR suite.
|
||||
|
||||
## Read the waterfall
|
||||
|
||||
|
||||
@@ -18,7 +18,8 @@ existing validation at application startup.
|
||||
to embedded PostgreSQL. Credentials, trust keys, provider configuration and
|
||||
deployment wiring needed before the database connection remain supplied by
|
||||
the environment or the existing secret system. This phase parses only the
|
||||
database connection record. Runtime mode, host binding and authentication
|
||||
database connection record and requires the stable environment encryption
|
||||
master key. Runtime mode, host binding and authentication
|
||||
checks wait until the saved snapshot has loaded.
|
||||
2. After schema migration and database connection, startup reads the private
|
||||
runtime configuration row. An existing invalid row or a database error stops
|
||||
@@ -38,6 +39,27 @@ existing validation at application startup.
|
||||
authentication and application services. A saved telemetry opt-out therefore
|
||||
takes effect before a telemetry client can be created.
|
||||
|
||||
Managed Cloud always requires a stable environment master key, including when
|
||||
an external default secrets provider is selected. Internal local-encrypted
|
||||
credential paths still need that key.
|
||||
|
||||
Managed Cloud validates effective S3 storage after publishing the canonical
|
||||
snapshot, before signing-key initialization, telemetry, authentication or app
|
||||
construction. Cloud requires S3 and a nonblank bucket; an authoritative absent
|
||||
configuration needs explicit environment storage settings. Raw saved snapshots
|
||||
cannot obtain a bucket from a schema default. Every legacy Cloud file must name its
|
||||
bucket before its one-time import, even if its saved provider is local disk and
|
||||
an environment bucket is present. Omission or blank values fail before seeding;
|
||||
The effective storage candidate is validated before seeding, so a rejected
|
||||
legacy file leaves no canonical row and can be corrected before retry.
|
||||
Environment overlays are not saved as operator choices. Correct that file before
|
||||
import, or use the existing absent-file/null-snapshot environment-only setup.
|
||||
Ordinary self-hosted file defaults remain unchanged.
|
||||
Already-canonical nonblank values, including `paperclip`, remain authoritative.
|
||||
Prior normalization cannot reliably distinguish an operator's deliberate name
|
||||
from a historical default, so this release does not invent retrospective
|
||||
provenance or replace those saved values.
|
||||
|
||||
Existing operator environment overlays keep precedence over saved values.
|
||||
Reading an overlaid value does not save it back to the database. Credentials and
|
||||
connection URLs are never copied into this JSONB row.
|
||||
@@ -78,8 +100,9 @@ bytes. Restart tests prove configuration restoration under a different home;
|
||||
they do not prove durable file, secret, or backup storage.
|
||||
|
||||
The decision signing service still uses `PAPERCLIP_DECISION_SIGNING_SECRET` when
|
||||
supplied and otherwise reads or creates its instance key file before the database
|
||||
connection. The local encrypted secret provider still uses its environment key
|
||||
supplied and otherwise reads or creates its instance key file. Managed Cloud
|
||||
performs that step after effective storage validation; self-hosted startup keeps
|
||||
its pre-connection ordering. The local encrypted secret provider still uses its environment key
|
||||
or existing key-file mechanism. Those byte-storage fallbacks are outside this
|
||||
configuration migration. Qualification must account for them separately; this
|
||||
PR does not establish file-free secret storage on Cloud.
|
||||
|
||||
+10
-1
@@ -61,6 +61,15 @@ self-hosted/Cloud targets and separately selected local/Daytona agents. Account
|
||||
and credential bindings stay in the private eval repo; registration and oracle
|
||||
tests do not establish a completed live pass or unattended CI qualification.
|
||||
|
||||
The deployment-targeted `question-answer-resume` journey reuses the classic
|
||||
two-question scenario and native continuation oracle on an attached target.
|
||||
It checks the actual board answers, one to three bound work runs, an agent-authored
|
||||
task document and browser readback after reload. It accepts provider questions and
|
||||
durable questions proven by an applied semantic receipt or an immutable completed
|
||||
native API mutation receipt. It does not qualify named-tool selection. Its provider owns target setup,
|
||||
usage and cleanup. Registration and local calibration do not establish a fresh
|
||||
Cloud pass or inclusion in a recurring selection.
|
||||
|
||||
The explicit-only [necessary free-text question journey](../tests/runner-e2e/README.md#necessary-free-text-question)
|
||||
checks one essential input, the rendered prompt and context, the real answer,
|
||||
one bound continuation, and an exact saved confirmation. Its four development
|
||||
@@ -547,7 +556,7 @@ any qualification claim; catalog presence alone is not a pass.
|
||||
|
||||
The explicit-only [native question/resume qualification](../tests/runner-e2e/README.md#task-continuation)
|
||||
separates a completed two-answer user journey from semantic-tool documentation
|
||||
qualification. It verifies the exact provider-pause or semantic-response-wake
|
||||
qualification. It verifies the exact provider-pause or native response-wake
|
||||
binding for each answer and preserves prior grades when the definition changes.
|
||||
|
||||
## Lifecycle behavior baseline
|
||||
|
||||
@@ -0,0 +1,462 @@
|
||||
# Skills on ephemeral web servers
|
||||
|
||||
## Qualification status
|
||||
|
||||
Implementation is in [PR #18334](https://github.com/paperclipai/paperclip/pull/18334).
|
||||
Hosted qualification uses the owned disposable
|
||||
[test tenant](https://ephemeral-skills-qa-oct-30.test.paperclip.app), external
|
||||
Postgres, S3, and a real remote Paperclip Computer. Cloud policy reserves the
|
||||
staging domain for master; the rejected staging branch request below made no
|
||||
deployment.
|
||||
|
||||
- **Passed:** independent-process PostgreSQL/S3 failure matrix; hosted A → B → C
|
||||
replacement with predecessor homes absent; C reads and executes B's acknowledged
|
||||
save; historical repository pin delivery while a newer revision is installed.
|
||||
- **Passed:** full CI and code review at `7ec495de77`, confidence 5/5, no
|
||||
unresolved findings. Workspace typecheck/build, focused regressions and the
|
||||
separate-process replacement matrix passed. Local timeout attempts remain
|
||||
recorded below; their results are not counted as passes.
|
||||
- **Passed:** compatible image rollback to `6518b323` retained the newer managed
|
||||
revisions and delivered their bytes plus the historical repository pin remotely.
|
||||
- **Passed:** deployed unassigned-skill Studio retry: the exact fork v3 was
|
||||
delivered and executed, Studio reached `succeeded`, and its output snapshot
|
||||
persisted. Independent package verification found zero blockers.
|
||||
- The maintenance CLI configuration bootstrap regression and server typecheck
|
||||
passed. The PR records final CI/review status for the commit containing this
|
||||
evidence update.
|
||||
|
||||
Runtime candidate `9200e3fcb4` contains the native Studio selection/completion and
|
||||
legacy completeness fixes. It is deployed and qualified. Later changes integrate
|
||||
master, protect drafts during a delayed UI reload, and load persisted Cloud
|
||||
configuration in the maintenance CLI; their verification is recorded separately.
|
||||
The chronological record below
|
||||
retains earlier failures and intermediate pending states; this section describes
|
||||
the current qualification status.
|
||||
|
||||
## Accepted contract
|
||||
|
||||
Given the same database, object storage, secrets, and supported application
|
||||
artifacts, a replacement server must discover, read, edit, and deliver protected
|
||||
installed skill versions without its predecessor's files or process memory.
|
||||
Disk is permitted for disposable scratch, verified caches, and execution delivery.
|
||||
Managed authoring and library operations address immutable content, not a mutable
|
||||
installed directory. Git remains the authoring source for repository skills;
|
||||
installed revisions and run pins govern delivery. Linked local sources remain an
|
||||
explicit self-hosted compatibility boundary.
|
||||
|
||||
Current, pinned, active/recovering, and authored versions retain durable bytes.
|
||||
Unused historical Git versions keep the existing expiry/exact-commit policy.
|
||||
Legacy conversion may use one maintenance window. Compatible later upgrades and
|
||||
rollback use the same remote state. Other web-server persistence, Railway traffic
|
||||
handoff, and production volume removal are outside this slice.
|
||||
|
||||
## Delivery and acceptance
|
||||
|
||||
1. Introduce managed ownership and content publication without installed paths;
|
||||
preserve access, atomic metadata/version publication, idempotency, conflicts,
|
||||
and active-run retention. Update Studio and API consumers.
|
||||
2. Separate selection/pinning from materialization; restore exact runtime digests.
|
||||
Add bounded legacy conversion and disk-independent eligibility diagnostics.
|
||||
3. Prove cold A → B → C replacements, concurrent writers, uncertain commits,
|
||||
offline upstream, corrupt/missing objects, access, retention and idle behavior.
|
||||
Run required checks and qualify one disposable staging tenant with a real
|
||||
remote agent. Finish with a reviewable PR and exact revision/evidence links.
|
||||
|
||||
## Canonical work and progress
|
||||
|
||||
- Worktree: `/Users/dotta/.codex/worktrees/d084/paperclip`
|
||||
- Branch: `codex/skills-ephemeral-web`
|
||||
- Draft PR: https://github.com/paperclipai/paperclip/pull/18334
|
||||
- Approved plan: this chat, “Skills on ephemeral web servers,” nine sections.
|
||||
- Implemented managed create/read/edit/delete-file/fork/rename/restore publication,
|
||||
immutable catalog installation/reset, Studio version conflict recovery, durable
|
||||
pre-materialization selection and exact pinned-runtime rehydration. Source
|
||||
disconnect retains immutable content and access provenance.
|
||||
- Added bounded installation conversion, eligibility and independent version
|
||||
verification to existing migration tooling; conversion requires retired writers.
|
||||
- Independent OS-process A → B → C qualification passed using owned Docker
|
||||
PostgreSQL and RustFS S3 fixtures. Real HTTP routes covered saves, supporting
|
||||
executable content, uncertain commit receipts, stale concurrent saves and upload
|
||||
crashes. This is not hosted Runner qualification.
|
||||
- Studio tests: 14 passed, including draft preservation and confirmed reload.
|
||||
- Workspace typecheck and build passed. Map checks and UI token gates passed.
|
||||
Broader compatibility coverage passed 362 cases; follow-up runs passed migration,
|
||||
policy, package, project access and retained-run cases after updating old model
|
||||
expectations. Final focused checks and the full repository suite are running.
|
||||
- One-connection tests now exercise package acquisition before the publication
|
||||
transaction. Fork reassignment also uses the transaction's database handle.
|
||||
- Host embedded Postgres cannot initialize: exhausted kernel semaphore pool.
|
||||
Owned Docker fixtures are `paperclip-skills-ephemeral-pg` (port 61006) and
|
||||
`paperclip-skills-ephemeral-s3` (port 61007). No unrelated databases changed.
|
||||
- Disposable staging tenant created through normal onboarding:
|
||||
https://ephemeral-skills-qa-oct-30.staging.paperclip.app
|
||||
Agent `dfd238b5-5e5d-43ef-b34a-cb5bff2267f3` (Skills Qualification), paused.
|
||||
OpenAI API-key setup uses the explicitly authorized local credential. Candidate
|
||||
`6518b323528b2b595c5949c3ed2c57a8d2438cb6` is building under release run
|
||||
https://github.com/paperclipai/paperclip/actions/runs/41085949238.
|
||||
Single-tenant deploy request: `c65f3677-4b4e-4687-957a-28e2bfb89451`.
|
||||
Stack `stack-pool-50f5009d5644` is user-managed during qualification so unrelated
|
||||
fleet rollouts cannot replace the test candidate. No live run claimed yet.
|
||||
- Greptile's first review found root-package path truncation, linked-local fork
|
||||
and restore regressions, and a concurrent receipt replay race. Fixed all four;
|
||||
focused review checks passed 76 server and 16 Studio tests. CI also exposed
|
||||
obsolete host-path fixtures and a company-deletion/publication race. Updated
|
||||
those fixtures and publication locking; 20 targeted integration tests passed.
|
||||
Skill detail now resolves existing metadata without seeding the entire library.
|
||||
- Remaining: finish repository checks and PR review, candidate deployment and
|
||||
fresh-home remote Runner qualification including compatible rollback. The PR
|
||||
stays draft until hosted qualification and the final checks are complete.
|
||||
- Greptile reached 5/5 with all six comments resolved at `8c0fae76a6`.
|
||||
CI at that revision passed typecheck, build, all unit/integration shards and
|
||||
Runner checks; two browser shards still require investigation. The shared-chat
|
||||
question fixture's five-second assertion raced a successful asynchronous run;
|
||||
its readiness wait now follows the existing run-settlement helper.
|
||||
- A cold metadata assertion exposed three manifest downloads during history
|
||||
listing. New versions now persist a complete metadata index and migration
|
||||
backfills legacy indexes without changing content/version identity. Process
|
||||
qualification confirmed zero metadata/warm downloads; its tiny fixture measured
|
||||
a 176 ms cold read (two objects, 899 bytes), 37 ms warm execution preparation,
|
||||
899 MB process RSS and 820 bytes of temporary files. These local fixture numbers
|
||||
are not hosted latency or incremental memory claims. A follow-up compatibility
|
||||
run caught changed file ordering; preserving the existing order fixes that drift.
|
||||
- Metadata/package compatibility passed all 44 tests after preserving file order.
|
||||
Both affected browser cases passed independently. Stop/reset now allows a bounded
|
||||
30-second cold startup; its failure trace showed cancellation during preparation
|
||||
when the old five-second assertion expired, before the fixture began streaming.
|
||||
- The baseline image published successfully, but the deployment check rejected the
|
||||
branch with `fleet_campaign_staging_requires_master` (Cloud run `41092962684`).
|
||||
Current Cloud policy uses `test.paperclip.app` for branch experiments. The local
|
||||
Cloud checkout's older runbook missed this boundary. Qualification is moving to
|
||||
an owned disposable test tenant; the rejected request made no tenant deployment.
|
||||
- All 53 applicable CI checks passed at `0dc9a42a6f` (two skipped checks).
|
||||
The next review found that complete metadata indexes bypassed the unchanged
|
||||
linked-local manifest shortcut. Whole-package identity mappings now retain that
|
||||
shortcut; subsets and remapped paths still use their projected inventory.
|
||||
- A new concurrency regression reproduced a content save overwriting an already
|
||||
acknowledged metadata edit. Publication now checks the metadata fields it will
|
||||
replace as well as the version head, and returns 409 when they changed during
|
||||
preparation. The managed-content and catalog suites passed after this fix.
|
||||
- Local package/project checks hit timing limits while an older full-suite worker
|
||||
remained active for over 80 minutes. That task-owned run was stopped; it is not
|
||||
recorded as a full-suite pass. All four isolated package cases then passed,
|
||||
including the two previous timeout failures and the linked-local regression.
|
||||
Final project-access/process qualification is running sequentially. Server
|
||||
typecheck passed with both final fixes.
|
||||
- Correct disposable branch-test tenant:
|
||||
https://ephemeral-skills-qa-oct-30.test.paperclip.app
|
||||
Stack `stack-ephemeral-skills-qa-oct-30` is pinned user-managed. Baseline A
|
||||
`6518b323528b2b595c5949c3ed2c57a8d2438cb6` is confirmed serving from image
|
||||
`ghcr.io/paperclipai/paperclip:sha-6518b323528b2b595c5949c3ed2c57a8d2438cb6-cloud`.
|
||||
Deploy request `19c33461-d232-453a-bdd1-ba357459be48`, campaign
|
||||
`fleet-campaign-1793366873548`, Cloud run `41094804453`: one target succeeded.
|
||||
The user approved saving the same OpenAI key to this test tenant; its remote
|
||||
Codex environment verification succeeded on a Paperclip Computer.
|
||||
- Studio created unassigned managed skill `3ade7878-8aaf-47c7-aebd-7da23a8afb5d`
|
||||
(Ephemeral Skills Proof), with instructions, `references/value.txt`, and
|
||||
`scripts/prove.sh`. Remote agent `300911d4-590d-4a26-b1c0-c80db14fa072` is
|
||||
preparing the executable flag through the ordinary API. Fresh-home replacement,
|
||||
delivered-byte verification and compatible rollback remain pending.
|
||||
- Final sequential project-access/process qualification passed all 31 cases;
|
||||
the complete-map package checks passed all four isolated cases. The metadata
|
||||
and linked-local fixes were pushed as `ceab192b1774fcb5be17db57de5579d81007b9c1`.
|
||||
- Remote preparation task EPH-1 saved revision 6, version
|
||||
`1abec28d-dd4a-4763-acd4-5a67af874911`, with the script executable. All three
|
||||
reported file digests match hashes independently computed from the Studio
|
||||
inputs. Company: `16cfa89e-f159-5040-927e-aca46ee87c2f`.
|
||||
- Baseline Studio test `81951c91-ec59-4eae-b5c5-c0083119f6ae` failed before
|
||||
execution (`b326a961-c1b8-43ad-b38b-7f6424939ee3`): its route constructed
|
||||
heartbeat without the existing plugin worker manager. This is a route wiring
|
||||
failure, not missing skill content or missing image dependencies. The fix passes
|
||||
the app's existing manager through the Studio route to execution, matching other
|
||||
task routes. No Cloud composition/admission policy changes are required.
|
||||
The first route-suite attempt hit its 30-second module-load setup timeout before
|
||||
any test ran; a bounded 120-second setup-budget retry is running.
|
||||
- The Studio route regression suite passed all 64 cases on retry, and server
|
||||
typecheck passed. The managed sandbox manager is reused from app construction;
|
||||
no provider behavior, permissions or lifecycle ownership changed.
|
||||
- Baseline remote task EPH-3 passed on run
|
||||
`07a711a9-a7d7-45e3-8c00-f64f71d2a9cc`: the delivered v6 script ran directly
|
||||
with mode `555`, printed `skill-script-A: durable-skill-payload-A-20261030`,
|
||||
and all three file digests matched independently calculated input digests.
|
||||
Its saved task document records the execution-local installation path.
|
||||
- Imported repository skill `581b718a-3681-48c4-96d5-87d12b694550` from
|
||||
`paperclipai/paperclip` commit `dff63551fe07934a82a0942e502adba3fcbb08ca`.
|
||||
The existing import filter admitted 12 files and excluded the API reference.
|
||||
A later explicit source refresh hit the repository size limit and retained
|
||||
the installed revision. That refresh is not counted as a successful update.
|
||||
- Test-only env campaign `fleet-campaign-1793366873581` succeeded at
|
||||
`2026-10-30T17:38:00.006Z`, changing only `PAPERCLIP_HOME` to
|
||||
`/tmp/ephemeral-skills-a` on `stack-ephemeral-skills-qa-oct-30`.
|
||||
Audit evidence reports one target, one key, zero removed keys, and unchanged
|
||||
Computer images. Studio reopened v6 with its supporting files afterward.
|
||||
Unassigned fork `6381a0a0-582b-4d26-b858-4e56b606e07c` was created through
|
||||
Studio and saved as v2 with `unassigned-payload-A-20261030` in its reference.
|
||||
- Review of `35b6a12fe4` identified a forced catalog reinstall conflicting with
|
||||
its own audit metadata write. A real Postgres regression reproduced the 409.
|
||||
Candidate auditing is now read-only; successful publication commits the new
|
||||
audit metadata, while unchanged/rejected operations retain audit reporting.
|
||||
Regression checks cover forced reinstall, a new slug, and a competing metadata
|
||||
writer. The combined catalog/managed run passed 29 cases and hit one unrelated
|
||||
15-second asset-test timeout; all four focused catalog cases passed on an
|
||||
isolated rerun. Server typecheck passed.
|
||||
- Latest browser CI exposed another five-second startup assertion in the
|
||||
feature-disable journey. Its trace showed an active adapter invocation before
|
||||
the fixture's first message. The assertion now uses the existing 30-second
|
||||
cold-start budget; the exact browser journey passed locally in 12.5 seconds.
|
||||
No feature-disable behavior or fixture completion assertions changed.
|
||||
|
||||
- Latest code review of `07fffa749511a39b05b2dbc43adcce842195398a` is 5/5,
|
||||
with zero unresolved review threads. Hosted candidate build is run
|
||||
`41101360597`; baseline A remains deployed until it completes.
|
||||
- Provider console independently confirmed external Neon Postgres and S3 on A,
|
||||
with `PAPERCLIP_HOME=/tmp/ephemeral-skills-a`, deployment
|
||||
`5fc05d1a-2451-465c-8a15-16b18d1e0d3d`, replica
|
||||
`f7393d02-49b6-40b9-ae94-db9181300bf4`. A temporary marker was written to
|
||||
that home so a later container can prove the predecessor's local state is absent.
|
||||
- Imported the smaller `vercel-labs/agent-skills` repository at exact commit
|
||||
`93f5a2dee1a270015473e19d24a758a012fa058b`: skill
|
||||
`3e9f2b84-2d15-49f9-a5c0-8596f4c6e313`, source
|
||||
`0c03e633-d22e-4a63-b5a5-843823f2eb7b`, 75 admitted files.
|
||||
Early pin attempts were rejected by the existing Beta skills gate. The late
|
||||
error toast was confirmed; read-only DB inspection showed no saved pin.
|
||||
- Beta skills is a tenant preference, so fleet feature override correctly
|
||||
rejected it as non-managed. Test-only env campaign
|
||||
`fleet-campaign-1793366873607` exposed only this preference, preserving the
|
||||
complete existing hidden-settings list and temporary A home. It succeeded at
|
||||
`2026-10-30T18:04:20.150Z`: one target, two keys, zero removed keys, unchanged
|
||||
Computer images. The tenant's normal Experimental UI then saved Beta skills
|
||||
enabled. No fleet default, identity, permission, or volume policy changed.
|
||||
- The preference campaign replaced A's container: deployment
|
||||
`9ba9202e-7f47-4edd-b501-aa807760b132`, replica
|
||||
`d2131533-f4d2-4173-b984-ca46beaef61c`. Provider console observed the
|
||||
predecessor marker absent, then wrote a new A2 marker for the next replacement.
|
||||
- Repository assignment saved through the library UI as historical version
|
||||
`918e2066-b241-4cdc-934a-db896138240b` (revision 1, `GitHub 93f5a2de`).
|
||||
Explicit source refresh to main published current revision 2
|
||||
`fa3bb9ac-fcd9-443b-970c-f62590f881dc` (`GitHub 1a2c79d4`); automatic
|
||||
updates remain paused for this fixture.
|
||||
- Remote task EPH-4 (`e561a058-3e2d-4f90-9899-a69c6539ed42`), run
|
||||
`9917cfa3-caed-400a-b1a0-58183e2e2614`, passed after A's temporary state
|
||||
was replaced. Managed v6 hashes/output/mode matched EPH-3. The repository
|
||||
wrapper delivered revision 1 while revision 2 was current. Independently read
|
||||
exact-commit upstream contents matched the delivered instruction digest
|
||||
`50b55178a2da8ee931850193596601fa0517cd800e171366a903769f25bf4dda`
|
||||
and `rules/async-parallel.md` digest
|
||||
`6d2f841896279e976dfcdc1ac89e70771ac188baadfd43c096b5706cb838b961`.
|
||||
The agent used the rule to recommend parallel independent fetches and saved
|
||||
paths, command results and API history in task document `immutable-pin-proof`.
|
||||
- Required CI gates `ci / verify` and `ci / e2e` passed on `07fffa749`.
|
||||
Latest check rollup: 52 success, two skipped, one cancelled advisory review
|
||||
job; Greptile separately completed at 5/5 with no unresolved threads.
|
||||
|
||||
- Candidate `07fffa749` deployed successfully through core-only test request
|
||||
`d4e172e8-a861-48cc-ae9c-e2f26c8ee636`, Cloud run `41106109829`.
|
||||
B is deployment `ed70e789-22c3-4b93-93de-da61d7f30ca4`, replica
|
||||
`16fbb2e8-a7b3-4f32-a483-bc2f5c77a8ee`, with
|
||||
`PAPERCLIP_HOME=/tmp/ephemeral-skills-b`. Local health confirmed the code SHA;
|
||||
provider console confirmed A's home and marker absent. The unassigned fork
|
||||
opened as v2 with zero agents. Studio acknowledged a supporting-file edit to
|
||||
the primary managed skill as v7 (`durable-skill-payload-B-20261030`).
|
||||
- Independent verification on B read 23 saved versions: 21 `remote_storage`
|
||||
results and two `database_release_snapshot` results. No corrupt, missing,
|
||||
local-storage or provider-mismatch results. The next cursor returned zero.
|
||||
- Live Studio test EPH-5, test `9c4f3775-2793-46c6-b09d-e3343e0e4c65`,
|
||||
heartbeat `7fe45977-a061-408b-b7c5-5721a7e9f08b`, passed the repaired plugin
|
||||
wiring but failed native admission: `skill_test` was excluded by Runner's
|
||||
task-mode allowlist and execution-input parser. This failure is retained;
|
||||
the Studio acceptance requirement remains pending a deployed retry.
|
||||
- Follow-up admits and preserves `skill_test` through the existing native
|
||||
selection, execution contract and tool bindings. It does not relabel tests
|
||||
as standard work. Task-bound JWT restrictions remain with their authorization
|
||||
owners; the native surface is restricted as detailed below. No executor refactor or
|
||||
Rust protocol change is needed. Older images that reject this mode cannot
|
||||
continue a new Studio test; rollback qualification settles tests first.
|
||||
- Follow-up local checks: 78 admission/input tests, 109 Runner contract tests,
|
||||
40 assigned-MCP tests, and three real-HTTP skill-test scope regressions passed.
|
||||
Initial scope/MCP attempts encountered sandbox socket restrictions; permitted
|
||||
retries passed. Runner TypeScript/Rust checks and server TypeScript check
|
||||
passed. Maps remain aligned (35 areas, 192 capabilities).
|
||||
|
||||
- B's v7 is `e1f96114-6be5-4878-b9ae-269bac0da215`; independent hash of
|
||||
its supporting file is `c2d9b967aa8ddfad7896804ea1a7ae613b8ff631ff6a084cee7553125bc7fd27`.
|
||||
EPH-6 (`c5377e90-c80c-4f97-8ada-c4eaf205af0a`), run
|
||||
`96537d81-b224-442a-9ec1-993fbd89ff56`, completed successfully and saved
|
||||
`server-b-skill-proof`. Direct script output contained the B payload; executable
|
||||
mode remained 555, other managed hashes were unchanged, and repository v1
|
||||
instruction/rule hashes matched the independent exact-commit reference.
|
||||
- C home campaign `fleet-campaign-1793366873685` (target
|
||||
`fleet-campaign-target-1793366873686`) succeeded at
|
||||
`2026-10-30T18:36:03.930Z`, preserving both managed env keys and Computer images.
|
||||
Deployment `462e3327-e49b-4096-b5e2-73f5db058a9f`, replica
|
||||
`01c696c4-89b9-4358-9c2b-108faa4c9d50`, served `07fffa749` with home
|
||||
`/tmp/ephemeral-skills-c`. Console verified A and B directories and B's marker
|
||||
absent. Studio cold-read v7 and the exact acknowledged B payload.
|
||||
- Unassigned fork v2 identity was independently confirmed as
|
||||
`8b008393-f909-424a-9f68-1995231455a7`. It remained at zero assignments on C;
|
||||
its supporting file was then edited through Studio to a C-specific payload.
|
||||
Execution on the candidate with native Studio admission remains pending.
|
||||
- C's remote EPH-7 (`d57f6f66-7072-4fb9-abde-199edf5192ef`), run
|
||||
`c7f89682-ab9b-4f00-940f-88967c6c0264`, completed successfully. The saved
|
||||
`server-c-skill-proof` document (revision `8129375b-f56c-4b80-99b0-637481a31f72`)
|
||||
was independently opened and read. All five hashes matched the B run and
|
||||
independent references. Its new session `7f164893cdc73464e112e2572baed3ddc166bb29485d770c37fbf7449793cdc0`
|
||||
executed the unchanged script with exit 0, mode 0555 and the exact B payload.
|
||||
The managed selected/current version remained v7, and repository selection
|
||||
remained v1 while its current head remained v2.
|
||||
- Review of `8821b040` found that native task creation omitted the admitted
|
||||
skill-test scope. Image build `41108317938` was cancelled before deployment.
|
||||
Native authorization now carries the saved scope, denies company/peer tools,
|
||||
task creation and external tools, and checks the scope before mutation receipt
|
||||
replay. Task context contains only the harness task. Real database regressions
|
||||
exercise both fresh tests and persisted tests after their task mode changes.
|
||||
- Native scope checks passed: three new real-database cases plus four REST
|
||||
scope/image-access cases. The existing native tool-authority suite passed all
|
||||
37 tests. Server typecheck and map checks passed. The initial new-test attempts
|
||||
corrected a fixture tool name and matched the existing privacy-preserving 404
|
||||
for unrelated tasks; own-task reads returned 200.
|
||||
- `350f1b377c459420a1c1474723501a4bccc6d7fc` received Greptile 5/5.
|
||||
The native-scope review thread is resolved. Test deployment request
|
||||
`d2480188-1fc9-4a22-a32b-16af7f439ca4` prepared in Cloud run `41110650568`;
|
||||
candidate image build is `41110729544`.
|
||||
- The fork's C save is version `ef34d9e5-2533-497e-8411-a797117afb4a`.
|
||||
C's durable `tool.execution.completed` event at sequence 322 was inspected
|
||||
independently of the report: the real shell command completed with exit 0,
|
||||
mode 555, all five expected hashes, and `skill-script-A: durable-skill-payload-B-20261030`.
|
||||
A disposable `qualification-marker-c` was written in C's temporary home for
|
||||
the next container replacement check.
|
||||
- Full CI at `350f1b377c` passed 50 checks but found two old `mode_denied`
|
||||
message expectations in case/reassignment tests. Both operations are rejected
|
||||
earlier by the native scope guard with 403. Updated the assertions and checked
|
||||
that denial never stops another task. The case-gate regression and all 26
|
||||
reassignment tests passed locally. Reassignment now uses the existing optional
|
||||
external-Postgres helper; initial attempts hit exhausted embedded-Postgres
|
||||
resources and a startup timeout, retained as failures rather than passes.
|
||||
These follow-ups change only tests and evidence, not candidate runtime code.
|
||||
- Image `350f1b377c` deployed successfully in Cloud run `41115408877`, confirmed
|
||||
by local health on deployment `d70457ab-a812-45d5-8a38-657f6bfc02de`, replica
|
||||
`9f58192d-9207-4065-86e4-48887c6a8b3e`. A/B homes and C's marker were absent.
|
||||
- Studio test `ef0aa327-f719-44a3-bea2-1d051f2a793a`, task EPH-8
|
||||
(`860476c5-d4bf-4619-9206-8aa18884f545`), executed successfully but delivered
|
||||
the agent's normally assigned primary skill instead of the requested unassigned
|
||||
fork. Its report explicitly records the mismatch. This is a failed qualification,
|
||||
regardless of the task's Done status. The fix passes the durable Studio pin into
|
||||
execution preparation, replacing ordinary assignments while preserving recovery
|
||||
pins and current access checks. Hosted retry remains required.
|
||||
- The same EPH-8 heartbeat (`94eeb6ff-7d9e-49b7-bee2-0ef5f41ff8a4`) succeeded
|
||||
and marked its task Done, but the Studio row remained queued with an empty
|
||||
output snapshot. Native completion bypassed the REST-only success hook. Native
|
||||
status publication now calls the existing skills owner within its transaction;
|
||||
status, output and activity commit together. Four real-Postgres regressions pass
|
||||
for completion/cancellation, replay from another client, transaction rollback,
|
||||
blocked work and superseded tests. Completion uses a conditional terminal update.
|
||||
- The two selection regressions pass, including assembled dispatch of an unassigned
|
||||
historical executable file. Server typecheck and map checks pass. A broad local
|
||||
execution suite attempt hit timeout cascades (20 passed, 9 failed); this is not
|
||||
counted as success. Isolated new tests passed; the full affected suite is rerunning.
|
||||
- Compatible rollback request `2363f01e-2e6b-4b72-9234-3fd0c5f22e88` deployed
|
||||
`6518b323528b2b595c5949c3ed2c57a8d2438cb6` through Cloud run `41116892516`.
|
||||
Deployment `5034b027-d9e2-4bd6-8efe-526d3d065d7d`, replica
|
||||
`9ff45218-e553-4122-b411-e7052c521917`, was confirmed through local health.
|
||||
The predecessor's `qualification-marker-d` was absent. Studio reopened the
|
||||
unassigned fork's v3 supporting file as `unassigned-payload-C-20261030`.
|
||||
- Rollback task EPH-9 (`d5d03621-9616-4713-88ad-0ea54e4c3d53`), run
|
||||
`7ae0b61d-0e9f-4761-914c-9dc399c0ebc8`, completed on a real remote Computer.
|
||||
Its `rollback-skill-proof` document matches all six independently known hashes,
|
||||
managed v7 and repository v1 IDs. It executed the unchanged script with exit 0,
|
||||
mode 0555 and the acknowledged B payload. Durable command event sequence 293
|
||||
was independently inspected through the tenant console and confirms those
|
||||
bytes, hashes and actual execution. The repository rule also produced the useful
|
||||
independent-requests `Promise.all()` recommendation.
|
||||
- The complete affected suites passed all 33 tests in 65.65 seconds. The Studio
|
||||
fix is `417270ab18`; current master `3b84c89885` merged without conflicts as
|
||||
`5afd8c3b056f6c0fceeb121c0f398beb72317e2b`. Post-merge server typecheck,
|
||||
all 33 affected tests, map checks and UI token gates passed again.
|
||||
- The independent OS-process replacement matrix passed again on `5afd8c3b05`
|
||||
(two scenarios, 54.24 seconds). A/B/C version IDs were
|
||||
`56c4b315-082f-4caa-8788-02e10b45d3a4`,
|
||||
`ed03e467-3a81-4256-849e-53ece688e5aa`, and
|
||||
`9ff5d4ce-43e7-4b2e-883d-8b010fc5c42b`. Cold read was 522.16 ms,
|
||||
two downloads/899 bytes; warm preparation was 143.72 ms with zero downloads.
|
||||
Reported RSS was 881,639,424 bytes and disposable home content 820 bytes.
|
||||
These are local fixture measurements, not hosted latency claims.
|
||||
- Candidate request `9a03542e-ea41-4ea1-94c8-7dd1ae38c621` prepares in Cloud
|
||||
run `41118819981` and builds in Core run `41118878753`. The tenant remains on
|
||||
the verified rollback image until this candidate is deployed.
|
||||
- Review at `5afd8c3b05` found that existing partial repository versions could
|
||||
bypass conversion and be reported as eligible. Installation conversion,
|
||||
eligibility and independent verification now compare the current saved inventory
|
||||
with the installed inventory. Missing files block readiness; conversion can use
|
||||
only complete saved/local content or the exact pinned remote source. Both JSONB
|
||||
and packaged legacy regressions pass, including upstream failure with an unchanged
|
||||
head, exact-commit repair and unchanged complete installations. The entire managed
|
||||
content suite passed 16 tests. Build `41118878753` was cancelled before deployment
|
||||
so hosted acceptance will use a candidate containing this correction.
|
||||
- Full workspace typecheck passed after allowing the migration launcher's local IPC
|
||||
socket. The initial sandbox attempt failed with `listen EPERM` before that check
|
||||
could run. The workspace build is running separately.
|
||||
- The workspace build passed on `9200e3fcb4` after correcting a missing-version
|
||||
null check caught by its first attempt. Greptile re-reviewed that commit at
|
||||
5/5 with zero unresolved findings. Image request
|
||||
`0b5a10c1-dccf-4c01-9db7-548ea07897a0` prepares in Cloud run `41120340127`
|
||||
and builds in Core run `41120440752`.
|
||||
- Earlier failed Studio fixture `ef0aa327-f719-44a3-bea2-1d051f2a793a` was
|
||||
cancelled through Studio to settle its stale queued pin. Its mismatch report and
|
||||
draft output remain visible. It is still recorded as a failed qualification.
|
||||
- CI run `41120305357` found the same obsolete restart-scope fixture in Runner
|
||||
static checks and general server shard 5. The helper always returned no saved
|
||||
skill; preparation now correctly rejects that state. It now reads a real durable
|
||||
test/version row, asserts missing-version rejection first, and still verifies
|
||||
restricted REST scope after task-mode edits. Both focused HTTP cases and server
|
||||
typecheck pass. The complete 52-case HTTP suite passed in 63.78 seconds. This follow-up
|
||||
changes only the test fixture and evidence, leaving image runtime code unchanged.
|
||||
- Master advanced to `76fde891cc` during image publication. Merge `61f5664337`
|
||||
preserves both the skill-recovery and native-usage imports; no skills behavior
|
||||
changed in the merge. Full workspace typecheck and build passed. A combined
|
||||
local run passed 42 cases, failed three execution timeouts plus a tracer setup
|
||||
assertion, and skipped 52 HTTP cases after a setup timeout. Isolated retries
|
||||
are recorded below rather than treating the combined run as passing.
|
||||
- Review found a delayed conflict-reload response could overwrite text typed after
|
||||
discard confirmation. The response now applies only while the same skill, file
|
||||
and draft remain current. All 17 Studio component cases passed, including a
|
||||
delayed response while the user continues typing. This client-only follow-up
|
||||
is separate from the `9200e3fcb4` server image used for remote delivery proof.
|
||||
- Full CI run `41124309799` passed at `7ec495de77`; Greptile review 14 is 5/5
|
||||
with zero unresolved findings. The isolated local execution retry stopped
|
||||
producing progress and was interrupted; no success is claimed for that attempt.
|
||||
The full CI suites cover the integrated execution and HTTP cases.
|
||||
- Candidate `9200e3fcb45082ad73fbb75863d56eb2e6ce526c` deployed successfully
|
||||
through Cloud run `41124147876`, ready at `2026-10-30T20:36:46Z`.
|
||||
Deployment `3daed721-eefe-4947-afe3-d8fd1db6aa2c`, replica
|
||||
`29375d2e-50ea-467e-9492-a2d4bc7e628e`, retained the temporary C home setting.
|
||||
Console inspection confirmed A/B homes and the rollback marker absent.
|
||||
- The Studio retry created test `7c55d51d-c2c9-426e-a2fa-3606c486d41a`, task
|
||||
`e8405564-1d2e-4013-8aeb-145de0a76fbd`, and remote run
|
||||
`c6ebc90d-1411-404b-ad6d-789d960a7a48`. It delivered only the selected
|
||||
unassigned fork `ef34d9e5-2533-497e-8411-a797117afb4a` (v3), with
|
||||
`unassigned-payload-C-20261030\n`, stdout
|
||||
`skill-script-A: unassigned-payload-C-20261030\n`, exit 0 and mode 0555.
|
||||
Studio visibly reached `succeeded` and displayed the durable output snapshot.
|
||||
The fork still has zero assignments. SHA-256 values match the expected fixture:
|
||||
`SKILL.md` = `a97ee4d33cac28f9affcc53e48b3de00f72a9a8b70a0b3a53bb81569b1111ae6`,
|
||||
reference = `0d5a7396baaf395ef24e9136b2f9892e9878d863b42ff3195d376f61248d1f5f`,
|
||||
script = `8830c87e4e56e76dbe70bfac5fa4260d1e33d62eaa3289d1f8887a3fa9521da0`.
|
||||
- Independent database inspection confirmed task EPH-10 is done, its native run
|
||||
succeeded, and its exact durable selection contains only the unassigned fork v3.
|
||||
The Studio row is `succeeded` with a 1,915-character output snapshot. Runner
|
||||
command event sequence 204 independently confirms all three hashes, actual
|
||||
script stdout, exit 0 and mode 0555; these are tool results, not only the agent's
|
||||
report. The Studio success screenshot is retained with the handoff.
|
||||
- Final eligibility inspected 14 installations, all `version_backed`.
|
||||
Independent verification inspected 25 versions: 23 `remote_storage`, two
|
||||
`database_release_snapshot`, zero blockers, and zero rows at the next cursor.
|
||||
The first standalone command incorrectly reported packages unavailable because
|
||||
it had not loaded Cloud's persisted runtime configuration. The same services
|
||||
passed after loading that snapshot. The CLI now loads it read-only and fails
|
||||
explicitly if absent, without seeding configuration. A real child-process test
|
||||
covers missing configuration, no write on inspection, eligibility, and object
|
||||
verification; it passed. An initial diagnostic wrapper also used a nonexistent
|
||||
compiled DB entry point; correcting it to the image's source entry point allowed
|
||||
the bounded verification to run. Neither diagnostic failure changed skill data.
|
||||
- The CLI child-process regression passed in 46.52 seconds, and server typecheck
|
||||
passed after the bootstrap correction. The CLI reads existing configuration
|
||||
without creating or changing it; no new maintenance process or listener exists.
|
||||
@@ -0,0 +1,173 @@
|
||||
# Skills on ephemeral web servers
|
||||
|
||||
The skills guarantee is replacement of A by B, and then C, with empty web-server
|
||||
homes and the same database, object storage, secrets and supported application
|
||||
artifacts. Disk remains useful for scratch archives, verified caches and transport
|
||||
staging. It does not own acknowledged managed edits or installed version selection.
|
||||
This guarantee does not qualify instructions, workspaces, controller state, run
|
||||
logs, traffic switching or readiness/draining for volume removal.
|
||||
|
||||
## Ownership and publication
|
||||
|
||||
`managed` is Paperclip ownership. Its locator is null; editability does not depend
|
||||
on a directory's position beneath a managed root. Existing policies normalize it
|
||||
to `workspace`, the policy category previously used by managed local skills.
|
||||
Repository provenance and tracking remain separate from installed content. Forks
|
||||
and disconnected editable copies retain source access and cannot publish restricted
|
||||
content through a public source category.
|
||||
|
||||
`managed-skill-content.ts` reads immutable version inventories, prepares candidates,
|
||||
and publishes them against a captured head. Package upload and verification happen
|
||||
before the final database transaction. That transaction rechecks identity/access,
|
||||
locks names in sorted order, locks the skill, verifies the base, and publishes the
|
||||
version, head, projections and applicable mutation audit/receipt. Publication races
|
||||
return `409`; clients must reconcile instead of automatically rebasing. Complete
|
||||
inline versions remain the compatibility fallback when external writes are disabled;
|
||||
they never depend on an installed directory. Normal cloud qualification uses remote
|
||||
object storage.
|
||||
|
||||
The initial create response, including its original version, can be replayed after
|
||||
a lost response and subsequent edits. Its durable API receipt retains the response
|
||||
projection without Markdown; the immutable version supplies the body. Receipts
|
||||
remain scoped to company, actor and operation context. A deleted skill's receipt
|
||||
fails explicitly rather than creating another identity.
|
||||
|
||||
`skill-execution-content.ts` owns temporary materialization. Heartbeat preparation
|
||||
selects authorized immutable versions, saves the selection (including an empty
|
||||
selection), and only then materializes admitted entries while retaining the existing
|
||||
retention lock. A renamed skill is recovered through the version's stable skill ID.
|
||||
Native recovery resolves the version, reconstructs its v1 projection and requires
|
||||
the admitted digest, manifest digest, file count and byte count to match. Adjacent
|
||||
compatible releases must preserve that projection contract.
|
||||
|
||||
Studio tests deliver the selected saved version through the same native Runner
|
||||
path, even without a permanent agent assignment. Their `skill_test` mode remains
|
||||
explicit in the execution input. The durable test row replaces ordinary agent
|
||||
assignments with its exact version, independently of the Beta skills preference;
|
||||
required environment skills remain subject to their existing policy. A shadowed
|
||||
or inaccessible test skill fails preparation. Preconfigured Runner homes cannot
|
||||
receive this managed delivery, so Studio requires an isolated home. Task-bound
|
||||
credentials and native authorization
|
||||
retain the admitted scope through restart and task-mode edits. Native tools expose
|
||||
only the harness task and admitted skills; company browsing, task creation,
|
||||
connectors and assigned MCP tools are unavailable. A rollback image must understand
|
||||
that mode to continue an active Studio test. Settle tests before rolling back to an
|
||||
earlier image that rejects it.
|
||||
|
||||
Native task completion publishes the Studio result and output snapshot in the
|
||||
same transaction as its status decision. Replaying a committed decision cannot
|
||||
recapture later document edits or duplicate completion activity. A successful
|
||||
provider turn alone does not complete a test whose task remains unfinished.
|
||||
|
||||
Bundled release snapshots remain immutable. Reconciliation preserves an installed
|
||||
head; an older process must never promote its shipped bytes over another installed
|
||||
version. The shipped release history remains independently selectable. Linked-local
|
||||
skills retain mutable source behavior and are explicitly excluded from cloud readiness.
|
||||
|
||||
## One-time conversion
|
||||
|
||||
First deploy compatible readers and shared/API types. Preserve the old volume and
|
||||
keep legacy writers until the final supported contents can be captured. Automatic
|
||||
JSONB package migration is separate from installation conversion; passing one does
|
||||
not prove the other is finished.
|
||||
|
||||
Run the existing bounded CLI with the target's explicit database and storage config:
|
||||
|
||||
```sh
|
||||
pnpm --filter @paperclipai/server exec tsx scripts/migrate-skill-packages.ts --phase=eligibility --company=<uuid> --limit=10
|
||||
pnpm --filter @paperclipai/server exec tsx scripts/migrate-skill-packages.ts --phase=installations --company=<uuid> --limit=10
|
||||
```
|
||||
|
||||
These commands return a cursor. Continue each phase with `--after=<uuid>` until an
|
||||
empty batch. Eligibility is a metadata-only report, not a storage verification claim.
|
||||
Installation preview inspects candidate legacy contents without publishing them.
|
||||
For remote legacy imports it can acquire their exact pinned source; it must never
|
||||
use the latest branch as a replacement for missing installed content.
|
||||
|
||||
1. Inventory all companies and source kinds. Identify missing versions, incomplete
|
||||
inventory, local storage receipts, catalog reset snapshots and unresolved runs.
|
||||
2. Backfill legacy package/version bodies with the existing `snapshots` and
|
||||
`versions` phases. The latter also fills missing version metadata indexes so
|
||||
subsequent library/history reads need no object downloads. Keep original bytes
|
||||
until independent verification succeeds.
|
||||
3. Stop admission and skill/source writers; retire every filesystem-authoritative
|
||||
process. The `--writers-stopped` flag attests this operator action; it does not
|
||||
stop the application itself.
|
||||
4. Apply final installation conversion on the host with the legacy files:
|
||||
|
||||
```sh
|
||||
pnpm --filter @paperclipai/server exec tsx scripts/migrate-skill-packages.ts --phase=installations --company=<uuid> --limit=10 --apply --writers-stopped
|
||||
```
|
||||
|
||||
5. Sweep `eligibility` and `verification`, including all historical versions. The
|
||||
latter verifies object bytes independently of caches. Follow all cursors; a
|
||||
successful first batch is not a complete readiness report.
|
||||
6. Start a compatible server with a fresh home and test list, file read, authoring,
|
||||
history and exact selected execution before reopening normal admission.
|
||||
|
||||
Managed conversion preserves skill IDs, keys, history, assignments, pins and access
|
||||
provenance. Identical complete snapshots reuse their version IDs. Catalog conversion
|
||||
preserves the original reset version as well as installed content. A missing legacy
|
||||
directory can use a complete verified saved version. A partial Markdown-only rescue,
|
||||
unknown revision, unsafe source tree or active legacy selection without exact version
|
||||
identity is a blocker. Settle or snapshot such runs while A is still available; do
|
||||
not cancel them simply to pass preflight.
|
||||
|
||||
Report statuses distinguish linked-local sources, legacy managed/catalog records,
|
||||
missing current versions, unknown active-run selections, missing/corrupt packages,
|
||||
local storage and provider mismatch. Expired unused Git history keeps its existing
|
||||
30-day/exact-commit policy. Current, pinned, authored and recovering versions need
|
||||
independent durable content. `local_storage` is supported self-hosted durability;
|
||||
it does not satisfy remote empty-disk recovery.
|
||||
|
||||
## Storage and rollback
|
||||
|
||||
Cloud readiness requires external Postgres and remote object storage. Migrate and
|
||||
verify existing local-disk objects before changing provider/bucket configuration;
|
||||
changing configuration alone does not copy receipts or objects. Keep the old provider
|
||||
available until a provider migration has copied and independently verified every
|
||||
referenced object and atomically updated its storage receipt. This command does not
|
||||
perform provider migration: `local_storage` and `provider_mismatch` are blocking
|
||||
results for cloud qualification, not instructions to switch configuration and retry.
|
||||
A directory of extracted caches is never a durable object backend.
|
||||
|
||||
Conversion establishes the rollback floor. Afterward only compatible version-reading
|
||||
binaries may overlap or be rolled back against the same remote state. Reattaching an
|
||||
old volume does not roll back committed content. Filesystem-authoritative binaries
|
||||
require an explicit reverse migration and are unsupported rollback targets.
|
||||
A routine compatible A → B upgrade needs no skills conversion or filesystem copy.
|
||||
|
||||
A current version ID alone does not establish conversion completeness. Eligibility
|
||||
and independent verification compare its file inventory with the installed record
|
||||
and report `incomplete_current_version` when supporting files are missing. Installation
|
||||
conversion can reacquire a complete exact pinned source; unavailable or unpinned
|
||||
sources remain blockers. Historical versions are not compared with newer installed
|
||||
inventories, since later revisions may legitimately add files.
|
||||
|
||||
## Qualification
|
||||
|
||||
The focused service suite covers publication rollback/conflict, supporting and binary
|
||||
files, executable modes, restore/fork/rename, active-run deletion protection and legacy
|
||||
conversion. The opt-in process suite starts independent Node servers with one database
|
||||
connection each, exercises real HTTP routes and object storage, removes predecessor
|
||||
homes and executes a delivered harmless script. It also injects a lost response, failed
|
||||
upload and process death during upload. It is a skills-router qualification, not a
|
||||
full hosted Runner or whole-application deployment claim.
|
||||
|
||||
Use owned disposable Postgres and S3-compatible fixtures. The optional admin URL
|
||||
creates a random database per test suite and never migrates the database named in
|
||||
that URL. The S3 test creates and removes its own random bucket. Supply test-only AWS
|
||||
credentials through the environment:
|
||||
|
||||
```sh
|
||||
PAPERCLIP_TEST_POSTGRES_ADMIN_URL=<disposable-postgres-url> \
|
||||
PAPERCLIP_TEST_S3_ENDPOINT=<disposable-s3-endpoint> \
|
||||
pnpm exec vitest run server/src/__tests__/ephemeral-skills-process.test.ts
|
||||
```
|
||||
|
||||
Record revision, fixture image digests, version IDs, cache/object reads, cold/warm
|
||||
timings and useful output. These local timings do not establish hosted latency.
|
||||
Separately qualify one disposable staging tenant and a real remote Runner, including
|
||||
an explicit repository import, historical pin, fresh-home replacements, compatible
|
||||
rollback and recovery without predecessor paths. Publish the observed evidence with
|
||||
the PR; a passing local suite is not that staging evidence.
|
||||
@@ -7,7 +7,26 @@ The original repository tree, wrappers, binary bytes and executable flags retain
|
||||
their existing behavior. New Git packages also retain an immutable restore recipe;
|
||||
locally authored/edited packages and unproven legacy packages keep a durable copy.
|
||||
|
||||
## Automatic upgrade
|
||||
## Installed content authority
|
||||
|
||||
Paperclip-owned skills use `sourceType: managed`, `sourceLocator: null`, and an
|
||||
immutable `currentVersionId`. Creation, edits, deletion of files, forks and restores
|
||||
prepare verified packages before a short transaction publishes the version, head,
|
||||
metadata and audit. A competing head returns `409`; it never overwrites another
|
||||
writer's files. Acknowledged saves survive cache loss. Studio submits the version it
|
||||
read and preserves unsaved text on a conflict.
|
||||
|
||||
Repository and catalog installations also read committed versions. Runtime selection
|
||||
persists version pins before delivery materializes files. Recovery uses the pinned
|
||||
version and checks its reconstructed v1 asset digest; a previous server's `rootPath`
|
||||
is not proof of availability. Active or recovering run pins block whole-skill deletion,
|
||||
even after the agent assignment is detached. Explicit linked-local sources retain
|
||||
their local filesystem behavior and are outside this replacement guarantee.
|
||||
|
||||
See [ephemeral web-server operation](skill-ephemeral-web-servers.md) for the one-time
|
||||
installation conversion, rollback boundary and qualification procedure.
|
||||
|
||||
## Automatic package upgrade
|
||||
|
||||
No data-migration command is required. The normal schema upgrade applies migration
|
||||
0415 (`0415_zippy_zemo.sql`). External writes and automatic conversion are enabled by default. Startup
|
||||
@@ -31,20 +50,30 @@ reader is the rollback floor; an older binary needs rehydrated database contents
|
||||
Use durable, backed-up local storage or S3-compatible storage for authored packages.
|
||||
The extracted cache is not that storage backend.
|
||||
|
||||
Deleting an editable file or folder keeps a temporary copy outside the skill until
|
||||
the transaction commits. Upload or database failures restore the original subtree,
|
||||
including binary files, permissions, empty folders and files omitted from inventory.
|
||||
Successful deletions remove the temporary copy; historical versions retain their
|
||||
existing package bytes. If the commit reply is lost, recovery checks the saved
|
||||
version under the mutation lock before restoring. A committed deletion stays
|
||||
deleted. If the database is unavailable or the skill has since changed, recovery
|
||||
preserves the backup and logs its location instead of overwriting newer work.
|
||||
Managed file and folder deletion publishes a new inventory. It requires no local
|
||||
rollback copy. Unused uploads follow the existing orphan/deletion machinery; a
|
||||
post-commit cache or notification failure cannot undo a committed save. Only the
|
||||
explicit linked-local compatibility adapter retains filesystem rollback handling.
|
||||
|
||||
Create idempotency receipts retain the original response projection and immutable
|
||||
version identity in `company_skill_mutation_receipts`; file-save receipts keep their
|
||||
existing activity receipt shape. Retries reauthorize access. Deleted identities do
|
||||
not transfer their receipts to a skill recreated with the same name. Skill bodies
|
||||
remain in packages/versions rather than activity logs.
|
||||
|
||||
The optional `server/scripts/migrate-skill-packages.ts` command remains available for
|
||||
diagnostics and controlled batches. It defaults to dry run, supports
|
||||
`--phase=snapshots|versions|orphans|deletions`, `--company=<uuid>`, `--limit=1..50`,
|
||||
`--phase=snapshots|versions|orphans|deletions|installations|eligibility|verification`, `--company=<uuid>`, `--limit=1..50`,
|
||||
`--after=<uuid>`, `--apply` and `--clear-legacy`. It is not part of normal installation
|
||||
or upgrade. Never point it at another instance's database/storage configuration.
|
||||
or compatible routine upgrade. The installations phase is the one-time legacy
|
||||
conversion boundary described in the linked runbook. Never point it at another instance's database/storage configuration.
|
||||
|
||||
New package-backed versions retain their complete path/kind/encoding index in
|
||||
`package_file_map`, including identity mappings. Library and version listing read
|
||||
this metadata without downloading manifests or archives. The bounded `versions`
|
||||
phase also backfills older null indexes from verified manifests without changing
|
||||
version IDs or content; include that phase in legacy conversion. Old null indexes
|
||||
remain readable during conversion, with a cold manifest read when needed.
|
||||
|
||||
## Acquisition and retention
|
||||
|
||||
@@ -83,8 +112,11 @@ Package/version publication and deletion use transaction-aware work notification
|
||||
local asset use signals its filesystem worker. Both reuse the delivery coordinator,
|
||||
restore deadlines on startup, pause in drain/standby, and stop on shutdown. With no
|
||||
pending conversion, retry, or eligible cache deadline they perform no recurring work.
|
||||
The supported live writer is the owning server; independent SQL writers/other servers
|
||||
need restart reconstruction or an explicit wake. No permanent DB listener is added.
|
||||
Compatible servers resolve the durable head on each content operation and use
|
||||
transactional publication checks. Content correctness needs no process-local
|
||||
invalidation. Maintenance wake delivery across instances remains owned by the
|
||||
delivery coordinator; startup reconstructs pending deadlines. No permanent
|
||||
skills-specific DB listener is added.
|
||||
Conversion retains authoritative legacy bytes until verification succeeds. Conversion
|
||||
retries and cache/deletion dates are optional maintenance eligibility; they may wait
|
||||
until the next ingress wake, including with package storage disabled. They do not
|
||||
|
||||
Reference in new issue
Block a user