mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-28 04:02:18 +01:00
Cover the agent prerequisite at the test API boundary
Update the route fixture for the new plugin declaration lookup and assert that missing agent scope never allocates a lease or falls back to the host. Document preparation and its unchanged actor and task-admission boundaries in the feature and access maps. Verified all 54 environment-test route cases, map structure checks, and token gates. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
3 files changed
+41
-1
No files matched your search
@@ -50,12 +50,20 @@ permission. Its creator can finish their own inactive setup with that permission
|
||||
changing another person's setup requires configuration permission.
|
||||
Creation retries reuse only records owned by the caller. Returning a completed
|
||||
record also requires the normal agent-read and configuration-read checks.
|
||||
An unfinished record stays paused with a
|
||||
An unfinished record keeps compatibility status `paused` with a
|
||||
`setup` hold and cannot receive API keys or authenticate with keys or JWTs.
|
||||
Its standard grants apply at hire. Authorized completion retries recover the
|
||||
same record and approval without changing the submitted configuration.
|
||||
Normal agent-authored hiring keeps its existing approval policy.
|
||||
|
||||
An agent-owned plugin may prepare the draft and leave its lifecycle in
|
||||
`verifying` while that setup hold remains. Only bounded Core-issued setup probes
|
||||
can run there. The creator's company creation permission also covers configuring
|
||||
and retrying their draft during preparation; other actors still require the
|
||||
ordinary configuration permission. This is a board wizard path, not new agent
|
||||
execution or probe authority. Lifecycle and component regressions cover these
|
||||
transitions; no permitted-agent or live-provider journey is claimed here.
|
||||
|
||||
The creation boundary resolves the request-level runner before adapter validation
|
||||
and credential normalization. Omitted/automatic new Codex selection uses the
|
||||
qualified target's default; explicit Legacy is retained. Disabled adapters and
|
||||
|
||||
@@ -37,6 +37,12 @@ Save & exit keeps its configuration; Finish setup on the agent returns to the
|
||||
same record. Final submission requests approval when required, then follows the
|
||||
existing preparation and verification lifecycle.
|
||||
|
||||
Agent-owned plugin environments prepare the saved draft in the background when
|
||||
their driver declares `requiresAgent`. The draft waits in `verifying` with its
|
||||
setup hold until hiring finishes. Changing environments keeps the selected
|
||||
account and Configure step, saves the selection, and invalidates its test.
|
||||
Preparation and failed-save retries remain visible without reconnecting.
|
||||
|
||||
### `agent-configuration`
|
||||
|
||||
Open `/agents/:agentId` and the configuration/instruction surfaces it exposes.
|
||||
@@ -87,6 +93,14 @@ Preconditions: follow the [baseline](./README.md#before-driving-a-journey). Use
|
||||
|
||||
Automated: [new agent page](../../ui/src/pages/NewAgent.test.tsx) and [configuration form](../../ui/src/components/AgentConfigForm.render.test.tsx) cover mocked UI behavior.
|
||||
|
||||
For an agent-owned plugin environment, verify preparation before connecting,
|
||||
same-agent probes, account preservation after an environment change, failed
|
||||
selection-save retry, and switching back while the computer stops. Confirm the
|
||||
setup hold still blocks ordinary work and API key creation before finishing.
|
||||
The [lifecycle tests](../../server/src/modules/agent-lifecycle/__tests__/lifecycle.test.ts)
|
||||
exercise durable transitions with synthetic plugin resources; they do not prove
|
||||
live VM provisioning.
|
||||
|
||||
Manual: Hire an agent with a distinct name and role. Complete any required approval, reload the roster, and open its configuration. Confirm manager, adapter, and model persisted; run a small task to prove execution readiness.
|
||||
|
||||
For a new Codex hire, choose the Codex harness. Automatic selection uses Paperclip
|
||||
|
||||
@@ -46,6 +46,11 @@ const mockEnvironmentRuntime = vi.hoisted(() => ({
|
||||
}));
|
||||
|
||||
const mockResolveEnvironmentExecutionTarget = vi.hoisted(() => vi.fn());
|
||||
const mockPluginEnvironmentRequiresAgent = vi.hoisted(() => vi.fn(async () => false));
|
||||
vi.mock("../services/plugin-environment-driver.js", async importOriginal => ({
|
||||
...(await importOriginal<typeof import("../services/plugin-environment-driver.js")>()),
|
||||
pluginEnvironmentRequiresAgent: mockPluginEnvironmentRequiresAgent,
|
||||
}));
|
||||
const mockInstanceSettingsService = vi.hoisted(() => ({
|
||||
get: vi.fn(async () => ({ defaultEnvironmentId: null as string | null })),
|
||||
getGeneral: vi.fn(async () => ({ censorUsernameInLogs: false, executionMode: "local" })),
|
||||
@@ -1053,6 +1058,19 @@ describe("agent test-environment route", () => {
|
||||
mockResolveNewAgentRunnerForCompany.mockClear();
|
||||
});
|
||||
|
||||
it("reports the missing agent prerequisite without acquiring a lease or probing the host", async () => {
|
||||
mockPluginEnvironmentRequiresAgent.mockResolvedValueOnce(true);
|
||||
mockResolveNewAgentRunnerForCompany.mockResolvedValueOnce({ adapterType: "paperclip_runner", adapterConfig: { provider: "codex" } });
|
||||
const app = await createApp();
|
||||
const res = await request(app)
|
||||
.post("/api/companies/company-1/adapters/codex_local/test-environment")
|
||||
.send({ adapterConfig: {}, environmentId: pluginEnvironment.id });
|
||||
expect(res.status, JSON.stringify(res.body)).toBe(200);
|
||||
expect(res.body).toMatchObject({ status: "warn", checks: [{ code: "environment_agent_required", level: "warn" }] });
|
||||
expect(mockEnvironmentRuntime.acquireRunLease).not.toHaveBeenCalled();
|
||||
expect(testEnvironmentSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("checks the plugin driver against the resolved Runner adapter, not the requested harness", async () => {
|
||||
mockResolveNewAgentRunnerForCompany.mockResolvedValueOnce({ adapterType: "paperclip_runner", adapterConfig: { provider: "acpx", acpxAgent: "claude" } });
|
||||
const app = await createApp();
|
||||
|
||||
Reference in new issue
Block a user