Skip to content

feat: launch Kata task workspaces#598

Merged
mariusvniekerk merged 24 commits into
mainfrom
codex/kata-workspace-diff-targets
Jun 26, 2026
Merged

feat: launch Kata task workspaces#598
mariusvniekerk merged 24 commits into
mainfrom
codex/kata-workspace-diff-targets

Conversation

@mariusvniekerk

@mariusvniekerk mariusvniekerk commented Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Kata tasks need the same workspace launch path as provider issues without treating Kata issue IDs as provider issue numbers. This keeps Kata owned by the daemon while still resolving a watched repository when the mapping is clear.

This adds conservative Kata project-to-repo resolution, daemon-scoped string workspace identity, live Kata task details inside workspace sidebars, and diff controls that only show merge target comparison when a real associated PR exists.

Validation: targeted Go and Svelte tests, ui-package-check, context-sync, and embedded-browser smoke.

generated by a clanker

@roborev-ci

roborev-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

roborev: Combined Review (bd5de2a)

Medium-risk issues remain in the Kata workspace changes.

Medium

  • internal/workspace/manager.go:442
    Kata workspace branch/worktree identity is derived from short_id/qualified_id/issue_uid only, while the DB item key is scoped by daemon and project. Two tasks with the same project-local short ID mapped to the same repo can insert as distinct workspaces but collide on GitHeadRef and WorktreePath (kata-<branchID>), causing setup failures or branch conflicts.
    Fix: Include a stable scoped suffix/hash from KataWorkspaceItemKey in both the branch name and worktree directory, and add a test with the same short ID across different daemon/project identities.

  • internal/workspace/monitor.go:117 and internal/workspace/pushed_head_observer.go:212
    The new UI/backend paths support associated_pr_number for Kata workspaces, but PR association discovery still only considers issue workspaces. A PR opened from a Kata workspace branch will never populate associated_pr_number, so the PR tab and merge-target diff remain unavailable.
    Fix: Include WorkspaceItemTypeKataTask in the PR monitor/observer eligibility and detection switch, with tests covering refresh/observer association for Kata workspaces.

  • frontend/src/lib/components/terminal/KataWorkspaceSidebarPane.svelte:197
    The sidebar renders the shared Kata detail component but wires recurrence create/edit callbacks to no-ops, so visible controls like “Mark as recurring...” and recurrence edit actions silently do nothing.
    Fix: Wire the same recurrence dialog/mutation flow used by the main Kata workspace, or hide/disable recurrence controls in this sidebar until they are supported.


Panel: ci_default_security | Synthesis: codex, 11s | Members: codex_default (codex/default, done, 9m2s), codex_security (codex/security, done, 5m24s) | Total: 14m37s

@roborev-ci

roborev-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

roborev: Combined Review (704346c)

Summary verdict: one medium issue needs to be addressed before merge.

Medium

  • internal/server/settings_handlers.go:850 — Deleting a configured repo that still has a [[kata_projects]] mapping can now return a 500. The handler removes the repo and calls Config.Save, but validation now requires every Kata mapping to point at an exact configured repo, so the save fails and is surfaced as an internal server error. Users cannot remove that repo until they separately remove the mapping.

    Suggested fix: In the delete path, either cascade-remove matching KataProjects entries or preflight the dependency and return a 400/badRequest with a clear mapping dependency error. If cascading, return/update the full settings state so the frontend removes the affected mappings too.


Panel: ci_default_security | Synthesis: codex, 8s | Members: codex_default (codex/default, done, 7m36s), codex_security (codex/security, done, 5m21s) | Total: 13m5s

@mariusvniekerk mariusvniekerk force-pushed the codex/kata-workspace-diff-targets branch from 704346c to a5248f8 Compare June 25, 2026 23:23
@roborev-ci

roborev-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

roborev: Combined Review (a5248f8)

Medium findings require attention before merge.

