Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/agent-memory/atomic-executor/MEMORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Atomic Executor Memory Index

- [Sibling-worktree shared-tooling hazard](project_sibling_worktree_shared_tooling_hazard.md) — a concurrent agent in a DIFFERENT worktree crashes your testhost + clobbers /tmp logs via shared global vstest/dotnet-coverage; use session scratchpad for logs, poll for a quiet machine before test runs, trust bash `$?` not log counts, never kill/commit others' processes/memory files
- [#375 residuals nullable gotchas](project_375_residuals_nullable_gotchas.md) — CS8644 inherited-interface mismatch from oblivious #366 base fixed with a `#nullable disable` island on the class-declaration line (not `!`); full-solution Rebuild cleans SVGControl.dll → isolated gate CS0006, re-run no-TWAE Build first; MeetingItemHelper Lazy<T> classes: bulk `= null!` + `(...)!` getters/lambdas beats widening the API (Python utf-8-sig for CRLF+BOM files)
- [#364 nullable-gate pre-existing blockers](project_364_nullable_gate_preexisting_blockers.md) — full-solution pragma-only TWAE gate fails at baseline (vendored SVGControl CS0649 + non-HelperClasses CS0618/CS0168); verify CS86xx via isolated UtilitiesCS build w/ BuildProjectReferences=false; analyzer-version drift needs nuget-install into packages/; coverage script single-assembly StrictMode bug

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: sibling-worktree-shared-tooling-hazard
description: A concurrent agent in a SIBLING worktree corrupts your test runs and temp logs via shared global tooling, even though source is isolated
metadata:
type: project
---

Two agents in DIFFERENT worktrees (e.g. `.claude/worktrees/agent-XXXX` and
`TaskMaster-wt/<other-feature>`) share machine-global resources even though their source trees are
git-isolated. This is distinct from [[project_concurrent_executor_same_worktree]] (same-worktree
file corruption).

**Why:** Observed on #374 (dialogs-misc) while a sibling agent ran #365 (outlook-folder-store)
concurrently. Three failure modes, all environmental (not code defects):
1. **Shared `/tmp`** — MSYS `/tmp` maps to a machine-wide temp dir. Both agents naturally pick the
same log filenames (e.g. `/tmp/baseline-tests.log`), so one clobbers the other; you may read the
OTHER worktree's output and see its paths/assemblies. Symptom: your log references a foreign
worktree path.
2. **Shared vstest/dotnet-coverage/testhost** — `Invoke-MSTestWithCoverage.ps1` uses global exes.
Under concurrent 24-worker (`<Workers>0</Workers>` = auto) coverage runs from both agents, the
testhost crashes mid-suite ("Test host process crashed", exit -1/1/127, partial pass counts like
522/927/5701 with 0 failures). Nondeterministic.

**How to apply:**
- Write ALL temp logs to the session scratchpad dir (from the system reminder), NEVER `/tmp`.
- Before every coverage/test run, poll for a quiet machine and only run when zero
`vstest|dotnet-coverage|testhost` processes exist; retry the whole run if it crashes with 0 test
failures. A poll-loop (up to ~40×15s) then run, wrapped in an up-to-5-cycle retry, reliably
catches a quiet window; a clean run is Total 5702 / Passed 5702 / 0 failed.
- Trust the bash `$?` exit code (yours), not log-derived counts, when logs may be clobbered. Build
gate conclusions on the scoped-build EXIT code (0 = zero CS86xx), which is immune to log
contamination.
- Do NOT kill testhost/vstest/dotnet-coverage processes — you cannot tell yours from the sibling
agent's, and killing theirs sabotages them. Just wait.
- Never stage the sibling/orchestrator's `.claude/agent-memory/orchestrator/*` files (they change
under you during the run); leave them untracked/modified and commit only your feature paths.
1 change: 1 addition & 0 deletions .claude/agent-memory/orchestrator/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@
- [Unplanned epic-child worktree mechanics](unplanned-epic-child-worktree-mechanics.md) — cross-worktree delegation works via absolute paths; atomic-executor runs C# tools via pwsh with explicit paths (vstest/csharpier not on PATH); collect_pr_context + PR/merge hooks resolve against session root
- [Parallel epic children name collisions](parallel-epic-children-name-collisions.md) — siblings coin identical type names in shared namespaces; CS0101/CS0104 surface only at rebase; rename YOUR types, rerun toolchain, no re-review
- [Swordfish epic F5 ScoDictionary blocker (RESOLVED)](project_swordfish_epic_f5_blocked_on_old_scodictionary.md) — F5 (#308) once WI-0-halted on the OLD ScoDictionary Swordfish base (ScoDictionaryNew was a decoy); #315/PR #316 deleted it, F5 then completed. Lesson: grep the OLD class base + using, not just the *New replacement
- [Epic-child stale local integration ref](project_epic_child_stale_local_integration_ref.md) — local branch ref for the epic integration branch can be stale in an agent worktree; `git fetch` and branch from `origin/<branch>`, not the bare local name, before trusting a Phase-0 gate
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: epic-child-stale-local-integration-ref
description: Local branch ref for the epic integration branch can be stale in an agent worktree; always git fetch and use origin/<branch> as the tip before branching a child worktree or checking a Phase-0 gate.
metadata:
type: project
---

For epic-child #374 (utilitiescs-nullable-dialogs-misc), the local ref
`epic/utilitiescs-nullable-remediation-integration` in the agent worktree
(`.claude/worktrees/agent-a7e55c484f5d14b45`) resolved to `6d4da8bb...`, an ancestor
commit that predated PR #379 (#363) and PR #382 (#364) both landing on the branch.
`git merge-base --is-ancestor` proved `6d4da8bb` was an ancestor of, not equal to,
`origin/epic/utilitiescs-nullable-remediation-integration` (`dffadd5a...`). Branching
the child worktree from the stale local ref would have made the Phase-0 gate (checking
`UtilitiesCS/Extensions/WinFormsExtensions.cs` for `#nullable enable`, proving #363
Batch D's merge) fail even though the epic orchestrator's briefing correctly stated the
dependency was merged — the briefing named the right commit, but the local ref hadn't
caught up to it yet.

**Why:** agent worktrees are created once and their local branch refs are not
automatically kept current with `origin/*` as sibling epic-child PRs merge over the
life of the epic. A `git checkout -b <child-branch> <local-integration-branch-name>`
without a preceding `git fetch origin` silently branches from stale history.

**How to apply:** in any epic-child orchestration, before creating/resetting the child
worktree branch from the epic integration tip, run `git fetch origin` and use
`origin/<integration-branch>`'s resolved SHA (not the bare local branch name) as the
base. Cross-check with `git merge-base --is-ancestor <briefed-commit> origin/<branch>`
when the briefing names a specific commit SHA for a dependency, to confirm the local
checkout actually contains it before trusting a Phase-0 gate check performed against
local refs. See also [[epic-child-pr-gate-gotchas]] and
[[unplanned-epic-child-worktree-mechanics]].
16 changes: 9 additions & 7 deletions UtilitiesCS/Dialogs/ActionButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Windows.Forms;
using UtilitiesCS.Dialogs;

#nullable enable

namespace UtilitiesCS
{
public class ActionButton
Expand Down Expand Up @@ -91,10 +93,10 @@ Button template
Button = MakeButton(buttonText, buttonImage, dialogResult);
}

private string _name;
private Button _button;
private string? _name;
private Button? _button;
private Button _template = new DelegateButtonTemplate().Button1; //.Clone();
private Action _action;
private Action? _action;

public static ActionButton FromButton(
Button button,
Expand All @@ -112,13 +114,13 @@ Action action

public string Name
{
get => _name;
get => _name!;
set => _name = value;
}

public Button Button
{
get => _button;
get => _button!;
set
{
if (_button != null)
Expand All @@ -130,7 +132,7 @@ public Button Button

public Action Delegate
{
get => _action;
get => _action!;
set => _action = value;
}

Expand Down Expand Up @@ -180,7 +182,7 @@ private static void AddImageToButton(Image Image, ref Button button)

internal void Button_Click(object sender, EventArgs e)
{
_action.DynamicInvoke();
_action!.DynamicInvoke();
}
}
}
16 changes: 9 additions & 7 deletions UtilitiesCS/Dialogs/DelegateButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Windows.Forms;
using UtilitiesCS.Dialogs;

#nullable enable

namespace UtilitiesCS
{
public class DelegateButton
Expand Down Expand Up @@ -90,10 +92,10 @@ Button template
Button = MakeButton(buttonText, buttonImage, dialogResult);
}

private string _name;
private Button _button;
private string? _name;
private Button? _button;
private Button _template = new DelegateButtonTemplate().Button1.Clone();
private Delegate _delegate;
private Delegate? _delegate;

public static DelegateButton FromButton(
Button button,
Expand All @@ -111,13 +113,13 @@ Delegate @delegate

public string Name
{
get => _name;
get => _name!;
set => _name = value;
}

public Button Button
{
get => _button;
get => _button!;
set
{
if (_button != null)
Expand All @@ -129,7 +131,7 @@ public Button Button

public Delegate Delegate
{
get => _delegate;
get => _delegate!;
set => _delegate = value;
}

Expand Down Expand Up @@ -179,7 +181,7 @@ private static void AddImageToButton(Image Image, ref Button button)

internal void Button_Click(object sender, EventArgs e)
{
_delegate.DynamicInvoke();
_delegate!.DynamicInvoke();
}
}
}
2 changes: 2 additions & 0 deletions UtilitiesCS/Dialogs/DelegateButtonTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading.Tasks;
using System.Windows.Forms;

#nullable enable

namespace UtilitiesCS.Dialogs
{
public partial class DelegateButtonTemplate : Form
Expand Down
4 changes: 3 additions & 1 deletion UtilitiesCS/Dialogs/FolderNotFoundViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading.Tasks;
using System.Windows.Forms;

#nullable enable

namespace UtilitiesCS
{
public partial class FolderNotFoundViewer : Form
Expand All @@ -17,7 +19,7 @@ public FolderNotFoundViewer()
InitializeComponent();
}

public string FolderAction { get; set; }
public string? FolderAction { get; set; }

public string FolderName
{
Expand Down
24 changes: 13 additions & 11 deletions UtilitiesCS/Dialogs/FunctionButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading.Tasks;
using System.Windows.Forms;

#nullable enable

namespace UtilitiesCS.Dialogs
{
public class FunctionButton<T>
Expand Down Expand Up @@ -189,10 +191,10 @@ Button template
ButtonClickedAsync = function;
}

private string _name;
private Button _button;
private string? _name;
private Button? _button;
private Button _template = new DelegateButtonTemplate().Button1; //.Clone();
private Func<T> _function;
private Func<T>? _function;

public static FunctionButton<T> FromButton(
Button button,
Expand All @@ -210,13 +212,13 @@ Func<T> function

public string Name
{
get => _name;
get => _name!;
set => _name = value;
}

public Button Button
{
get => _button;
get => _button!;
[MethodImpl(MethodImplOptions.Synchronized)]
set
{
Expand Down Expand Up @@ -247,7 +249,7 @@ public Button Button

public Func<T> Delegate
{
get => _function;
get => _function!;
set => _function = value;
}

Expand Down Expand Up @@ -295,10 +297,10 @@ private static void AddImageToButton(Image Image, ref Button button)
button.TextImageRelation = TextImageRelation.ImageBeforeText;
}

private Func<T> _buttonClicked;
private Func<T>? _buttonClicked;
public Func<T> ButtonClicked
{
get => _buttonClicked;
get => _buttonClicked!;
[MethodImpl(MethodImplOptions.Synchronized)]
set
{
Expand All @@ -314,10 +316,10 @@ public Func<T> ButtonClicked
}
}

private Func<Task<T>> _buttonClickedAsync;
private Func<Task<T>>? _buttonClickedAsync;
public Func<Task<T>> ButtonClickedAsync
{
get => _buttonClickedAsync;
get => _buttonClickedAsync!;
set
{
if (_buttonClickedAsync is not null && _button is not null)
Expand All @@ -332,7 +334,7 @@ public Func<Task<T>> ButtonClickedAsync
}
}

public T Value { get; internal set; }
public T? Value { get; internal set; }

internal void Button_Click(object sender, EventArgs e)
{
Expand Down
4 changes: 3 additions & 1 deletion UtilitiesCS/Dialogs/InputBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Threading;
using System.Windows.Forms;

#nullable enable

namespace UtilitiesCS
{
/// <summary>
Expand Down Expand Up @@ -66,7 +68,7 @@ internal static Func<InputBoxViewer, DialogResult> DialogInvoker
/// Side Effects:
/// Disposes the viewer form before returning.
/// </summary>
public static string ShowDialog(
public static string? ShowDialog(
string Prompt,
string Title = "",
string DefaultResponse = ""
Expand Down
2 changes: 2 additions & 0 deletions UtilitiesCS/Dialogs/InputBoxViewer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Threading.Tasks;
using System.Windows.Forms;

#nullable enable

namespace UtilitiesCS
{
public partial class InputBoxViewer : Form
Expand Down
8 changes: 5 additions & 3 deletions UtilitiesCS/Dialogs/MyBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
using System.Windows.Forms;
using UtilitiesCS.Dialogs;

#nullable enable

namespace UtilitiesCS
{
public enum BoxIcon
Expand Down Expand Up @@ -90,7 +92,7 @@ IList<ActionButton> actionButtons
return result;
}

public static T ShowDialog<T>(
public static T? ShowDialog<T>(
MyBoxViewer viewer,
string Message,
string Title,
Expand Down Expand Up @@ -148,7 +150,7 @@ Dictionary<string, Action> actions
return ShowDialog(viewer, message, title, icon, actionButtons);
}

public static T ShowDialog<T>(
public static T? ShowDialog<T>(
string message,
string title,
BoxIcon icon,
Expand Down Expand Up @@ -236,7 +238,7 @@ MyBoxViewer _viewer
public class FunctionButtonGroup<T>
{
public List<FunctionButton<T>> FunctionButtons { get; set; } = [];
public T Result { get; set; }
public T? Result { get; set; }
}

internal static FunctionButtonGroup<T> ToFunctionButtonsAsync<T>(
Expand Down
4 changes: 3 additions & 1 deletion UtilitiesCS/Dialogs/MyBoxModeless.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using System.Diagnostics.CodeAnalysis;
using System.Windows.Forms;

#nullable enable

namespace UtilitiesCS.Dialogs
{
/// <summary>
Expand Down Expand Up @@ -65,7 +67,7 @@ internal static void ShowStoreLockupNotification(
Action disableSessionOnly,
Action disableForFutureSessions,
Action reenable,
Action<MyBoxViewer> showAction
Action<MyBoxViewer>? showAction
)
{
var viewer = new MyBoxViewer();
Expand Down
Loading