feat: IM-7 — Cluster A invite marker + optional/non-blocking closure#253
Merged
Conversation
Add a durable collaboratedAt?: number root field to ImprovementProject, set ONCE on the first invite (roster grows beyond the solo creator) at both ProjectsTabView onMembersChange set-sites and NEVER cleared on removal. Threads the existing component-stable now (no bare Date.now() in the testable path). Adds an isCollaborative(ip) = Boolean(ip.collaboratedAt) predicate that gates the Azure-only collaboration affordances. The patch type already permits the new optional root field, and the IMPROVEMENT_PROJECT_UPDATE reducers carry it through via ...patch — no action-union or IDB change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IPDetailTeamRail now gates the sign-off section behind isCollaborative(ip): solo projects (no collaboratedAt) hide it entirely — a solo investigation closes without sign-off. Sign-off is decoupled from the process owner and is never a hard gate to close: canApprove = pendingSignoff (no processOwner requirement), and the pending copy reads a generic 'Awaiting approval' rather than naming a gatekeeper. The approver identity is captured at the dispatch site: Azure ProjectsTabView resolves the acting user from project membership (actingApprover), falling back to a generic Reviewer ref — never the process owner. PWA wires no sign-off callbacks at all (Mode-1 solo, §9.2) and its nudge stub is removed. ProcessHub.processOwner is retained (independent uses). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…al (IM-7 §11 #6) Surface B (ControlHandoff.signoff + the CONTROL_HANDOFF_SIGNOFF action) had zero UI dispatch and duplicated the wired, canonical IP.signoff lifecycle. Atomic discriminated-union cascade in one coherent change so the tree never holds a broken union: - control.ts: drop ControlHandoff.signoff + its now-unused ImprovementProjectSignoff import. - controlHandoffActions.ts: drop the CONTROL_HANDOFF_SIGNOFF action arm, the 'signoff' key from the CONTROL_HANDOFF_UPDATE Omit, and the unused import. - applyAction.ts (azure + pwa): drop the CONTROL_HANDOFF_SIGNOFF reducer arms. - exhaustiveness.test.ts: drop the matching case so the assertNever switch stays exhaustive (proven: re-adding the stale case makes tsc error TS2678). - Read consumers App.tsx + Editor.tsx: re-point the closure checklist's trainingDelivered from the deleted handoff.signoff?.approvedBy to the handoff lifecycle (status === 'operational'); processOwnerAcknowledged already keys off status !== 'pending'. - control.test.ts + controlActions.test.ts + both applyAction.control.test.ts: drop the signoff fixtures/assertions. core tsc + both-app tsc clean. No IDB bump (non-indexed field removal). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ame, PWA solo flow, decision-log §11 #6 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…atedAt (IM-7 review) The team rail previously rendered the Signoff section whenever isCollaborative(ip) was true. After a PWA local invite stamps collaboratedAt the section would appear with a permanently-disabled "Request approval" button — the hidden-vs-disabled anti-pattern (§9.2 / feedback_hidden_vs_disabled_cta). New gating: isCollaborative(ip) && (!!onRequestSignoff || !!onApproveSignoff || !!onNudgeSignoff) - PWA wires none of the three callbacks → section absent even post-invite - Azure wires all three → section shows once collaborative (unchanged behaviour) Also: update IPDetailTeamRail "approved state" test to wire onApproveSignoff (the section now requires a callback to render), fix pwa-solo-investigation.md table and sequence diagram note to reflect the accurate predicate, and add a new PWA test asserting the section stays absent after collaboratedAt is stamped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ragments (IM-7 review) - product-overview.md: drop "Charter ceremony" (Project created from Home + invite); reframe sign-off as optional/out-of-band; add to decision-log IM-7 apply-phase list - ia-nav-model.md: "a Report the Sponsor signs off" → "Sponsor reviews (sign-off optional/out-of-band)" - personas/lead.md: Mermaid "Sponsor reviews + signs off" → "Sponsor reviews (out-of-band sign-off; Lead records)" - control.md: Mermaid node Rev[Sustainment review] → Rev[Control review] (code identifiers unchanged) - applyAction.control.test.ts (azure + pwa): drop "signs off," from it() description (handoff signoff was deleted in IM-7; the test no longer exercises it) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…e (IM-7 review) The team rail gates sign-off on collaboratedAt AND >=1 sign-off callback; the PWA wires none, so the section is always absent (even post-invite). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
IM-7 (spec §9 + §11 #6). Project = collaboration; closure is optional, non-blocking, hidden-solo.
What changed
ImprovementProject.collaboratedAt?— durable marker set once on first invite, never cleared (gates Azure collaboration surfaces; not a reversiblemembers.length>1). NewisCollaborative(ip)predicate.processOwner(any acting user approves).ProcessHub.processOwnerretained for its other uses.IP.signoffis canonical;ControlHandoff.signoff+CONTROL_HANDOFF_SIGNOFFdeleted (zero UI dispatch — dead scaffolding); the two read consumers re-pointed to handoffstatus/acknowledgedAt; exhaustive union preserved.member===sponsor, noapprove-*; Sponsor = identity label).flows/pwa-solo-investigation.md; decision-log §11 chore(deps-dev): bump vite-plugin-pwa from 0.21.2 to 1.2.0 #6.Verification
pr-ready-checkgreen (on the main-merged state).product-overview.mdde-gatekeeper + doc-terminology fragments. Core sound: exhaustive union holds, consumers re-pointed, marker set-once/never-cleared dual-tested.🤖 Generated with Claude Code