Medium

  • internal/workspace/monitor.go:115
    Kata workspaces are created and documented as issue-like workspaces, but the PR association monitor only treats pull-request and issue workspaces as eligible. As a result, associated_pr_number is never populated for Kata workspaces, so the PR-backed sidebar and merge-target flow cannot become available after a user opens a PR from a Kata workspace branch.
    Fix: Include WorkspaceItemTypeKataTask in PR association and pushed-head observer eligibility, handling it like issue-backed workspaces where the associated PR is discovered from the workspace branch/repo rather than provider issue identity.

  • internal/server/kata_workspace.go:345
    readKataProjectTOML reads .kata.toml with os.ReadFile, which follows symlinks and has no size limit. Automatic Kata workspace resolution calls this for configured worktree_base_path repos from /kata/workspace-target and /kata/workspaces. A malicious or compromised repository checked out at that path can make .kata.toml a symlink to /dev/zero or another unbounded/special file, causing middleman to hang or exhaust memory during workspace target resolution.
    Fix: Reject symlinks and non-regular files with Lstat, enforce a small maximum size before reading, and read through an io.LimitReader so the TOML parser only receives bounded regular-file content.


Panel: ci_default_security | Synthesis: codex, 10s | Members: codex_default (codex/default, done, 6m10s), codex_security (codex/security, done, 4m56s) | Total: 11m16s

@roborev-ci

roborev-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown

roborev: Combined Review (81ffa49)

Summary verdict: Changes are mostly sound, but two Medium issues should be fixed before merge.

Medium

  • internal/server/settings_handlers.go:71
    slices.Clone(s.cfg.KataProjects) preserves a nil slice, so the settings endpoint can emit kata_projects: null even though the response schema marks kata_projects as a required non-null array. Normalize nil mappings to an empty slice before returning the settings response, matching the existing agents and launch_targets handling.

  • internal/workspace/manager.go:459
    Kata workspaces are persisted as kata_task, but the code paths that populate associated_pr_number still only process issue workspaces. A Kata workspace created through this API cannot discover its PR after the branch is pushed/opened, so the PR tab and merge-target diff controls stay unavailable except for manually seeded rows. Extend the PR association monitor and pushed-head observer to treat kata_task workspaces like issue workspaces, with tests covering a real Kata workspace association path.


Panel: ci_default_security | Synthesis: codex, 8s | Members: codex_default (codex/default, done, 10m55s), codex_security (codex/security, done, 5m59s) | Total: 17m2s

@roborev-ci

roborev-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown

roborev: Combined Review (072f2b0)

The PR is not ready: three medium-severity issues need fixes; no security findings were reported.

Medium

  • internal/server/kata_workspace.go:277
    Automatic fallback by project name is disabled whenever any configured .kata.toml has a UID/identity, even if the name-only match is in a different repo. That prevents valid name-only Kata projects from resolving once another watched Kata clone has stable identity metadata.
    Fix: Remove the global identifier-count gate; for name fallback, match only .kata.toml entries without UID/identity and require exactly one name match.

  • frontend/src/lib/components/terminal/WorkspaceListSidebar.svelte:883
    Kata workspaces are still treated as PR workspaces in the workspace list. The item bubble opens the PR tab, context menu URLs point at provider PR/issue number 0, and the row renders #0 instead of a Kata task identity.
    Fix: Add kata_task to this component’s workspace model and special-case display/actions: open the kata_task sidebar tab, avoid provider item URLs for Kata tasks, and render a stored Kata short/qualified ID or task label instead of #0.

  • internal/db/db_test.go:96
    Several DB migration/repair regression tests were deleted while adding a new workspace schema migration, including coverage for legacy timestamp repair, broken workspace migration repair, runtime-session rename, fleet schema repair, and workspace uniqueness migration behavior.
    Fix: Restore those migration tests with unaliased assert helpers instead of removing them.


Panel: ci_default_security | Synthesis: codex, 10s | Members: codex_default (codex/default, done, 11m43s), codex_security (codex/security, done, 7m15s) | Total: 19m8s

@mariusvniekerk

Copy link
Copy Markdown
Collaborator Author

internal/db/db_test.go:96
Several DB migration/repair regression tests were deleted while adding a new workspace schema migration, including coverage for legacy timestamp repair, broken workspace migration repair, runtime-session rename, fleet schema repair, and workspace uniqueness migration behavior.
Fix: Restore those migration tests with unaliased assert helpers instead of removing them.

WILL NOT DO. THESE TEST ARE A CANCER AND PROMOTE BAD DESIGN PATTERNS.

@wesm

wesm commented Jun 26, 2026

Copy link
Copy Markdown
Member

lol

@roborev-ci

roborev-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown

roborev: Combined Review (e20374d)

Code review found one medium-severity issue that should be fixed before merge.

