Repository navigation
v0.2.9 P4: land approved Implementation Note rev.3 (no code yet) - #29
Merged
Merged
Conversation
Per R014, approved design docs land on disk in the next turn. rev.3 ships the C0 pre-implementation audit step with the three-decision matrix (usable now / unavailable-degraded / conflict-with-PLAN), the .unknown taskPhase omission rule, and the post-merge housekeeping note keeping R011.a closeout off the P4 commit order. No code in this commit. C0 audit happens after this PR's CI green.
Audits the 8 §9 sources against current main read paths. Per rev.3
matrix:
- 6 sources usable now (time anchors, branch+cwd, related sessions,
project name, current phase, latest assistant progress).
- 2 sources unavailable/degraded — recent files (PLAN's
SessionDetail.recentFiles is async-only; bind degraded
SessionSummary.filesTouched count line) and recent tool ops
(PLAN's SessionSignals.toolsUsed is async-only with no sync
cache; omit category in P4).
- 0 sources conflict with PLAN — no PM escalation required.
Source 8 ("latest assistant progress") is a naming alias, not a
semantic conflict — bound to the sync-persisted SessionSummary.lastProgress.
C1 not started. Stops here for PM review of audit decisions.
Adds the v0.2.9 P4 evidence composition layer per the C0-audited
binding decisions in docs/PLAN-v0.2.9-P4.md:
Model (Models/EvidenceItem.swift):
- EvidenceCategory enum, 7 cases — recentToolOps intentionally not
in the enum (audit row 2; PM-ratified omission). The CaseIterable
invariant is asserted in tests so future re-introduction surfaces.
- EvidenceItem { category, title, lines: [String] }
- EvidencePackage (ordered, omits empty categories)
Composer (Services/EvidenceComposer.swift):
- Pure compose(session:relations:) -> EvidencePackage
- No I/O, no LLM, no async
- recentFiles degraded to "<N> 个文件被修改" count line (audit row 1)
- recentToolOps not produced (audit row 2)
- Time anchors include createdAt + lastActiveAt only; milestone
events deferred — including them would require extending the
signature with [MilestoneEntry], which rev.3 didn't sketch and
C1 stays on the literal signature
- Source 8 latestProgress cascades lastProgress -> currentTaskSummary
per PM ratify
Tests (Tests/XCTests/Services/EvidenceComposerTests.swift, 19 cases):
- Per-source emission rules
- Empty/zero/nil omission per category
- recentToolOps NOT in enum (CaseIterable assertion)
- .unknown taskPhase omission
- recentFiles degraded count
- latestProgress cascade (lastProgress wins, fallback to summary,
both empty omits)
- §9 ordering invariant on a fully-populated session
xcodeproj synced; 4-way verify green:
swift build, swift test 534/0, xcodebuild build, xcodebuild test 433/0.
No UI, no SessionStore wiring — that's C2.
… tests Adds the read-only evidence accessor on SessionStore that composes through the C1 pure EvidenceComposer: evidence(for ref: SessionRef) -> EvidencePackage Behavior: - Looks up the SessionSummary in sessions[] by ref. - Returns an empty package when the session is not found (e.g. archived/removed between scans). - Otherwise calls EvidenceComposer.compose(session:relations:) where relations come from the existing relations(for:) accessor — no new scanner, cache, or async path introduced. Tests (Tests/XCTests/Services/SessionStoreEvidenceTests.swift, 5 cases): - Unknown ref returns empty package, no crash. - Populated session via MockEvidenceProvider + performScan composes into the expected category set. - relations(for:) flow surfaces sameBranch relation in the relatedSessions category (two sessions on identical cwd+branch). - .unknown taskPhase omission still holds through the wiring path. - Degraded recentFiles count line still holds through the wiring path. xcodeproj synced. 4-way verify green: swift build, swift test 539/0, xcodebuild build, xcodebuild test 438/0. No UI — that's C3.
Adds the read-only structural evidence section per PLAN-v0.2.9.md §9 "rendered below the AI panel, expandable". EvidencePanel (Views/Sessions/EvidencePanel.swift): - Reads SessionStore.evidence(for:) — pure rule, no LLM, no async, no new fetching. - DisclosureGroup, collapsed by default. Empty packages render nothing (no chrome, no header) so unknown / brand-new sessions don't show an empty section. - Per-row layout: localized title + N value lines (lineLimit 2, middle truncation for long paths). - Accessibility identifiers per category for future UI tests. SessionTileView wiring: - Right column of expandedContent now stacks LLMPanelView above EvidencePanel. The frame still fills the column at infinity width so layout is unchanged when the evidence panel is empty. No new unit tests (UI behavior covered by C4 smoke). C1 + C2 already cover the data path; C3 only renders what compose+wiring produce. Known accepted UX duplication (not addressed in C3): - SessionTileView's left column already shows a "关联" relations list with "同分支" / "延续" labels. The new evidence panel will also show relatedSessions via `EvidenceCategory.relatedSessions`. C3 leaves both intact — removing the leftColumn version is a separate UI cleanup outside §9 scope. C4 smoke will confirm the visual cost is acceptable. xcodeproj synced. 4-way verify green: swift build, swift test 539/0, xcodebuild build, xcodebuild test 438/0.
C3 smoke surfaced a real product wart: the EvidencePanel was rendering 5 categories that are already shown at higher fidelity elsewhere in the same expanded tile (recentFiles in QuickFactsView; timeAnchors in the tile header; branchCwd / projectName in the metadata row; relatedSessions in leftColumn). Result was visually noisy duplication, not a smoke-stage cosmetic issue. C3.1 adds a view-level display policy without touching the canonical EvidenceComposer package: EvidencePanel.expandedTileFiltered(_:) -> EvidencePackage Drops the 5 duplicated categories on the way from store.evidence(for:) to render. Keeps .currentPhase and .latestProgress, which have no duplicate elsewhere in the expanded tile. If post-filter package is empty, EvidencePanel returns EmptyView (no header, no DisclosureGroup chrome) — the section disappears entirely on sessions with .unknown phase + empty progress. The composer's canonical 7-category package is unchanged, so future host views (a session inspector / detail pane) can apply a different filter or no filter at all without re-litigating the C0/C1 data model. Tests (Tests/XCTests/Services/EvidencePanelFilterTests.swift, 11 cases): - empty in → empty out - each of the 5 duplicated categories drops in isolation - .currentPhase and .latestProgress kept in isolation - full 7-category input → reduces to [currentPhase, latestProgress] - all-duplicate input → empty (panel hides) - §9 order preserved for kept categories C4 smoke checklist updated in docs/PLAN-v0.2.9-P4.md to focus on de-dup verification (no duplication with tile chrome) rather than the pre-C3.1 "categories populated" wording. xcodeproj synced. 4-way verify green: swift build, swift test 550/0, xcodebuild build, xcodebuild test 449/0.
Documents the post-C3.2 finding that P4 ships 7 evidence categories at the data layer but the expanded-tile UI surfaces at most 2 (currentPhase + latestProgress) after de-dup, with the other 5 as dormant infrastructure. Adds a "Known build/surface ratio risk" section to docs/PLAN-v0.2.9-P4.md capturing: - The 7 vs ≤ 2 layer-by-layer breakdown. - The downstream consumers that *might* materialize the dormant categories (P5 prompt input, P7 rationale, or a future detail/inspector surface). - The tracking item: re-evaluate at v0.2.9 GA / v0.3 kickoff. If P5/P7/new-surface don't consume them, prune dormant categories in a follow-up cleanup before they leak into v0.3. - A pointer to RULES.md R016 (UI-first phase note) — the rule that exists *because* of this ratio. P4 is grandfathered; P5/P6/P7 implementation notes will follow R016's UI-first 4-question framework. Docs-only. No code changes; no commit-order impact. C3.3 is a follow-up audit-trail commit on top of C3.1's de-dup, not a new phase.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Lands the approved P4 Implementation Note rev.3 on disk per R014, then progressively layers the evidence implementation: C0 audit → C1 composer + tests → C2 store accessor + wiring tests → C3 SwiftUI panel embed → C3.1 expanded-tile de-dup filter → C3.3 build/surface ratio audit (this commit).
Scope as merged
docs/PLAN-v0.2.9-P4.md(rev.3 + C0 audit table + build/surface ratio risk section).EvidenceItem/EvidenceCategory/EvidencePackage(7 categories;recentToolOpsintentionally not in enum per C0 audit row 2).EvidenceComposer.compose(session:relations:)with rev.3 audit-decision bindings (degradedfilesTouchedcount for source 1;lastProgress-then-currentTaskSummarycascade for source 8).SessionStore.evidence(for:) -> EvidencePackagethin wrapper over composer +relations(for:).EvidencePanelrendered belowLLMPanelViewin expanded tile, read-onlyDisclosureGroup, hides entirely when post-filter package is empty.EvidencePanel.expandedTileFiltered(_:)drops 5 categories already shown elsewhere in the expanded tile.Verification
swift build✓swift test✓ 550 / 0xcodebuild build✓ BUILD SUCCEEDEDxcodebuild test✓ 449 / 0, TEST SUCCEEDEDTest plan
expandedTileFilteredpolicy is the right host-context call (vs. moving filter into composer)Build vs surface ratio note
P4 implements 7 evidence categories at the data layer (
EvidenceComposer+ tests). In the expanded tile host context, C3.2 intentionally surfaces onlylatestProgress(andcurrentPhasewhen not.unknown) after de-dup; the other categories are dormant infrastructure pending P5 prompt input, P7 rationale, or a future detail / inspector surface.If those downstream uses do not materialize, dormant categories should be pruned instead of carried into v0.3.
Tracking item: re-evaluate at v0.2.9 GA / v0.3 kickoff. See
docs/PLAN-v0.2.9-P4.md§"Known build/surface ratio risk" for the full audit trail and the RULES.md R016 (UI-first phase note) link.