mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-30 13:20:54 +01:00
## Thinking Path > - Paperclip manages work through tasks, agent runs, dependencies, and human decisions. > - The first-task workflow asks for approval before it creates an execution task. > - File-producing work must run on a child task before onboarding can finish. > - A child blocked by its onboarding source cannot start while the source waits for that child. > - This change rejects that dependency during task creation and later edits, and gives the agent a correction. > - The shipped recipe shows the dependency direction and requires the actual approved inputs in the child instructions. ## Linked Issues or Issue Description **What happened?** After human approval, an onboarding run could create a child with the onboarding source in `blockedByTaskIds`. Creation saved a blocked child with no wake. The parent could then wait for that child. A handoff could also refer to input from the parent conversation without including the input in the child description. **Expected behavior** The approved child can execute before its waiting parent. Invalid first-task dependency input fails before task creation and leaves the same command key available for a corrected call. The child instructions include the required approved input and constraints. **Steps to reproduce** 1. Accept a proposal on a server-created first task. 2. Call native `create_task` with `status: "todo"` and the onboarding source in `blockedByTaskIds`. 3. Observe a blocked child with no scheduled wake. Block the parent on that child to expose the stalled handoff. **Paperclip version or commit** The regression reproduces on `f8484a9f8d1f68e9534fee4f29e00e716dc680f4`. The repair is based on current master. **Deployment mode** Core native and REST task creation. The same server boundary serves self-hosted and hosted instances. Related: #18080 fixed remote delivery of the selected first-task skill. This change handles the later child handoff boundary. ## What Changed - Reject a task blocked by its authenticated first-task source during creation and later dependency edits. Later agent edits also check the locked target's server-owned onboarding parent, protecting a child running under its own execution. Compare UUID identity in PostgreSQL so alternate supported UUID spellings cannot bypass the check. The error explains the correction. - Add a native child/dependency recipe with self-contained approved input guidance. Clarify the general `create_task` input descriptions and update their generated contracts. - Cover native and REST rejection, corrected retry, preserved valid dependencies and replay, and an executable recipe with exact input bytes read from the child's own context. Thread the authenticated run through native dependency edits. Keep blocker corrections independent of a new proposal decision. - Update execution semantics and the existing onboarding map entries. ## Verification - Red on `f8484a9f`: the new native regression received a created blocked child instead of the expected rejection. - Review regressions were red on the original PR head: uppercase, unhyphenated and braced source UUIDs created blocked children; a later child PATCH returned 200 and saved the reversed blocker. - Review follow-up reproduced both native and REST child-own-run bypasses on `75fa75a6`: the native dependency call applied the reverse edge; the child's own PATCH returned 200. The regression uses the actual authenticated child execution and an already checked-out task. - All 95 tests across first-task admission, assets, and the full native tool-authority suite pass. The shipped recipe is validated against the native schemas and exercised through real task/dependency services with disposable PostgreSQL. Rejected PATCH tests preserve existing authorization and attempt-audit behavior and require no requested task-field, relation or wake change. Compatibility controls retain ordinary manual parent blockers, explicit board edits, other blockers and empty-list corrections. - Runner TypeScript build, generated contracts, capability inventory, protocol manifest, and map checks passed. - Server typecheck and all 95 focused tests pass with the child-run follow-up. All latest checks pass on `f24509ae`: 55 successful checks, one neutral review check, four skipped checks, and a successful legacy security status. Both automated reviews are 5/5 on this exact commit. - Prior-head CI failures are preserved: the Runner close fixture had unconfirmed provider drain while suspension succeeded; its exact fake-provider subprocess row passed locally with unchanged sources. The browser outage test lost its title textarea before any outage write. A bounded local control with a fully loaded composer passed every original outage assertion. The prior failure is an editor-readiness race; its exact asynchronous ordering remains unproved. No UI, browser-test, or timeout change is included. Neither failure is counted as a pass or silently discarded. - The first `f24509ae` CI attempt had two interrupted jobs: Typecheck and General server 9/12. Their logs record runner shutdown signals. The server job also records lost runner communication. The same-head failed-job rerun passed both jobs and the required aggregate. It reused the other successful results. No source, test, or timeout change was made for the rerun. The failed attempt remains preserved. Full repository checks pass in CI; the local full repository typecheck, test, and build commands were not repeated. - No external model or provider calls are used by these checks. Real-provider acceptance at this revision remains separate. ## Risks - The new rejection uses the authenticated run and the server-owned onboarding origin. Ordinary tasks, other blockers, empty-list corrections, and already committed creation replay retain their existing behavior. Blocker edits do not reapply the creation approval gate. - Nonempty blocker edits perform two indexed identity reads; the task lookup covers at most the run source and locked structural parent. Other patches and empty-list corrections add no source lookup. The update guard adds no parent row lock behind a child. Existing REST authorization checkout and attempt auditing remain in place before the domain mutation guard. - The explicit input recipe guides the model. Schema and persistence tests do not prove that a future model follows every instruction. - The tool guidance changes the generated semantic catalog identity. The maintained generated files are synchronized in this change. ## Model Used OpenAI `gpt-6.1-sol` through Codex, with `ultra` reasoning effort, repository tools, code generation, and test execution. The context window is not exposed by the runtime. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used and stated the available runtime detail - [x] I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work - [x] I have searched GitHub for duplicate or related PRs and linked them above - [x] I have described the issue in-PR following the bug issue template - [x] I have not referenced internal or instance-local Paperclip issues or links - [x] My branch name describes the change and contains no internal ticket ID - [x] I have run focused tests locally and they pass - [x] I have added or updated tests where applicable - [x] I have updated relevant documentation to reflect my changes - [x] I have considered and documented risks above - [x] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge --------- Co-authored-by: Paperclip <noreply@paperclip.ing>
239 lines
15 KiB
Markdown
239 lines
15 KiB
Markdown
---
|
||
navigation: {"section":"Getting started and access","sectionOrder":10,"order":10}
|
||
---
|
||
|
||
# Onboarding and first work
|
||
|
||
An operator can start an instance, create a company, configure its first agent, and reach a real first task. Instance setup and company onboarding are separate steps.
|
||
|
||
Feature ID: `onboarding`.
|
||
|
||
Implementation: [web wizard](../../ui/src/components/OnboardingWizard.tsx), [CLI setup](../../cli/src/commands/onboard.ts).
|
||
|
||
Agent access: [companion](../agent-access-map/onboarding.md).
|
||
|
||
## Sub-features
|
||
|
||
- `instance`: `onboarding/instance` — choose local instance configuration and start the server.
|
||
- `company`: `onboarding/company` — create a company with its identity and initial agent.
|
||
- `adapter`: `onboarding/adapter` — choose an available harness, model, account, and execution environment.
|
||
- `first-task`: `onboarding/first-task` — leave setup with a task whose execution or missing prerequisite is visible.
|
||
|
||
- `resume`: `onboarding/resume` — return to an incomplete wizard without losing saved state.
|
||
|
||
The [Cloud Product onboarding journey](../../tests/runner-e2e/PRODUCT-JOURNEYS.md)
|
||
defines portal workspace creation, API-key connection, native Codex creation,
|
||
and a first downloadable artifact with an independent oracle. Its dependent
|
||
task-properties journey reuses onboarding state. This is a scripted coverage
|
||
recipe, not a claim of a completed Cloud run or strict browser-only discovery.
|
||
|
||
## How to get to it (user POV)
|
||
|
||
### `web-wizard`
|
||
|
||
Open `/onboarding` or the onboarding launcher in an empty company context.
|
||
Use `/<company-prefix>/onboarding` to resume an existing company's agent setup;
|
||
the unprefixed route starts at organization naming on self-hosted instances.
|
||
Cloud-managed instances reuse their existing company for agent setup.
|
||
|
||
### `cli-setup`
|
||
|
||
Use `paperclipai onboard --help` or `paperclipai run --help` to select an isolated data directory before setup.
|
||
|
||
## Driving it with Playwright and the Paperclip CLI
|
||
|
||
Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use a new isolated data directory and record deployment mode. A configured adapter may still need account authentication.
|
||
|
||
### `web-wizard`
|
||
|
||
Automated: [wizard tests](../../ui/src/components/OnboardingWizard.test.tsx) cover mocked wizard behavior; [onboarding browser suite](../../tests/e2e/onboarding.spec.ts) supplies its own test environment. Live model execution is a separate check.
|
||
|
||
The [published canary smoke](../../tests/canary-onboarding/canary-onboarding.spec.ts)
|
||
checks the exact installed version through Connect a model. Submitting the agent
|
||
name must save one paused setup record with disabled heartbeats and no task or
|
||
run. The [authenticated release smoke](../../tests/release-smoke/docker-auth-onboarding.spec.ts)
|
||
checks the same held state, then completes that record through Connect without
|
||
creating a second agent. Its Docker harness mocks credential verification; live
|
||
provider authentication remains separate evidence.
|
||
|
||
Name-only setup defers the runner field while the provisional adapter remains
|
||
held in setup. Choosing a provider updates that same setup record with its
|
||
selected runner. The wizard regression covers a saved native choice followed by
|
||
OpenAI Subscription selection; it does not prove provider authentication.
|
||
|
||
- **Create company and resume.** Start a fresh empty instance and run doctor using
|
||
the [verification skill](../../.agents/skills/verify-paperclip/SKILL.md). Run
|
||
`node .agents/skills/verify-paperclip/scripts/onboarding-smoke.mjs --evidence-dir "$VERIFY_EVIDENCE_DIR"`.
|
||
The helper opens `/onboarding` in a fresh self-hosted instance, enters a unique
|
||
name in `e.g. Northwind Labs`, and chooses `Continue`. The agent-name field must
|
||
appear and the saved company must have no invented goal. Reopen the
|
||
company-prefixed onboarding route and reload; the agent step must appear
|
||
without creating another company. Screenshots and a trace capture the real UI action and result.
|
||
This proves company creation/resumption, not hiring or a first model run.
|
||
|
||
Manual: Create a disposable company and first agent. Leave midway, reopen the
|
||
company's onboarding route, and finish; drafts save automatically. Follow the
|
||
created first task, verify the selected agent and company, and inspect its output
|
||
or explicit authentication gate. Reload both company and task.
|
||
|
||
For Codex or Claude, choose the harness and leave runner selection automatic to prove the
|
||
first-agent default. On a qualified target it saves Paperclip Runner; Advanced
|
||
also permits Legacy. Do not switch runners after onboarding when claiming proof
|
||
of that default. Test the selected runtime and account, then complete a bounded
|
||
useful task and follow-up with an independently checked file artifact. Saved
|
||
execution configuration and recorded run identity must match after reload.
|
||
The Codex first-task eval applies operator QA bounds before Get started through
|
||
the existing agent configuration API. It verifies that only timeout and
|
||
concurrency change; automatic runner, account and environment choices remain.
|
||
These campaign bounds are separate from production creation defaults.
|
||
Use [runner validation](./runs-adapters.md#adapter-setup) and
|
||
[environment qualification](./execution-environments.md#environment-settings)
|
||
for the prerequisites; a successful login alone is insufficient.
|
||
|
||
For managed Cloud setup, an outdated default Claude CLI is prepared automatically
|
||
in a private versioned runtime directory before its hello test. Verify that the
|
||
selected model and account stay unchanged and that the compatible executable is
|
||
actually used. A failed installation still blocks hiring. Cloud failures must
|
||
not display Manual debug shell commands or legacy operator hints; self-hosted
|
||
failures retain that help.
|
||
[Wizard controls](../../ui/src/components/OnboardingWizard.test.tsx) and
|
||
[runtime controls](../../packages/adapters/claude-local/src/server/sandbox-cli-version.test.ts)
|
||
cover these boundaries. They do not establish live Cloud onboarding success.
|
||
|
||
For a new Claude agent on an explicit immutable sandbox image or a Daytona
|
||
named snapshot, use Connect to
|
||
qualify the selected environment through the existing permission-gated probe.
|
||
Do not preprobe outside onboarding when claiming this first-use path. Fresh
|
||
scoped discovery determines the runner for both the account test and hire;
|
||
the measured Legacy result remains valid. An instance-admin denial, incomplete
|
||
cleanup, missing lease or changed configuration stops setup before the adapter
|
||
test or hire. Daytona resolves the selected snapshot to its immutable provider
|
||
ID before creating the measured lease; native execution pins that same ID.
|
||
Mutable image tags and other providers’ named templates remain unqualified. [Helper controls](../../ui/src/lib/qualify-claude-setup.test.ts)
|
||
and mounted wizard/new-agent tests use mocks; live managed acceptance remains a
|
||
separate gate.
|
||
For a new Codex agent with Auto on a saved immutable OCI sandbox, Connect first
|
||
uses the existing saved environment probe when authoritative qualification is
|
||
absent. The board actor needs the existing instance-environment administration
|
||
permission. Refresh company/environment-scoped discovery before testing the
|
||
selected runtime. A denied probe, unconfirmed cleanup or setup failure must be
|
||
visible; selecting Legacy remains an explicit choice. Creation and discovery
|
||
themselves allocate no target. A valid measured unsupported target follows the
|
||
server's Legacy default. Named Cloud snapshots remain a separate unqualified
|
||
boot-identity and fresh-signup gap.
|
||
|
||
Selected native setup derives its target isolation as task execution does. The
|
||
hello probe retains its read-only permission profile, approval-never policy and
|
||
bounded provider turn. It skips Codex's project-instruction discovery in its new,
|
||
empty private workspace; ordinary tasks still load their project instructions.
|
||
Local and SSH transports retain Codex isolation. An injected environment flag
|
||
cannot establish an outer sandbox identity. Verify these boundaries with the
|
||
existing native setup controls and a real managed task/follow-up; source checks
|
||
alone are insufficient.
|
||
|
||
The explicit manual Product E2E cell
|
||
`confirmation-replies.runner-codex.daytona.task-card-accept` covers this fresh
|
||
managed wizard path without fixture agent creation or a fixture preprobe. Its
|
||
existing attachment oracle checks a downloaded physical file and follow-up
|
||
continuity. Setup evidence must correlate both lease IDs with the same company,
|
||
environment and provider; missing responses or unmatched rows keep cost coverage
|
||
unknown. Run this cell only on an eligible target with separately authorized
|
||
provider, runtime and cleanup reservations. Its source and mock controls are
|
||
prepared. The literal `ea6c8eb5e16d61111968f633a66748b397b64a3e` live attempt
|
||
failed: the child document existed, but the physical file was attached to the
|
||
parent, and recovery stopped the completion callback before a provider turn.
|
||
The failed report remains evidence; the revised source still needs live proof.
|
||
Local cases and automatic selection remain unchanged.
|
||
|
||
First-task task creation enforces proposal acceptance at the shared server
|
||
boundary. Verify that native `create_task` and both REST creation endpoints reject
|
||
an authenticated onboarding run before its latest proposal has a saved human
|
||
acceptance, including an explicit standalone parent. Then accept a confirmation
|
||
or the current plan revision and verify creation succeeds. Opening answers,
|
||
agent-only acceptance, stale plans and newer pending/rejected proposals must not
|
||
admit new work. [Admission controls](../../server/src/__tests__/onboarding-first-task-admission.test.ts)
|
||
exercise native and REST calls against disposable PostgreSQL; live model and
|
||
Cloud onboarding remain separate evidence.
|
||
|
||
After acceptance, reject a new task whose blockers include its onboarding source.
|
||
The rejected command must leave no task, dependency, wake or creation receipt;
|
||
a corrected retry must still create the ready child. Preserve valid blockers for
|
||
other work. Check equivalent UUID spellings and a later child PATCH as well as
|
||
native dependency edits, including the child's own run with a waiting parent and
|
||
no first-class dependency yet. Preserve normal API attempt auditing and allow blocker
|
||
corrections without a new proposal acceptance. The shipped handoff recipe copies the actual approved inputs and
|
||
constraints into the child, then makes the parent depend on the child. Its
|
||
schema and persistence controls do not prove that a live model follows it.
|
||
|
||
Native completion also requires a saved human proposal decision. An opening
|
||
answer alone must leave the first task in review. Verify that premature native
|
||
completion is refused, including a result already saved before finalization.
|
||
Accepted proposals and acknowledged human rejections can close the first task;
|
||
rejection still does not authorize new tasks. The
|
||
[native completion controls](../../server/src/services/native-runtime/paperclip-control-plane-port.test.ts)
|
||
exercise these boundaries against disposable PostgreSQL. These controls do not
|
||
identify a historical Cloud failure or establish live onboarding success.
|
||
|
||
For accepted file-producing work, verify exactly one self-assigned child with a
|
||
self-contained description. The onboarding run must yield through the existing
|
||
dependency/block disposition so the child's own execution can publish its file.
|
||
Native file registration remains bound to the executing task. On completion,
|
||
the original conversation must receive the actual child and downloadable file
|
||
links. Document-only child work may finish inline; a plan-only request must not
|
||
start implementation. Existing first-task asset controls check the instructions,
|
||
not model compliance. Inspect the child's execution, document, downloaded file
|
||
and source-correlated completion reply in the real journey.
|
||
|
||
Leave and resume during harness/runner setup. Confirm the draft retains the
|
||
explicit choice and compatible account bindings, old native Codex setup links
|
||
recover the harness and runner, and a changed harness or runner invalidates stale
|
||
test results. Existing Legacy agents remain Legacy when their onboarding/setup
|
||
configuration is reopened; this journey does not migrate them.
|
||
|
||
Reload both `/onboarding` and the company-prefixed route after the first agent is
|
||
saved but before Get started. The authorized draft must retain its current step
|
||
and that agent's execution choice. An explicit new-company opening still starts
|
||
fresh. Opening another company must clear the previous company's resource IDs;
|
||
an unauthorized account must not restore its draft. Existing component controls
|
||
cover these boundaries; they do not substitute for the managed first-task eval.
|
||
The existing mocked-login browser case reopens and reloads Connect directly. It
|
||
checks the saved company/name/harness/runner, exact active authorization session,
|
||
one login start and no hire while login is pending. This is login UI evidence,
|
||
not a provider or managed-environment qualification.
|
||
|
||
### `cli-setup`
|
||
|
||
Automated: [CLI onboarding](../../cli/src/__tests__/onboard.test.ts) and [isolated test drive](../../cli/src/__tests__/test-drive.test.ts) cover their setup contracts; they do not establish that every model account is usable.
|
||
|
||
Manual: Run setup in the disposable directory, open the URL it prints, and confirm the instance identity and company. Restart using that same configuration and verify saved state. Exercise an unavailable adapter and confirm an actionable error.
|
||
|
||
## Gotchas
|
||
|
||
- An empty company, an empty instance, and an unauthenticated browser are different states.
|
||
- Creating an agent does not prove its provider login or first execution succeeded.
|
||
- See [access](./access.md) for authenticated deployments and [agents](./agents.md) for later hiring.
|
||
|
||
### Storybook verification
|
||
|
||
#### `resume`
|
||
|
||
Capability ID: `onboarding/resume`.
|
||
|
||
Scope: ui
|
||
Storybook: Restored incomplete wizard; invalid or unauthorized saved company; temporarily withheld draft; account switch; storage failure.
|
||
Production: Reload company-prefixed onboarding without duplicating company; restore only authorized account/company draft and retain input after recoverable loading failure.
|
||
Sources: Source: [OnboardingWizard.tsx](../../ui/src/components/OnboardingWizard.tsx), [onboarding-state.ts](../../ui/src/lib/onboarding-state.ts). Tests: [OnboardingWizard.test.tsx](../../ui/src/components/OnboardingWizard.test.tsx), [onboarding-state.test.ts](../../ui/src/lib/onboarding-state.test.ts), [onboarding.spec.ts](../../tests/e2e/onboarding.spec.ts)
|
||
|
||
#### `instance`
|
||
|
||
Capability ID: `onboarding/instance`.
|
||
|
||
Scope: cli
|
||
Storybook: No authored UI story required for host installation and startup.
|
||
Production: Configure isolated data directory, start instance, confirm printed URL/identity/health, restart with saved configuration.
|
||
Sources: Source: [onboard.ts](../../cli/src/commands/onboard.ts), [onboard-service.ts](../../cli/src/onboard-service.ts). Tests: [onboard.test.ts](../../cli/src/__tests__/onboard.test.ts), [onboard-service.test.ts](../../cli/src/__tests__/onboard-service.test.ts), [test-drive.test.ts](../../cli/src/__tests__/test-drive.test.ts)
|
||
|
||
### Documentation scope: Login, invitations, and access
|
||
|
||
Deployment modes and core login/invite/member/token paths are mapped; exhaustive identity-provider, expiry, role, and resource-policy combinations remain.
|