Medium

  • internal/server/kata_workspace.go:333
    A repository contributor can commit .kata.toml as a symlink to an endless or very large local file, such as /dev/zero, in a repo configured with worktree_base_path. When the user opens a Kata task, /kata/workspace-target scans configured worktrees and os.ReadFile follows that symlink with no file-type or size limit. That can block or exhaust memory in the middleman process from untrusted repo content, taking down the local maintainer console.

    Remediate by Lstating .kata.toml, rejecting symlinks and non-regular files, and reading through a small explicit limit before TOML decoding.


Panel: ci_default_security | Synthesis: codex, 8s | Members: codex_default (codex/default, done, 6m49s), codex_security (codex/security, done, 5m23s) | Total: 12m20s

@roborev-ci

roborev-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown

roborev: Combined Review (af7320c)

Medium-risk issues remain before merge.

Medium

  • internal/db/db_test.go:95 - Several DB migration/repair regression tests were deleted while adding a workspace schema migration, leaving legacy timestamp repair, workspace migration repair, runtime-session rename, fleet schema repair, and workspace uniqueness preservation unguarded. Restore the migration regression tests with the unaliased assert import/helper style.

  • internal/server/settings_handlers.go:71 - kata_projects is declared as a required non-null array in the API schema, but slices.Clone(nil) leaves it nil, so default settings responses encode "kata_projects": null. Normalize nil Kata project mappings to an empty slice before returning settings.


Panel: ci_default_security | Synthesis: codex, 9s | Members: codex_default (codex/default, done, 11m15s), codex_security (codex/security, done, 5m38s) | Total: 17m2s

@roborev-ci

roborev-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown

roborev: Combined Review (ec2bd39)

No Medium, High, or Critical findings to report.

Both reviews found no reportable issues at Medium severity or above.


Panel: ci_default_security | Synthesis: codex, 4s | Members: codex_default (codex/default, done, 10m53s), codex_security (codex/security, done, 4m14s) | Total: 15m11s

mariusvniekerk and others added 19 commits June 26, 2026 13:30
Kata tasks need a workspace action that behaves like provider issues without making Kata part of the provider registry or requiring manual mapping in the common local-clone setup.

This design pins the server-side resolver, .kata.toml discovery boundary, manual settings fallback, action visibility rules, and test expectations before implementation.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Kata issues are not provider issues, so the design cannot require a synced provider issue number or reuse the provider issue workspace endpoint.

This updates the spec to require a string workspace owner key for Kata task UIDs, a Kata-backed workspace creation endpoint, and repository mapping only for choosing the worktree base.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Kata-backed workspaces should keep the workspace sidebar aligned with the live Kata task browser instead of reusing provider issue UI just because the worktree has a repository.

This records that kata_task workspaces mount the existing KataIssueDetail component through a loader/adapter, fetch live daemon contents, and fall back only to stored Kata metadata when live data is unavailable.

Validation: git diff --check.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
The workspace sidebar should reuse the live Kata task detail UI, but the existing component may need its browser-specific assumptions pulled out before it can be embedded cleanly.

This keeps the requirement focused on one shared task-detail implementation while allowing the implementation plan to refactor the existing boundary instead of cloning the UI for workspaces.

Validation: git diff --check.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Kata tasks need the same workspace affordance as provider issues without pretending their UID is a provider issue number. Store a string owner key and Kata metadata on workspace rows so create/reuse can key by Kata issue UID while provider workspaces preserve numeric numbers.

Repo resolution is intentionally conservative: manual settings mappings or a unique watched clone .kata.toml match choose the target repo, and ambiguous tasks expose no button. Workspace sidebars render the live Kata detail component so Kata task workspaces do not fall back to provider issue UI.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Kata tasks are daemon-owned strings, so raw issue UIDs cannot safely key workspaces once multiple Kata daemons or projects are in play. Requiring the daemon ID and storing a scoped owner key prevents cross-project reuse while keeping provider issue workspaces on their numeric keys.

Live Kata project payloads can expose opaque project UIDs while local clones identify the project through .kata.toml identity or name. The resolver now treats UID/identity as the stronger signal and only falls back to project name when exactly one watched clone claims it, so unclear mappings still hide the workspace action.

Validation: go test ./internal/db ./internal/workspace ./internal/server -shuffle=on; cd frontend && ../node_modules/.bin/vp test run src/lib/features/kata/KataWorkspace.test.ts; bun run check; git diff --check; scripts/context-sync --check. Verified in the embedded browser by creating a Kata-backed workspace and opening the live Kata task sidebar pane. The first two commit-hook runs hit a local tmux timeout in TestFleetSnapshotEmptyTmuxServerE2E under full package concurrency; rerunning that test alone passed.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Kata and issue workspaces do not have a merge target until a PR is associated with the workspace. Rendering Target unconditionally invited guaranteed 404s, and relative worktree roots could create the worktree under the Git base repo while the API later read a different path.

