GitHub
07/05/2026, 7:56 AMActive until a node actually picks them up
• Show carves as Pending once one or more targets have scheduled/started the carve
• Mark carves Completed only after all expected targets have fully finished their carve uploads
Carve list UX
• Display the carve path instead of the internal generated carve name
• Add a dedicated status column with clear lifecycle badges
• Add a manual Refresh button to refetch the carves table
• Surface the derived carve lifecycle state from the API to the React list
Carve detail UX
• Add a Complete carve action for incomplete carves
• Show recorded carve targets in the detail page
• Avoid rendering zero-value completion timestamps as bogus dates like 31 Dec
Carve target handling
• Persist carve target rows when a carve is created
• Return those target rows from the carve detail API response
Why
This fixes a few operator-facing problems in the carve workflow:
• carves could look completed even though nodes had only scheduled them
• carves could remain active forever even after every target actually finished
• the list showed internal carve names instead of the real file path operators care about
• whole-environment carve targets were not visible in the detail view
• unset completion timestamps rendered like real dates
Testing
• GOCACHE=/tmp/osctrl-gocache go test ./pkg/queries ./cmd/tls/handlers
• cd frontend && node node_modules/.ignored/vitest/vitest.mjs run src/features/carves/CarvesListPage.test.tsx src/features/carves/CarveDetailPage.test.tsx
• cd frontend && node node_modules/.ignored/typescript/bin/tsc -p tsconfig.json --noEmit
Notes
• Carve list status now uses a carve-specific derived state from carved-file rows rather than relying only on the parent distributed-query flags.
• The target persistence fix applies to newly created carves; older carves created before target rows were stored may still have incomplete target metadata.
jmpsec/osctrlGitHub
07/05/2026, 9:40 AM