Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e50173e
docs(epic): author folder-tree-breadcrumb-redesign manifest
drmoisan Jul 17, 2026
ddc4fd8
docs(9101): prepare live folder-hierarchy provider feature (#350)
drmoisan Jul 17, 2026
205b5e0
chore(memory): record orchestrator-state validator flat-key + enum sc…
drmoisan Jul 17, 2026
72e1ad0
docs(349): prepare EfcViewer WebView2 breadcrumb feature (epic child …
drmoisan Jul 17, 2026
1fa2c85
docs(351): prepare quickfiler-breadcrumb-webview2 epic child (researc…
drmoisan Jul 17, 2026
58b1458
merge(epic): fan in folder-hierarchy-live-provider (#350) prepared child
drmoisan Jul 17, 2026
74493e8
merge(epic): fan in efcviewer-breadcrumb-webview2 (#349) prepared child
drmoisan Jul 17, 2026
90332b2
merge(epic): fan in quickfiler-breadcrumb-webview2 (#351) prepared child
drmoisan Jul 17, 2026
3d322cf
docs(epic): back-fill resolved issue numbers and add kickoff artifact
drmoisan Jul 17, 2026
158ccb8
feat(350): add live Outlook folder-hierarchy provider contract
drmoisan Jul 18, 2026
ad0e3da
docs(350): add feature-review audit artifacts (policy, code, feature)
drmoisan Jul 18, 2026
8e24269
Merge pull request #353 from drmoisan/feature/folder-hierarchy-live-p…
drmoisan Jul 18, 2026
be6f38d
feat(349): replace EfcViewer folder tree with WebView2 breadcrumb con…
drmoisan Jul 18, 2026
fece796
docs(349): add feature-review audit artifacts (policy, code, feature)
drmoisan Jul 18, 2026
5108fa8
Merge pull request #355 from drmoisan/feature/efcviewer-breadcrumb-we…
drmoisan Jul 18, 2026
219145e
docs(agent-memory): record collect_pr_context session-root write beha…
drmoisan Jul 18, 2026
e2b94b0
docs(351): capture Phase 0 policy-read, baseline toolchain, and 9101 …
drmoisan Jul 18, 2026
95e2b3e
docs(351): Phase 1 fail-before exception dossier and reproduction ana…
drmoisan Jul 18, 2026
4102eb3
test(351): reconcile merged 9101 contract (DIRECT-CONSUME) and pin pr…
drmoisan Jul 18, 2026
84180cf
feat(351): add host-neutral BreadcrumbStateModel and BreadcrumbRender…
drmoisan Jul 18, 2026
160ead6
feat(351): add breadcrumb bridge protocol, async message router, and …
drmoisan Jul 18, 2026
fabc641
feat(351): add WebView2 messenger seam, breadcrumb page resource, and…
drmoisan Jul 18, 2026
33ac6a3
feat(351): replace CboFolders with WebView2 breadcrumb in live ItemVi…
drmoisan Jul 18, 2026
fab4891
docs(351): Phase 6 structural-impossibility dossiers for runtime veri…
drmoisan Jul 18, 2026
756414b
test(351): close final QA loop — coverage-gap tests, JaCoCo gate arti…
drmoisan Jul 18, 2026
43354fb
docs(351): add feature-review audit artifacts (policy, code, feature)…
drmoisan Jul 18, 2026
8e4e896
fix(351): resolve cross-feature name collisions with #349 after rebas…
drmoisan Jul 18, 2026
cf1d21f
Merge pull request #356 from drmoisan/feature/quickfiler-breadcrumb-w…
drmoisan Jul 18, 2026
9f8e61d
docs(agent-memory): record parallel-epic-children name-collision patt…
drmoisan Jul 18, 2026
16671d6
Merge remote-tracking branch 'origin/main' into epic/folder-tree-brea…
drmoisan Jul 18, 2026
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
2 changes: 2 additions & 0 deletions .claude/agent-memory/atomic-executor/MEMORY.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Atomic Executor Memory Index

- [#349 breadcrumb WebView2 gotchas](project_349_breadcrumb_webview2_gotchas.md) — retyped Designer field breaks reflection-injected tests (inject a router instead); aggregate async d__ classes for >=90% proofs; QuickFiler.Test is Newtonsoft-free

- [VS18 build/test toolchain paths](project_vs18_build_toolchain_paths.md) — build with VS **18** full-framework msbuild.exe (not Core .dotnet-sdk, which dies on binary resx MSB3822); nuget.exe restore; MSYS_NO_PATHCONV; csharpier v1 subcommands; dotnet-coverage needs `--` separator
- [C# canonical coverage artifact conversion](project_csharp_canonical_coverage_artifact_conversion.md) — hook reads artifacts/csharp/coverage.xml as JaCoCo; convert feature Cobertura (dedup lines, per-package counters); first-party aggregate under-counts <85% because uninstrumented assemblies show 0% — defer repo-wide to PR CI per policy-audit §5.4, don't cherry-pick

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: 349-breadcrumb-webview2-gotchas
description: "#349 EfcViewer breadcrumb swap: retyped Designer field breaks reflection test injection; async-state-machine classes hide coverage gaps; QuickFiler.Test has no Newtonsoft"
metadata:
type: project
---

Three gotchas from executing #349 (EfcViewer TreeListView -> WebView2 breadcrumb), directly relevant to sibling epic child 9103 (QuickFiler breadcrumb, same epic):

1. Retyping the Designer `FolderListBox` field (TreeListView -> WebView2) compile-broke `EfcHomeControllerExecuteMovesTests`, which injected the removed private `_selectedNode` field via reflection. Fix: drive a REAL `BreadcrumbBridgeRouter` over `Mock<IBreadcrumbWebHost>` + `Mock<IFolderHierarchyProvider>` to a selected state (`BindRowsAsync` + `SelectFirstRow`) and inject `_router` instead.
2. Cobertura per-class rates hide async gaps: `BreadcrumbBridgeRouter` showed 91.6% at class level while its compiler-generated `<HandleLeafToggleAsync>d__` machine sat at 29%. Per-module >= 90% verification MUST aggregate the parent type plus its `<...>d__`/`<>c__DisplayClass` nested classes (line-level dedup). Scratchpad script pattern: fold `name -replace '\.<[^>]*>.*$'`.
3. QuickFiler.Test has NO Newtonsoft.Json reference (and must not gain one — Newtonsoft-consuming code lives only in UtilitiesCS). Router tests must assert on raw JSON payload strings (JSON-escape HTML fragments: `\` -> `\\`, `"` -> `\"`), not JObject.

**Why:** 9103 consumes the same 9101 provider surface (`FolderBreadcrumbSegment` with `Key`/`FolderPath`/`HasChildren`, key-based `GetAncestorChainAsync`/`GetImmediateSubfoldersAsync`, string-path bridge `ResolveLeafKeyAsync`) and will hit the same three traps.
**How to apply:** when a plan retargets a QuickFiler viewer's folder list to WebView2, pre-check reflection-based tests for removed private fields, aggregate nested-type coverage before claiming >= 90%, and keep bridge-JSON assertions Newtonsoft-free in QuickFiler.Test.
1 change: 1 addition & 0 deletions .claude/agent-memory/atomic-planner/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
- [#307 F2 ScoCollection deletion gate](project_307_f2_scocollection_deletion_gate.md) — full first-party ScoCollection/ScoStack reference set incl. tests beyond spec §7; ISubjectMapSco/IScoCollection F5 boundary; FS/Prompt seams live in ScoCollection.cs
- [#328 store-exclusion seams](project_328_store_exclusion_seams.md) — StoresWrapper(469)/TreeOfToDoItems(481) near 500-limit, ToDoEvents(594) pre-existing over-limit; new test .cs need csproj wiring; four inclusion surfaces lockstep; adopted persisted StoreWrapper.StoreId
- [C# coverage gate expects JaCoCo](project_csharp_coverage_gate_jacoco_format.md) — validate-feature-review-coverage.ps1 reads artifacts/csharp/coverage.xml as JaCoCo, not Cobertura; plan a conversion scoped to first-party
- [#351 QuickFiler breadcrumb plan seams](project_351_quickfiler_breadcrumb_plan_seams.md) — JSON code in UtilitiesCS only (QuickFiler lacks Newtonsoft); P2-T1 blocked-if-9101-absent; evidence/repro/ rejected; coordinator pattern
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: project-351-quickfiler-breadcrumb-plan-seams
description: "#351 plan (plan.2026-07-16T21-53.md) load-bearing decisions: JSON code must live in UtilitiesCS (QuickFiler has no Newtonsoft ref), P2-T1 blocked-if-9101-absent gate, evidence/repro/ rejected, coordinator pattern"
metadata:
type: project
---

Plan `docs/features/active/2026-07-16-quickfiler-breadcrumb-webview2-351/plan.2026-07-16T21-53.md` (8 phases, 52 tasks) encodes these non-obvious decisions; keep them stable across preflight revision loops:

- **JSON placement:** `Newtonsoft.Json` is referenced only by `UtilitiesCS.csproj` (13.0.4), NOT by `QuickFiler.csproj`. All bridge message serialization (`BreadcrumbBridgeMessages.cs`, router) lives in `UtilitiesCS/OutlookObjects/Folder/`; the QuickFiler-side `BreadcrumbBridgeCoordinator` handles raw JSON strings only (no-new-packages guardrail G2).
- **9101 gate:** P0-T8 records `9101-CONTRACT: PRESENT|ABSENT`; P2-T1 reconciles (`DIRECT-CONSUME` vs `ADAPTER-REQUIRED`) and halts BLOCKED if absent — the plan never re-implements the live Outlook query. P2-T2/T3 carry explicitly authorized skip branches tied to the P2-T1 decision (compatible with the no-SKIPPED rule).
- **Evidence override:** spec.md FR-5/AC-6 names `evidence/repro/` — rejected; repro goes to `evidence/regression-testing/`, post-fix to `evidence/qa-gates/`, with an `EVIDENCE_LOCATION_OVERRIDE_REJECTED:` line in the plan header. P1-T1 allows a fail-before exception dossier when live-host capture is impossible.
- **Testable layering:** host-neutral core in `UtilitiesCS/OutlookObjects/Folder/` (StateModel, RenderProjection, BridgeMessages, BridgeRouter, SelectionMap) mirroring `FolderTreeStateModel`; QuickFiler seams `IWebViewMessenger` + exempt `WebView2Messenger` + non-exempt `BreadcrumbBridgeCoordinator` (tested with Moq'd messenger). Legacy arrow fall-throughs preserved via `UnhandledArrow` event rerouted in `KeyboardHandler.cs:543-583` (reroute, not removal).

**Why:** these came from repo verification (csproj greps) and spec/guardrail reconciliation during planning; a revision loop that moves JSON code into QuickFiler or drops the P2-T1 gate would break G2/G6.

**How to apply:** when revising this plan after `PREFLIGHT: REVISIONS REQUIRED`, update the same file in place and re-verify these four decision points survive the delta. Related: [[evidence-path-normalization]], [[plan-validator-task-id-sequential-constraint]], [[project_legacy_csproj_explicit_compile_include]].
2 changes: 2 additions & 0 deletions .claude/agent-memory/orchestrator/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- [Remediation-plan em-dash required](remediation-plan-em-dash-required.md) — the plan validator rejects `### Phase N (continued) — <Title>`; only canonical `### Phase N — <Title>` passes
- [new_active_feature_folder date prefix](new-active-feature-folder-date-prefix.md) — standalone feature folders get the YYYY-MM-DD- prefix automatically; epic-child folders don't (git mv those)
- [orchestrator-state validator divergence](orchestrator-state-validator-divergence.md) — MCP orchestrator-state check is stricter than the real SubagentStop hook; conform to the canonical schema's remediation_loop shape
- [orchestrator-state flat keys + step-status enum](orchestrator-state-flat-keys-and-enum.md) — validator needs FLAT top-level variable keys (not nested under "variables") and enum step statuses (in_progress not in-progress); fable_policy "available" => C3->opus
- [C# analyzer packages.config quirks](csharp-analyzer-packages-config-quirks.md) — non-SDK analyzer wiring needs manual roslyn subfolder selection; SecurityCodeScan.VS2019 breaks Roslyn 5.6 via CS8032 (can't be silenced by editorconfig)
- [Whole-repo CI gate is not out-of-scope](whole-repo-ci-gate-not-out-of-scope.md) — a pre-existing repo-wide csharpier/lint failure blocks the PR's required check (AC6); fix it, don't defer it
- [Honor user's per-cycle folder layout](feedback_verify_flat_artifact_layout_after_executor.md) — #181 user committed a per-cycle folder layout (<ts>-remediation/, <ts>-audit/); follow it. Only revert UNDIRECTED agent relocations, not the user's own reorg
Expand Down Expand Up @@ -45,4 +46,5 @@
- [Verify subagent capability claims](feedback_verify_subagent_capability_claims.md) — never relay "agent type not registered" without checking .claude/agents frontmatter; demand verbatim error; blocked state, not silent fallback
- [Epic-child plan Phase 0 paths are stale](feedback_plan_phase0_paths_are_stale_in_epic_children.md) — epic-child plans cite the planning worktree's absolute paths for P0 policy reads; redirect the executor to the CURRENT worktree's files in the delegation prompt
- [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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ Evidence (epic child #324, folder-probability-plumbing, 2026-07-16): `gh pr crea

**Why:** an Agent-tool isolated worktree makes the agent's own cwd == the worktree, and hooks inherit that cwd. This differs from [[child-orchestrator-pr-hook-reads-session-root]], which applied when the session cwd was a *separately-created named* worktree distinct from the feature worktree (session cwd != feature worktree). Distinguish the two topologies before deciding whether to stage artifacts in the session root.

**How to apply:** in an Agent-tool isolated worktree, author the PR body/receipt and keep the child checkpoint in the agent worktree's `artifacts/` and do NOT copy them to the session root — copying `orchestrator-state.json` to the shared session root can clobber a concurrent sibling child's merge-gate checkpoint. Run `collect_pr_context` with `workspace_root` = the agent worktree. If a future run shows the hook reading the session root (e.g. `PR_CONTEXT_MISSING`/`ORCHESTRATOR_STATE_PREFLIGHT_FAILED` despite valid agent-worktree artifacts), only then stage into the session root.
**How to apply:** in an Agent-tool isolated worktree, author the PR body/receipt and keep the child checkpoint in the agent worktree's `artifacts/` and do NOT copy them to the session root — copying `orchestrator-state.json` to the shared session root can clobber a concurrent sibling child's merge-gate checkpoint. Run `collect_pr_context` with `workspace_root` = the agent worktree, but note (re-verified 2026-07-18, child #349/PR #355): even with that arg it WRITES `pr_context.*` to the SESSION ROOT while its JSON response claims agent-worktree paths; the head/base/merge-base refs are still resolved correctly by branch name. Copy `pr_context.summary.txt`/`.appendix.txt` into the agent worktree's `artifacts/` before authoring the receipt (whose `context_summary_path` points at the worktree copy). Other MCP tools (`resolve_execute_hard_lock_prompt`, `validate_orchestration_artifacts`) DO honor `workspace_root`; hard-lock target paths must be absolute or resolution fails. If a future run shows the hook reading the session root (e.g. `PR_CONTEXT_MISSING`/`ORCHESTRATOR_STATE_PREFLIGHT_FAILED` despite valid agent-worktree artifacts), only then stage into the session root.

Also confirmed this run: on an epic integration-based branch the Python validator (`scripts/dev_tools/*.py`) is absent, so `Test-PythonOrchestratorValidatorAvailable` returns false and the portable `OrchestratorStateCompletion.psm1` gate is authoritative at SubagentStop (base presence + model-routing existence only). The bundled MCP `require_complete` check is much stricter (full large-route pr_gate/ci_gate + promotion/research/planning receipts) and will FAIL for a prepared-epic child that resumes at execution — that divergence is expected and is NOT the real Stop gate. See [[orchestrator-state-validator-divergence]].
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: orchestrator-state-flat-keys-and-enum
description: The orchestrator-state MCP validator requires flat top-level variable keys and a specific step-status enum; nesting under "variables" or using "in-progress" fails
metadata:
type: feedback
---

The `validate_orchestration_artifacts` (artifact_type: orchestrator-state) MCP validator requires the
lifecycle variables as FLAT top-level keys, not nested under a `variables` object. Required top-level
keys: `objective`, `change_budget_estimate`, `path_selected`, `promotion-type`, `short-name`,
`relativeFile`, `long-name`, `issue-num`, `feature-folder`, `work-mode`, `plan-path`,
`completed_steps`, `next_step`, `last_updated`, `step5_status`..`step10_status`,
`delegation_receipts`, `blocked_reason`.

Valid `stepN_status` enum: `not-applicable`, `pending`, `delegated`, `verified`, `blocked`,
`not_started`, `in_progress`, `completed`. Note `in_progress` uses an UNDERSCORE; `in-progress`
(hyphen) is rejected. Valid `blocked_reason`: `none`, `spawn_agent_unavailable`,
`delegation_launch_failed`, `delegate_no_receipt`, `delegate_contract_incomplete`,
`validator_failed`, `user_requested_stop` (use `"none"`, not null, to be safe).

**Why:** On the folder-hierarchy-live-provider (#350) epic-child preparation run I first nested the
variables under `variables` and used `step6_status: "in-progress"`; the validator failed with
"Checkpoint missing required key: promotion-type ..." and "invalid step6_status". Authoritative
source is `extensions/drm-copilot/src/lib/validate/orchestrator-state-core.ts`
(`REQUIRED_STATE_KEYS`, `VALID_STEP_STATUS`, `VALID_BLOCKED_REASONS`) in the drm-copilot repo.

**How to apply:** In preparation-mode epic-child runs (and any orchestrator run), the checkpoint also
needs `complexity_assessments[]` + `model_routing_receipts[]` populated for every delegated agent to
pass `require_model_routing=true`. In this repo `config/orchestration-routing.json` has
`fable_policy: "available"`, so C3 -> opus for all agents (base `complexity_to_model` table, no clamp,
no overlay). See [[orchestrator-state-validator-divergence]] and [[pr-author-hook-blocks-gh-in-this-repo]].
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: parallel-epic-children-name-collisions
description: Parallel epic children can invent identical C# type names in the same shared namespace; collisions surface only at rebase — resolve by renaming YOUR types, rerun full toolchain, no re-review needed per epic directive
metadata:
type: project
---

Verified 2026-07-18 (epic folder-tree-breadcrumb-redesign, children #349/#351). Two siblings executing concurrently against the same integration base both created breadcrumb types in `UtilitiesCS.OutlookObjects.Folder`. Textual merge conflicts were confined to `.csproj` `<Compile Include>` blocks (union-resolve, keep both), but two SEMANTIC collisions appeared only at the post-sibling-merge rebase build: CS0101 (`BreadcrumbRow` defined by both) and CS0104 (`BreadcrumbBridgeRouter` ambiguous between `QuickFiler.Controllers` and `UtilitiesCS.OutlookObjects.Folder` in sibling test files importing both namespaces).

**Why:** epic planning did not assign type-name budgets/prefixes per child; both features independently coined natural names for the same domain. git cannot see same-name-new-file collisions across different paths.

**How to apply:**
- After a sibling merges first, rebase and expect the analyzer build to fail even when only csproj conflicts appeared; grep both branches' new type names in shared namespaces proactively (`git diff --name-only base..integration` vs your new files).
- Resolve by renaming YOUR OWN types (e.g. `BreadcrumbRow`->`BreadcrumbStateRow`, `BreadcrumbBridgeRouter`->`FolderBreadcrumbBridgeRouter` with git mv + csproj update), never editing sibling-owned merged files.
- Identifier-rename-only + full toolchain green in one pass counts as rebase conflict resolution under the epic directive ("rebase onto the updated integration tip and rerun the full toolchain before merging") — no feature-review re-run required; document it in the PR body and checkpoint.
- csharpier may need a re-format after renames (longer identifiers re-wrap lines).
- Also observed: `collect_pr_context` wrote pr_context.* INTO the agent worktree when `workspace_root` was the Agent-tool isolated worktree (cwd==worktree topology), consistent with [[agent-worktree-hooks-resolve-to-agent-cwd]] and contrasting [[collect-pr-context-lands-in-main-checkout]] (named-worktree topology).
2 changes: 2 additions & 0 deletions .claude/agent-memory/task-researcher/MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
- [legacy-scodictionary-removal-315](project_legacy_scodictionary_removal_315.md) — #315: DELETE SCODictionary_Tests(+Additional), RETARGET 3 SmartSerializable* test files, IScoDictionary interface safe to keep for F5 (2026-07-11)
- [lock-recursion-coverage-317](project_lock_recursion_coverage_317.md) — #317: deleted LockRecursionTests.cs is a restoration (F2-authored clean-base coverage F5 knowingly removed per WI-4), not new authoring; no git/shell tool this session (2026-07-11)
- [qfc-folder-tree-percentage-325](project_qfc_folder_tree_percentage_325.md) — #325 (epic child 9003): only 1 live viewer (ItemViewer) despite 9 dead CboFolders variants; owner-draw ComboBox + host-neutral TreeNode<T> seams; consumes 9001 probability contract (2026-07-15)
- [qfc-breadcrumb-webview2-351](project_qfc_breadcrumb_webview2_351.md) — #351 (epic 9103): 9101 provider ABSENT (code to assumed contract); JS<->.NET bridge greenfield (no WebMessageReceived anywhere); Theme.Rendering TODO = top percentage hypothesis (2026-07-16)
- [dependabot-net481-340](project_dependabot_net481_340.md) — #340: no packages.config package currently dropped net481; transitive-bump restraint is already Dependabot's NuGet default (cite security-updates docs, not a new config primitive); use semver-major ignore not fabricated version ceilings (2026-07-16)
- [folder-hierarchy-provider-350](project_folder_hierarchy_provider_350.md) — #350/epic 9101: reuse existing snapshot infra (IOutlookFolderTreeService.GetChildren + ParentKey walk), add IFolderHierarchyProvider facade + pure GetAncestorChain, no new COM seam; defer deleting BuildFromRows/Build to 9102/9103 (2026-07-16)
Loading
Loading