Normalize workspace roots to absolute paths, route non-PR merge-target lookup through associated_pr_number, and document the diff-scope contract so future workspace UI work keeps Target tied to real PR availability.

Validation: go test ./internal/workspace -run 'TestCreateKataTask|TestCreateIssue' -shuffle=on; go test ./internal/server -run 'TestWorkspaceDiffEndpointReportsMergeTarget' -shuffle=on; cd frontend && ../node_modules/.bin/vp test run --project unit ../packages/ui/src/components/workspace/WorkspaceRightSidebar.test.ts; ./node_modules/.bin/vp run ui-package-check; git diff --check; scripts/context-sync --check. Verified in the embedded browser at http://127.0.0.1:64298/terminal/7c29c65820bbc431 that the Kata workspace diff shows HEAD and Branch only, with no file-list error.

Generated with Codex

Co-authored-by: Codex <codex@openai.com>
Migration 000036 introduced real schema artifacts but left the SQL file as a no-op and reconciled columns later in Go. That made an impossible version/schema mismatch look supported and encouraged future migrations to hide bad fixtures behind conditional column repair.

Put the owner-key schema changes back into the numbered migration and make rewind fixtures remove later artifacts before claiming an older schema version. The migration docs now state that version and physical schema must match, so duplicate-column states fail instead of being papered over.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Migration 000036 should only define the schema and backfill existing rows. A trigger that fills item_key for future inserts hides call sites that failed to adopt the new required column.

Remove the fill trigger and make current-schema workspace fixtures pass item_key explicitly, matching the production InsertWorkspace path. The migration guidance now calls out that new required columns should be written by inserts rather than papered over by triggers or repair hooks.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Unsupported downgrade fixtures were modeling impossible version/schema combinations and had started driving production migration design in the wrong direction. Keep historical fixtures limited to forward migration tests, remove the ordinary downgrade/legacy-row tests, and document that invariant for future schema work.

Kata workspace rows also need scoped local branch/worktree identities and live embedded task controls to match their scoped owner keys. This keeps same-short-ID tasks from colliding, hides merge-target-dependent diff controls when no PR exists, wires recurrence actions in the embedded task pane, and tolerates settings payloads that omit kata_projects.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Aliased testify/assert imports made test helpers depend on a package alias that should not exist and contradicted the test guidance. Enforce the unaliased assert import through importas, normalize existing Assert usages to assert.New/assert calls, and document the convention so future test edits have both lint and context coverage.

Validation: go test ./tools/testifyhelpercheck -shuffle=on; go test ./... -run '^$' -shuffle=on; GOCACHE="${GOCACHE:-/tmp/middleman-gocache}" mise exec -- golangci-lint run --fix; go test ./internal/server -run TestMsgvaultConfigureRejectsInvalidUpdateWithoutReplacingPriorConfig -shuffle=on; git diff --check; scripts/context-sync --check.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Rebasing onto current main surfaced stale assert helper aliases in tests that are compiled through the PR merge ref. Normalize those call sites so the assert import policy and the merged test set agree.\n\nDeleting a configured repo also has to keep kata project mappings valid, because config save validates mappings against the remaining exact repo list. Cascade mappings for the deleted repo and roll back both config slices if persistence fails.\n\nValidation: go test ./internal/server -run 'TestHandleDeleteRepo|TestHandleDeleteRepoRemovesKataProjectMappings' -shuffle=on; go test ./internal/github ./internal/server -run '^$' -shuffle=on; make lint; make test-short.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Non-PR workspaces no longer render merge-target-dependent controls, including the commit range picker. The full-stack workspace diff spec was still opening that picker, so Chromium CI failed after the intended UI change.\n\nUpdate the spec to assert the two available scopes and the absence of Target and commit-range controls for a workspace without a merge target.\n\nValidation: cd frontend && ../node_modules/.bin/vp test run; cd frontend && ../node_modules/.bin/vp exec -- playwright test --config=playwright-e2e.config.ts --project=chromium --project=firefox tests/e2e-full/00-workspace-tab-persistence.spec.ts.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Deleting a configured repo can invalidate Kata project mappings because config saves validate those mappings against the exact configured repo set. Record that settings deletion must cascade the matching mappings in the same save and rollback path so future settings work does not rediscover the failure mode.\n\nValidation: git diff --check; scripts/context-sync --check.

