mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 13:24:55 +01:00
feat(environments): expose boot-relevant drift attribution in the custom-image overview (#11751)
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - Paperclip lets operators prepare and use custom images for sandbox environments > - The custom-image overview detected drift but did not show which boot source changed > - Operators need the changed field and values to understand why a template no longer matches > - This pull request adds safe drift attribution to the overview API and the out-of-sync banner > - The benefit is faster diagnosis without exposing secrets or internal snapshot data ## Linked Issues or Issue Description **Subsystem affected** Cross-cutting (server and UI). **Problem or motivation** The custom-image overview reported drift without identifying the changed boot source. Operators had to inspect other data to find the cause. **Proposed solution** Return a classified drift summary with changed paths and their prior and current values. Show the boot-source field in the UI banner. Keep legacy templates and unclassified drift on the generic message. **Alternatives considered** The change does not expose the full snapshot or fingerprint. This keeps the overview contract small and avoids secret disclosure. **Roadmap alignment** The change supports the existing custom-image environment workflow and does not duplicate a roadmap item. ## What Changed - Add `activeTemplateDrift` to the custom-image overview response. - Classify drift as `boot_source_drift`, `knob_only`, or `unclassified`. - Return drifted paths with safe `from` and `to` values. - Show the changed boot-source field and values in the out-of-sync banner. - Keep legacy templates fail-closed and exclude secrets, fingerprints, and raw snapshots. - Add server and UI tests for the new behavior. ## Verification - `npx vitest run server/src/__tests__/environment-custom-images-service.test.ts` passes with 27 tests. - `npx vitest run ui/src/pages/CompanyEnvironments.test.tsx` passes with 27 tests. - `pnpm --filter @paperclipai/ui exec tsc --noEmit` passes. - Review the overview response and banner cases for boot-source, knob-only, and legacy drift. ## Risks The overview response gains one optional field. Legacy templates remain compatible because they return `unclassified` and keep the generic banner. The service excludes secret values, fingerprints, and raw snapshots. ## Model Used OpenAI Codex, GPT-5, tool use and code execution enabled. The model reviewed the handoff and managed the pull request. ## Checklist - [x] I have included a thinking path that traces from project context to this change - [x] I have specified the model used (with version and capability details) - [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 either (a) linked existing issues with `Fixes: #` / `Closes: #` / `Refs: #` OR (b) described the issue in-PR following the relevant issue template - [x] I have not referenced internal/instance-local Paperclip issues or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip` URLs) - [x] My branch name describes the change (e.g. `docs/...`, `fix/...`) and contains no internal Paperclip ticket id or instance-derived details - [x] I have run 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] All Paperclip CI gates are green - [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [ ] I will address all Greptile and reviewer comments before requesting merge Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
2eb9a09c0c
commit
b8a76081ec
5 files changed
+258
-5
No files matched your search
@@ -20,10 +20,22 @@ export interface EnvironmentCustomImageOverview {
|
||||
* back to the base image until a new image is captured. `null` when unknown.
|
||||
*/
|
||||
activeTemplateMatchesConfig?: boolean | null;
|
||||
/**
|
||||
* Boot-relevant drift attribution for the active template. It names the
|
||||
* classification and the drifted paths with their `from`/`to` values, so the
|
||||
* banner can name the changed field. `null` or absent when there is no active
|
||||
* template or the driver is not `sandbox`.
|
||||
*/
|
||||
activeTemplateDrift?: EnvironmentCustomImageActiveTemplateDrift | null;
|
||||
activeSession: EnvironmentCustomImageSetupSession | null;
|
||||
latestSession: EnvironmentCustomImageSetupSession | null;
|
||||
}
|
||||
|
||||
export interface EnvironmentCustomImageActiveTemplateDrift {
|
||||
classification: EnvironmentCustomImageRelinkClassification;
|
||||
driftedPaths: EnvironmentCustomImageDriftedPath[];
|
||||
}
|
||||
|
||||
export type EnvironmentCustomImageReconciliation =
|
||||
| { action: "relinked"; template: EnvironmentCustomImageTemplate }
|
||||
| { action: "detached"; template: EnvironmentCustomImageTemplate };
|
||||
|
||||
Reference in new issue
Block a user