worktree dirty at stage end: the "uncommitted path" is the harness's own .konveyor/analysis.json

Open
#257 0 comments 0 reactions 1 assignee View on GitHub

Maintainers usually reply within 1 day

@hhpatel14 is already working on this.

Since Sep 29, 2026.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
52/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Active
Tech stack
git, go, kubernetes

Research direction

Start in harness/cmd/migration-harness/main.go at the harness write around lines 999-1016 and the step 11 dirty-worktree check around lines 538-544. Trace how the cloned repository is prepared and how status output is collected. Done means harness-authored paths are handled deterministically, the warning reflects agent work, and the log identifies the remaining paths.

Written by the indexing model from the issue text.

Description

bug

Summary

worktree dirty at stage end — agent left N uncommitted paths fires on clean,
fully successful runs. The uncommitted path is not agent work: it is
.konveyor/analysis.json, which the harness itself writes into the cloned
repo before the agent starts. The warning names the agent for the harness's own
artifact, and because it fires on essentially every plan stage it can't serve
as a signal for the case it exists to catch (see #166).

A second consequence: whether .konveyor/ ends up on the pushed branch is
decided by whichever git add the model happens to type that run, so branch
contents are nondeterministic across runs.

Evidence

Traced on a full green run (rec-4zjzj, all three stages Succeeded) by
polling git status --porcelain inside the live stage pods.

The harness writes the file at
harness/cmd/migration-harness/main.go:999-1016,
and the check is step 11 at
main.go:538-544.

plan stage — warning fires

Pod log:

00:32:10 INFO  [ok] wrote 45 analysis insights to /workspace/repo/.konveyor/analysis.json
00:35:38 INFO  [ok] watcher push: success
00:35:40 WARN  worktree dirty at stage end — agent left 1 uncommitted paths
00:35:40 INFO  [header] Final Push

Worktree, polled from inside the pod:

time git status --porcelain HEAD
20:32:19 ?? .konveyor/ ← harness wrote it, ~3 min before the agent acted base
20:35:08 ?? .konveyor/, ?? docs/ base
20:35:15 A docs/plan.md, ?? .konveyor/ base
20:35:21 ?? .konveyor/ d65cfa9

The agent committed all of its own work. The single remaining path is the
harness's.

It is not ignored, so it cannot be skipped by accident:

$ git check-ignore -v .konveyor/analysis.json
(not ignored)
$ cat .git/info/exclude
(does not exist)

coolstore's .gitignore is target, .classpath, .idea, .settings,
.vscode — nothing covering .konveyor/.

execute and verify — no warning

Neither stage warns, because both agents happened to run:

00:40:01 INFO  tool: shell · cd /workspace/repo && git add -A && git status

git add -A sweeps up the harness's file along with the agent's edits, so the
worktree ends clean. The plan agent ran git add docs/plan.md instead.

Resulting branch contents
55251b2  Verify: Complete build verification and fix compilation issues
36357b8  Execute: Complete Java EE to Quarkus 3 migration
d65cfa9  Add migration plan for Java EE 7 to Quarkus 3 migration
100f12c  (base)
commit added
d65cfa9 (plan) docs/plan.md
36357b8 (execute) .konveyor/analysis.json, .konveyor/handoff.md

So .konveyor/analysis.json lands on the branch as a side effect of the
execute agent's git add -A, two stages after it was written. On runs where
no agent uses git add -A, it never lands at all — which matches what's
observable across older branches (konveyor/migration-1786821891 has no
.konveyor; konveyor/migration-1785854186 has it with execute.json,
graph.json, spec.md, …).

Why it matters

  1. The message is factually wrong. It attributes a harness-written file to
    the agent.
  2. It logs a count, never the paths, so nobody reading the log can tell
    what was left — the pod is gone by then. Determining this required polling
    a live pod.
  3. It always fires on plan, which makes it useless as a signal. #166 asks
    for exactly this warning to become a reliable indicator that real agent work
    was lost; that can't happen while a harness artifact keeps it permanently on.
  4. Branch contents are nondeterministic. Whether .konveyor/ is committed
    depends on the model's choice of git add invocation.

Suggested fix

Three small, independent pieces:

  • Decide whether .konveyor/ belongs on the branch, and make it
    deterministic either way. If it is harness scratch, write it to
    .git/info/exclude right after clone, so no agent can accidentally commit it.
    If it is meant to be published, have the harness commit it itself rather than
    hoping an agent sweeps it up.
  • Exclude harness-authored paths from the dirty check, so the warning
    reflects only agent work.
  • Log the paths, not just the count (capped, e.g. first 10 + …and N more),
    so the warning is actionable from the log alone.

With those, the warning becomes a true signal and #166's checkpoint work has
something reliable to trigger on.

Related

  • #166 — Agent work is lost on abnormal stage termination. Same check, but
    scoped to abnormal termination; this report is the clean-exit case and the
    reason that check currently can't be trusted.
Dominant language
Go
Stars
5
Forks
13
Avg merge
4d 2h
Merged PRs (30d)
27

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • Has a pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from konveyor/agentic-controller

All issues in konveyor/agentic-controller

Similar issues

More Go issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.