Generated with Codex
Co-authored-by: Codex <codex@openai.com>
Automatic project-name fallback was gated on a global count: if any watched
clone's .kata.toml carried a uid/identity, name matching was disabled for every
clone. A valid name-only Kata project then stopped resolving as soon as an
unrelated watched clone gained stable identity metadata, hiding its workspace
action.

Make the guardrail per-entry instead: name matching considers only clones that
declare no uid/identity, and still requires exactly one match. A clone with
stable identity is matched by uid/identity alone and is never resolved by a
colliding name, which also removes the ambiguity a reviewer flagged in the
design spec. Document the precedence and the both-fields matching rule so
separate implementations cannot diverge.

Validation: go test ./internal/server -run TestKataWorkspaceTarget -shuffle=on;
go vet ./internal/server; golangci-lint run ./internal/server;
scripts/context-sync --check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Kata workspaces were rendered through the provider PR/issue path in the
workspace list. The item bubble opened the PR sidebar tab, its context menu
offered "Open item on provider" / "Copy item URL" built from provider item
number 0, and the row showed "#0" instead of the Kata task identity.

Teach the list its third owner type. Kata rows now open the kata_task sidebar
tab, render the stored short/qualified ID (falling back to a "Kata" label) with
the task title in the tooltip and as the display name, suppress the provider
item URL since a Kata task has no provider PR/issue, and match search against the
task identity instead of the numeric item. The bubble gets its own state class
and is width-capped so variable-length identifiers do not disturb the row layout.

Validation: cd frontend && node ../node_modules/vite-plus/bin/vp test run
src/lib/components/terminal/WorkspaceListSidebar.test.ts; full unit project run;
frontend-check (fmt, lint, svelte-check).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The diff-scope contract said the merge-target scope exists "when the workspace
has a PR identity," but the server only resolves it when a synced repo row, a
synced merge request row, and a non-empty base branch all exist. A workspace
whose associated PR is unsynced, removed, or has no base branch therefore still
satisfies the documented condition while the API returns "merge target branch
not available," reopening the 404 path the hidden controls were meant to prevent.

State availability as a resolvable merge target branch, make the server the
authority, and record that the sidebar's PR-identity gate is necessary but not
sufficient so the divergence is a known, expected state rather than a surprise.
Note the resolved-merge-target summary signal as the follow-up that would let the
UI gate match the server check exactly.

Validation: scripts/context-sync --check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The workspace list now treats kata_task as a third owner type, but that
contract lived only in the implementation: a future change could diverge on how
a Kata row labels its bubble, what it falls back to when short_id/qualified_id/
title are absent, whether item_number 0 is a value to show, and which provider
actions apply.

Document the list-row presentation in the design spec — bubble identity fallback
(short_id, then qualified_id, then "Kata"), display-name fallback (title, then
branch), the kata_task sidebar tab, the suppression of provider item-URL
actions, and identity-based search — so the two label fallback chains and the
"item_number 0 is incidental, not a sentinel" rule are explicit.

Also assert the full Kata identity (project name, short/qualified ID, title) on
the create-workspace response. That real-HTTP plus SQLite test is what proves the
wire shape the list rendering depends on, so the frontend component fixture is
backed by a backend contract test rather than asserting backend-shaped values on
its own.

Validation: go test ./internal/server -run TestCreateKataWorkspace -shuffle=on;
scripts/context-sync --check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Kata workspace search only indexed the optional short_id, qualified_id, title,
and project name. A Kata workspace created without a short or qualified ID
renders the generic "Kata" bubble and was then unsearchable: none of its durable
identifiers were in the haystack, so it could not be located by its actual task
UID or owner key.

Add the daemon, project, and issue UIDs and the stored item_key to the Kata
search haystack so such a workspace stays findable by its key, and document the
behavior alongside the rest of the Kata list-row contract.

Validation: cd frontend && node ../node_modules/vite-plus/bin/vp test run
src/lib/components/terminal/WorkspaceListSidebar.test.ts; svelte-check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mariusvniekerk and others added 5 commits June 26, 2026 13:30
The workspace list reloads from GET /workspaces, but coverage only asserted the
create response. If list serialization or the DB summary hydration dropped the
kata object, create could pass while the list fell back to a generic "Kata" or
branch-only label after a refresh.

Add a real-backend list test that seeds a kata_task workspace and asserts GET
/workspaces returns the full Kata owner metadata (project UID/name, short and
qualified IDs, title) plus item_number 0. Also reconcile the design spec: the
ownership-schema and API-shape sections claimed item_number was absent/omitted
for Kata workspaces, but it is a non-nullable integer always emitted as 0, so the
contract now says exactly that and tells consumers to ignore it. Document the
list-endpoint and list-row fallback expectations in the coverage section.

Validation: go test ./internal/server -run TestListWorkspacesIncludesKataMetadata
-shuffle=on; scripts/context-sync --check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
.kata.toml lives in a watched repository whose contents are not trusted. A
contributor could commit it as a symlink to an endless or very large file such
as /dev/zero; when a maintainer opens a Kata task, /kata/workspace-target scans
each configured worktree and os.ReadFile followed that symlink with no file-type
or size limit, so untrusted repo content could stall or exhaust memory in the
local middleman process and take down the console.

Lstat the path and accept only a regular file (rejecting symlinks, devices,
FIFOs, and directories), re-check the opened descriptor to close the Lstat/open
swap window, and read through an explicit 64 KiB cap before TOML decoding. The
file only carries a tiny [project] table, so the cap is generous while making an
unbounded read impossible.

Validation: go test ./internal/server -run
'TestReadKataProjectTOML|TestKataWorkspaceTarget' -shuffle=on; go vet
./internal/server; golangci-lint run ./internal/server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capture in the Kata design spec that .kata.toml is untrusted repository content
read defensively (regular-file only, bounded size), so a later resolver change
does not reintroduce an unbounded os.ReadFile that a malicious clone could abuse
to stall or exhaust the process.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kata_projects is declared as a required non-null array in the settings schema,
but the default no-mappings case left it as a nil slice (slices.Clone(nil)),
which serializes to "kata_projects": null. That contradicts the schema's
nullable:"false" contract and forces clients to handle a null where the type
promises an array.

Normalize the cloned mappings to an empty slice before returning, matching how
agents and launch targets are already handled. Add a wire-level test asserting
the default response encodes the field as [] rather than null.

Validation: go test ./internal/server -run
'TestHandleGetSettings|TestHandleUpdateSettingsPersistsKataProjectMappings'
-shuffle=on; go vet ./internal/server; golangci-lint run ./internal/server.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Rebasing this branch onto main combined main's newly added GitHub App token
tests (which still import testify/assert aliased as Assert) with this branch's
importas rule that forbids the alias. Git's three-way merge kept main's new
Assert.* call sites while taking this branch's unaliased import, leaving
undefined: Assert and breaking compilation, lint, and the Go test jobs on the PR
merge ref.

Normalize the three surviving Assert.* usages to the unaliased assert package so
the merged tree compiles and satisfies the no-alias lint rule.

Validation: golangci-lint run ./...; make testify-helper-check; go build ./...;
go test ./internal/config ./internal/tokenauth ./internal/githubapp
./internal/github ./cmd/middleman -shuffle=on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mariusvniekerk mariusvniekerk force-pushed the codex/kata-workspace-diff-targets branch from ec2bd39 to faa6cf8 Compare June 26, 2026 18:25
@roborev-ci

roborev-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown

roborev: Combined Review (faa6cf8)

High-risk regression: the diff removes important upgrade/migration coverage and should restore equivalent tests before merge.

High

  • internal/server/e2etest/labels_provider_test.go:463, internal/db/label_external_id_migration_test.go:1, internal/db/db_test.go:95
    • The change removes upgrade and migration regression coverage instead of updating it. The deleted GitLab legacy label external ID e2e/migration tests protect an upgrade path where label assignments can be silently rewired, and several DB repair regression tests are also removed.
    • Restore equivalent migration and e2e coverage with unaliased assert/require imports, or move it to focused test files without reducing the covered upgrade paths.

Panel: ci_default_security | Synthesis: codex, 7s | Members: codex_default (codex/default, done, 7m49s), codex_security (codex/security, done, 5m32s) | Total: 13m28s

@mariusvniekerk mariusvniekerk merged commit ede5e5a into main Jun 26, 2026
17 checks passed
@mariusvniekerk mariusvniekerk deleted the codex/kata-workspace-diff-targets branch June 26, 2026 18:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants