Skip to content

chore(deps): bump @microsoft/teams-js from 2.49.0 to 2.50.0#4

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/microsoft/teams-js-2.50.0
Closed

chore(deps): bump @microsoft/teams-js from 2.49.0 to 2.50.0#4
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/npm_and_yarn/microsoft/teams-js-2.50.0

Conversation

@dependabot
Copy link
Copy Markdown
Contributor

@dependabot dependabot Bot commented on behalf of github Mar 14, 2026

Bumps @microsoft/teams-js from 2.49.0 to 2.50.0.

Release notes

Sourced from @​microsoft/teams-js's releases.

v2.50.0

2.50.0

Thu, 12 Mar 2026 20:51:32 GMT

Minor changes

  • Updated ExternalApp* capabilities to allow calls in sidePanel frame context.
Changelog

Sourced from @​microsoft/teams-js's changelog.

2.50.0

Thu, 12 Mar 2026 20:51:32 GMT

Minor changes

  • Updated ExternalApp* capabilities to allow calls in sidePanel frame context.
Commits

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code labels Mar 14, 2026
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 14, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mean-beoynd-lite-pwa Ready Ready Preview, Comment Mar 20, 2026 0:55am
variscout_website Ready Ready Preview, Comment Mar 20, 2026 0:55am

@dependabot dependabot Bot force-pushed the dependabot/npm_and_yarn/microsoft/teams-js-2.50.0 branch from 1026b6b to 325865f Compare March 14, 2026 07:29
@dependabot dependabot Bot force-pushed the dependabot/npm_and_yarn/microsoft/teams-js-2.50.0 branch from 325865f to 0612bf8 Compare March 17, 2026 17:19
jukka-matti added a commit that referenced this pull request Mar 19, 2026
Phase A — Consolidation:
- Create ai-journey-integration.md as the journey-organized AI entry point
- Merge ai-data-flow.md into ai-architecture.md (data flow, hook composition, mode transitions)
- Archive 4 files: ai-assisted-analysis, ai-experience-narrative, ai-data-flow, strategy brainstorm
- Add scope headers to ai-architecture, ai-context-engineering, aix-design-system
- Fix all cross-references across 20+ files, update architecture index and CLAUDE.md

Phase B — AI Collaborator Philosophy:
- ADR-027: evolve AI from narrator to collaborator (explain + suggest actions, analyst confirms)
- Reframe business-bible H8 from "narrator" to "collaborator", strengthen H9
- Update mental-model-hierarchy: AI modes with actionable suggestions, KB in SCOUT, close gap #4
- Add aix-design-system §2.8 Actionable Suggestion Pattern with governance rules
- Add ai-architecture collaborator capabilities (action callbacks, hypothesis seeding)
- Update evaluation: P1-5 implemented, add P1-8 through P1-11 collaborator items

Co-Authored-By: ruflo <ruv@ruv.net>
@dependabot dependabot Bot force-pushed the dependabot/npm_and_yarn/microsoft/teams-js-2.50.0 branch from 0612bf8 to a1cd63f Compare March 19, 2026 20:27
Bumps [@microsoft/teams-js](https://github.com/OfficeDev/microsoft-teams-library-js/tree/HEAD/packages/teams-js) from 2.49.0 to 2.50.0.
- [Release notes](https://github.com/OfficeDev/microsoft-teams-library-js/releases)
- [Changelog](https://github.com/OfficeDev/microsoft-teams-library-js/blob/v2.50.0/packages/teams-js/CHANGELOG.md)
- [Commits](https://github.com/OfficeDev/microsoft-teams-library-js/commits/v2.50.0/packages/teams-js)

---
updated-dependencies:
- dependency-name: "@microsoft/teams-js"
  dependency-version: 2.50.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@jukka-matti
Copy link
Copy Markdown
Owner

Applied this update directly on main in a consolidated dependency bump commit (all 13 Dependabot updates at once). Closing this PR.

@dependabot @github
Copy link
Copy Markdown
Contributor Author

dependabot Bot commented on behalf of github Mar 20, 2026

OK, I won't notify you again about this release, but will get in touch when a new version is available. If you'd rather skip all updates until the next major or minor version, let me know by commenting @dependabot ignore this major version or @dependabot ignore this minor version. You can also ignore all major, minor, or patch releases for a dependency by adding an ignore condition with the desired update_types to your config file.

If you change your mind, just re-open this PR and I'll resolve any conflicts on it.

@dependabot dependabot Bot deleted the dependabot/npm_and_yarn/microsoft/teams-js-2.50.0 branch March 20, 2026 12:56
jukka-matti added a commit that referenced this pull request Apr 18, 2026
…ector

Second deliverable from the FRAME umbrella (ADR-070). Adds the core-layer
primitives that the FRAME workspace UI (PR #4) will render and integrate:
schema, rule-table mode resolver, and map-vs-data gap detector. No UI yet —
pure domain code, fully unit-tested.

Changes:
- packages/core/src/frame/types.ts — ProcessMap schema (ProcessMapNode,
  ProcessMapTributary, ProcessMapHunch, ProcessMapLayout, ProcessMap with
  version=1), TributaryRole, plus the input/result shapes for the two
  engines (ModeInferenceInput, InferredMode, ModeInferenceResult with
  stable rule IDs; Gap, GapKind, GapSeverity, GapDetectorInput).
- packages/core/src/frame/modeInference.ts — pure inferMode() function
  replacing the keyword-heuristic mode guess in parser/detection.ts.
  Rule table in priority order: yamazumi.tripletPresent →
  defect.typeAndCount → defect.passFail → performance.threeOrMoreChannels
  → capability.outcomeSpecsAndSubgroups → standard.fallback. Each rule
  documented; result carries a human-readable reason + rulesSatisfied IDs
  so UI and telemetry can surface the "why."
- packages/core/src/frame/gapDetector.ts — pure detectGaps() function.
  Emits required gaps first (missing-cts, missing-spec-limits) then
  recommended gaps (missing-subgroup-axis, missing-time-axis,
  missing-ctq-at-step, step-without-tributaries). Step-scoped gaps walk
  in map `order` so UI can render them inline next to the right node.
- packages/core/src/frame/index.ts — barrel.
- packages/core/src/frame/__tests__/modeInference.test.ts — 16 tests
  covering each rule, priority ordering, and degenerate inputs.
- packages/core/src/frame/__tests__/gapDetector.test.ts — 14 tests
  covering required/recommended ordering, step-scoped walking, and
  mapless flows.
- packages/core/package.json — new sub-path export './frame' →
  './src/frame/index.ts' (alongside existing 18 sub-paths). Per core
  CLAUDE.md, sub-path exports are public API.
- packages/core/src/ai/types.ts — ProcessContext gains a single optional
  processMap?: ProcessMap field. Null for existing projects and mapless
  flows; populated by the FRAME workspace. No breaking changes to any
  existing consumer.

Tests: +36 core tests (2574 total, was 2538). pr-ready-check.sh green
(all packages' tests pass, lint clean, docs:check passes).

Base: main. Independent of PR #65 (samples) and PR #69 (capability
quick wins) — only touches @variscout/core. PR #4 (FRAME UI) will
depend on this.

Plan: .claude/plans/i-was-interviewing-greg-dynamic-umbrella.md
Spec: docs/superpowers/specs/2026-04-18-frame-process-map-design.md
ADR:  docs/07-decisions/adr-070-frame-workspace.md

Co-Authored-By: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request Apr 18, 2026
…ector (#70)

Second deliverable from the FRAME umbrella (ADR-070). Adds the core-layer
primitives that the FRAME workspace UI (PR #4) will render and integrate:
schema, rule-table mode resolver, and map-vs-data gap detector. No UI yet —
pure domain code, fully unit-tested.

Changes:
- packages/core/src/frame/types.ts — ProcessMap schema (ProcessMapNode,
  ProcessMapTributary, ProcessMapHunch, ProcessMapLayout, ProcessMap with
  version=1), TributaryRole, plus the input/result shapes for the two
  engines (ModeInferenceInput, InferredMode, ModeInferenceResult with
  stable rule IDs; Gap, GapKind, GapSeverity, GapDetectorInput).
- packages/core/src/frame/modeInference.ts — pure inferMode() function
  replacing the keyword-heuristic mode guess in parser/detection.ts.
  Rule table in priority order: yamazumi.tripletPresent →
  defect.typeAndCount → defect.passFail → performance.threeOrMoreChannels
  → capability.outcomeSpecsAndSubgroups → standard.fallback. Each rule
  documented; result carries a human-readable reason + rulesSatisfied IDs
  so UI and telemetry can surface the "why."
- packages/core/src/frame/gapDetector.ts — pure detectGaps() function.
  Emits required gaps first (missing-cts, missing-spec-limits) then
  recommended gaps (missing-subgroup-axis, missing-time-axis,
  missing-ctq-at-step, step-without-tributaries). Step-scoped gaps walk
  in map `order` so UI can render them inline next to the right node.
- packages/core/src/frame/index.ts — barrel.
- packages/core/src/frame/__tests__/modeInference.test.ts — 16 tests
  covering each rule, priority ordering, and degenerate inputs.
- packages/core/src/frame/__tests__/gapDetector.test.ts — 14 tests
  covering required/recommended ordering, step-scoped walking, and
  mapless flows.
- packages/core/package.json — new sub-path export './frame' →
  './src/frame/index.ts' (alongside existing 18 sub-paths). Per core
  CLAUDE.md, sub-path exports are public API.
- packages/core/src/ai/types.ts — ProcessContext gains a single optional
  processMap?: ProcessMap field. Null for existing projects and mapless
  flows; populated by the FRAME workspace. No breaking changes to any
  existing consumer.

Tests: +36 core tests (2574 total, was 2538). pr-ready-check.sh green
(all packages' tests pass, lint clean, docs:check passes).

Base: main. Independent of PR #65 (samples) and PR #69 (capability
quick wins) — only touches @variscout/core. PR #4 (FRAME UI) will
depend on this.

Plan: .claude/plans/i-was-interviewing-greg-dynamic-umbrella.md
Spec: docs/superpowers/specs/2026-04-18-frame-process-map-design.md
ADR:  docs/07-decisions/adr-070-frame-workspace.md

Co-authored-by: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request Apr 27, 2026
F-6 closes the Phase 6 acceptance gate. All 8 acceptance criteria covered:

- AC #1 visually confirmed in chrome — flipping investigation status to
  `resolved` renders the "Set up sustainment cadence" prompt in the editor
  (Coffee Moisture sample, vite at :5173).
- AC #1-#5 functionally covered by 78 component/page/service tests
  (SustainmentEditors, ProcessHubSustainmentRegion, ProcessHubFormat.sustainment,
  Dashboard.processHub, Editor.sustainment, blobClient).
- AC #5 also covered by 39 core sustainment tests (selectSustainmentBuckets +
  path constructors).
- AC #6 vacuously satisfied — no sustainment fields wired into AI context
  builders yet (consistent with spec open-question #4 deferring CoScout
  proactivity). No PII surface.
- AC #7 covered by 14 schema.v6 + sustainmentStorage migration tests.
- AC #8 confirmed: process-hubs/{hubId}/sustainment/... path constructors at
  packages/core/src/sustainment.ts:307-343, consumed by
  apps/azure/src/services/blobClient.ts:444-470.

Total deterministic verification: 153 tests across @variscout/core,
@variscout/azure-app components/pages/services. All green.

Index reconciliation in docs/superpowers/specs/index.md is intentionally
deferred — the file already carries unstaged operating-model workstream
edits that the user wants kept on a separate branch.

Deferred to a follow-up interactive walk (file as F-8 if regressions
surface): full Flow A configuration, Flow B-D execution (verdict logging,
drifting+escalate, handoff record), bucket-split visual rendering colors,
mobile/dark/fi locale spot checks, duplicate-render quirk visual
confirmation. Functional contract for all of these is covered by the 78
Phase 6 component/page tests.

Co-Authored-By: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request Apr 27, 2026
Sequenced TDD plan for Phase 2 V2 closure:
- PR #4: response-path routing (ResponsePathAction in core, actionToHref
  in azure, panel refactor with required actions contract, Dashboard
  wiring + telemetry)
- PR #5: evidence chip from findingCounts (linkFindingsToStateItems pure
  aggregator, chip render in panel, Azure consumer wires resolver +
  chip click)

Documents two pragmatic divergences from spec:
1. linkFindingsToStateItems takes findingsByInvestigationId Map (not
   flat Finding[]) since Finding has no direct investigationId field
2. EvidenceSheet full-list rendering deferred (Dashboard doesn't load
   findings hub-wide today); chip click navigates instead

Spec amended with implementation-plan back-link.

Co-Authored-By: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request Apr 27, 2026
* feat(core): add ResponsePathAction discriminated union + deriveResponsePathAction

Pure mapping from a state item's response-path to a domain action.
Exhaustive on ProcessStateResponsePath. Returns 'unsupported' for paths
with no current Azure surface (monitor → informational, MSA → planned).

Phase 2 V2 PR #4, Task 5.

Co-Authored-By: ruflo <ruv@ruv.net>

* test(core): add compile-time exhaustiveness guard for deriveResponsePathAction

Adds a @ts-expect-error test that fails to compile if a future
ProcessStateResponsePath variant is added without a matching case
in deriveResponsePathAction.

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(azure): add actionToHref URL adapter for ResponsePathAction

Thin Azure-side adapter mapping ResponsePathAction discriminated union
to URL strings. Single URL source — adding a new ResponsePathAction
variant in core triggers a TS build error here via the exhaustive
switch.

Phase 2 V2 PR #4, Task 7.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(azure): move processHubRoutes from routing/ to lib/

Honors apps/azure/CLAUDE.md FSD rule: 'Don't introduce new top-level
directories. Feature-Sliced Design: features/, hooks/, components/,
services/, auth/, db/, lib/.'

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(azure): add safeTrackEvent wrapper for no-PII telemetry events

Try/catch'd facade over App Insights trackEvent. Silently swallows
failures so telemetry can never block UX. Caller is responsible for
ADR-059 no-PII compliance in the payload (enum values, opaque IDs,
integers only).

Phase 2 V2 PR #4, Task 8.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(ui): require actions + evidence contracts on ProcessHubCurrentStatePanel

Refactors panel to take 3 required props (state, actions, evidence)
instead of 1 (state). State-item cards become clickable affordances when
the action is supported; 'monitor' and 'measurement-system-work' paths
render as 'Informational' / 'Planned' pills with no click affordance.

evidence contract is unused in this PR (passes through stubbed); PR #5
wires the chip count + click.

Per feedback_no_backcompat_clean_architecture memory: required props
by default. The Azure consumer (ProcessHubReviewPanel) is refactored
in the next subagent task to pass these contracts.

Adds keyboard activation (Enter/Space), aria-label, and tooltip text
on planned/informational cards.

8 existing tests rewired + 6 new action-behavior tests = 14 tests.

Phase 2 V2 PR #4, Tasks 9-10.

Co-Authored-By: ruflo <ruv@ruv.net>

* test(ui): add Space-key activation test + a11y TODO on title tooltip

Code-review followups for ProcessHubCurrentStatePanel:
- Add a Space-key keyboard activation test to mirror the Enter-key
  test (ARIA button convention).
- Document the title-attribute tooltip's accessibility limitation
  (touch unreachable, screen-reader unreliable per WCAG 1.3.3 / 4.1.2)
  as an inline TODO. Pill text already conveys the state visually;
  upgrade to a Tooltip primitive when the design system grows one.

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(azure): wire ProcessHubReviewPanel + Dashboard to ProcessHubCurrentStatePanel actions

ProcessHubReviewPanel now passes the required actions + evidence contracts
to the panel. Adds defaultInvestigationId memo (most-recent investigation
heuristic) and actionFor closure that calls deriveResponsePathAction.

Dashboard wires handleResponsePathAction with safeTrackEvent telemetry
(hubId/responsePath/lens/severity — no PII per ADR-059) and routes via
the existing onOpenProject callback.

evidence contract is stubbed in this PR (passes empty findingsFor +
no-op onChipClick); PR #5 wires the chip count + click.

Phase 2 V2 PR #4, Tasks 11-12.

Co-Authored-By: ruflo <ruv@ruv.net>

* fix(azure): pass real hubId to telemetry instead of investigation ID

ADR-059 forbids logging customer-meaningful identifiers. The previous
handler labeled an investigation ID as 'hubId' in the telemetry payload,
which is a real leak. Now ProcessHubReviewPanel passes rollup.hub.id
(an admin-assigned slug) explicitly to the Dashboard handler.

Also:
- Add safeTrackEvent to handleResponsePathAction useCallback deps
- Document the intentional empty-string defaultInvestigationId fallback

Phase 2 V2 PR #4, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(core): commit assertNever helper that powers exhaustive switches

The assertNever function was added to types.ts and exported from
index.ts as part of the ResponsePathAction work, but the types.ts
change was inadvertently left uncommitted while the export and its
consumers landed across several commits. Local tests passed because
the working directory had it; CI would have failed with an unresolved
export.

Phase 2 V2 PR #4, missing-commit recovery.

Co-Authored-By: ruflo <ruv@ruv.net>

---------

Co-authored-by: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request Apr 27, 2026
* feat(core): add linkFindingsToStateItems pure aggregator

Pure 2-input join: state items × findings (pre-grouped by investigation
ID). Caller provides a resolver implementing the per-item-type linkage
rules. Findings filtered to RELEVANT_FINDING_STATUSES (analyzed,
improving, resolved).

Phase 2 V2 PR #5, Tasks 1-3.

Co-Authored-By: ruflo <ruv@ruv.net>

* test(core): replace Math.random with sequential counter in processEvidence tests

Per packages/core/CLAUDE.md hard rule: never Math.random in tests. The
finding-ID factory now uses a module-scoped sequential counter for
deterministic test fixtures.

Phase 2 V2 PR #5, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(ui): add evidence chip to ProcessHubCurrentStatePanel state-item cards

Each state-item card now renders a small evidence chip in the lower-right
showing the count of linked findings (analyzed / improving / resolved).
Chip click fires evidence.onChipClick with the item + resolved findings;
event.stopPropagation prevents the card click from also firing.

Chip is independent of action support — Planned/Informational cards still
show evidence counts when present. Chip is omitted when findings is empty.

The evidence prop, previously stubbed in PR #4, is now wired through.
Azure consumer still passes a stub findingsFor (() => []), so the chip
won't render in the running app until the next subagent task wires
findingsFor to ProcessHubInvestigationMetadata.findingCounts.

5 new chip tests added (count display, singular/plural, empty omit,
click fires + stops propagation, renders on unsupported cards too).

Phase 2 V2 PR #5, Tasks 4-5.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(azure): wire evidence chip to findingCounts in ProcessHubReviewPanel

Replaces the PR #4 stub evidence contract with a real wiring:

- findingsFor: derives chip count from
  ProcessHubInvestigationMetadata.findingCounts (relevant statuses
  analyzed + improving + resolved). Returns synthetic Finding-shaped
  placeholder objects (only id surface) — chip uses .length.
- onChipClick: emits 'process_hub.evidence_chip_click' App Insights
  event with no-PII payload (hubId, responsePath, lens, evidenceCount)
  and navigates to the most-recent linked investigation via the
  existing onOpenInvestigation callback.

Pragmatic divergence from spec: Dashboard doesn't load full Finding[]
objects today. The EvidenceSheet with finding labels is deferred to a
follow-up PR — see plan PR #5 future work.

Phase 2 V2 PR #5, Task 6.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(azure): clarify ProcessHubReviewPanel evidence wiring shortcuts

Two reviewer-flagged comment additions:

1. The Finding[] cast in findingsFor is intentionally narrow — chip only
   reads .length. Adds a TODO referencing the follow-up EvidenceSheet PR
   that will introduce a Pick<Finding, 'id'> narrow type at the panel's
   evidence-contract boundary, removing the cast.

2. Documents the per-investigation item.investigationIds[0] navigation
   target — typically a single linked investigation, so most-recency is
   moot. Hub-aggregate items already fall back to the most-recent via
   defaultInvestigationId.

No code changes — comments only.

Phase 2 V2 PR #5, code-review followup.

Co-Authored-By: ruflo <ruv@ruv.net>

---------

Co-authored-by: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request May 9, 2026
… V1 PRs

- Add PR-RPS-1 SHIPPED entry to §1
- Replace items #1, #3, #4 (Charter/Sustainment/Handoff piecewise) with the
  unified RPS V1 PR-RPS-2 through PR-RPS-10 sequence
- F5's HubAction work now subsumed by PR-RPS-9 + PR-RPS-10 (note added)
- Resolve §5 "F5 timing" question (moot post-RPS V1)
- Add 3 new heuristics to §6 (step-back-for-system-design, drop-methodology-
  bridges, code-review-must-checkout-PR-branch)
- Add RPS V1 spec + plan as related/references

Co-Authored-By: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request May 14, 2026
…leanup workstream) (#166)

* fix(8f-followup): delete legacy variscout-wall-layout Dexie DB on init

Closes 8f followup HIGH #3 — pre-8f users carried an orphan IndexedDB
forever after the wallLayoutStore → canvasViewportStore shape change.
Mirror PwaHubRepository's legacy-DB cleanup pattern. Tightens the
existing test that lied about asserting deletion.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(8f-followup): migrate canvas UI strings to typed message catalogs

Closes 8f followup HIGH #5 — 47 hardcoded English strings across
SystemLevelView, CanvasLensPicker, MobileLevelPicker, NoFocalStepPrompt,
AuthorL3View, LocalMechanismView now route through MessageCatalog.
CANVAS_LENS_REGISTRY labels/descriptions translated at render time in
CanvasLensPicker via LENS_LABEL_KEY / LENS_DESC_KEY maps; the hooks
registry keeps English for non-UI consumers. Non-English locales receive
English placeholders pending a translation pass (TODO(i18n) comment).

Co-Authored-By: ruflo <ruv@ruv.net>

* fix(8f-followup): migrate Canvas empty-state to message catalog

Closes the i18n reviewer's flagged follow-up: Canvas/index.tsx:1042
rendered the lens registry's English label and a local
CANVAS_LEVEL_LABELS map as user-facing copy, bypassing i18n.

- Export LENS_LABEL_KEY from CanvasLensPicker for cross-component reuse
- Reuse canvas.mobile.{system,process,step} for level labels
- Add canvas.lensPicker.invalidAtLevel parameterized key (32 locales,
  English placeholder elsewhere per the catalog's translation pass plan)
- Drop CANVAS_LEVEL_LABELS + remove now-unused CANVAS_LENS_REGISTRY import

Co-Authored-By: ruflo <ruv@ruv.net>

* test(8f-followup): cover CanvasLensPicker lens × level predicate

Closes 8f followup LOW #20 — load-bearing CanvasLensPicker had no
dedicated test. 18 enabled/disabled cells (3 levels × 6 lenses) +
click-dispatch + aria-label assertions.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(8f-followup): refresh stale wallLayoutStore references in store comments

Closes 8f followup LOW #18 — viewStore.ts:140 + preferencesStore.ts:178
still mentioned wallLayoutStore in doc-strings after the PR1 rename to
canvasViewportStore.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(8f-followup): fix plan frontmatter category to allowed enum value

* refactor(8f-followup): extract getStepColumnAssignments to @variscout/core/frame

Closes 8f followup HIGH #2 — AuthorL3View's private focalStepColumns
helper duplicates business logic that should live in core/frame. The
helper now lives at packages/core/src/frame/stepColumns.ts with 6
unit tests; AuthorL3View imports it. Per ADR-074 amendment + ADR-081:
Canvas embeds owner-surface computation, doesn't re-derive.

Co-Authored-By: ruflo <ruv@ruv.net>

* fix(8f-followup): tie L1 specLimits to outcome's own measureSpecs entry

Closes 8f followup MEDIUM #8 — SystemLevelView trusted a flat specLimits
prop without ADR-073-anchored contract. Now accepts measureSpecs keyed by
column and derives from measureSpecs[map.ctsColumn] internally; old prop
renamed to specLimitsOverride (advisory/debug only, deprecated). Canvas
passes { [ctsColumn]: { usl, lsl, target, cpkTarget } } as measureSpecs.
Two regression tests assert the leak scenario: wrong-column measureSpecs
key produces '--' Cpk, not a silently wrong value.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(8f-followup): replace LocalMechanismView's focalStepColumns duplicate

Same ADR-074 amendment violation that PR2 fixed in AuthorL3View. The
private helper now delegates to getStepColumnAssignments from
@variscout/core/frame (introduced in the prior commit), flattening the
structured result into the string[] this view needs.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(8f-followup): resolve lens × level matrix gap via spec amend

Closes 8f followup HIGH #4 via AMEND path (not expand). Git blame shows
both `performance` and `yamazumi` lenses were introduced with
`enabled: false` AND registry descriptions explicitly labeling them as
"Future ... lens" — intentional V2 placeholders, not bugs. Spec §10 was
over-promised at original ship.

- Spec §10 matrix amended: 6 cells marked `(V2 — deferred; lens not
  enabled in V1)` instead of pretending they ship enabled
- V2 expansion path documented inline
- investigations.md entry marked RESOLVED 2026-05-13 with rationale

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): replace setViewportLevel throw with warn + no-op (4.4)

l3 without focalStepId now emits console.warn and returns the viewport
unchanged instead of throwing. fitToContent guards the same path.
Updated test asserts warn was called and state did not change.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(8f-followup): co-locate level math constants in core/canvas/viewport (4.7)

Move FIT_TO_CONTENT_ZOOM_BY_LEVEL from canvasViewportStore into
@variscout/core/canvas/viewport.ts and re-export it through the barrel.
Add LOD_SNAP_BOUNDARIES (L2_OVERVIEW_LOW=0.5, L2_DETAIL_HIGH=1.8) for
the upcoming snap-to-LOD feature. Single source of truth for level math.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): enforce 6px click-vs-drag deadband via clickDistance(6) (4.3)

Adds .clickDistance(6) to the d3-zoom behavior in useCanvasViewportInput.
Pointer moves ≤5px are treated as clicks; ≥6px as drags. Matches spec §6.3.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(8f-followup): delete dead worldToWallSvg + document CanvasViewport (4.5/4.6)

worldToWallSvg was an identity function with no callers outside its own test;
deleted function and test. CanvasViewport is used in Canvas/index.tsx — added
JSDoc comment explaining its role so the seam is documented.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): snap-to-LOD on wheel-stop via d3-zoom end handler (4.2)

Adds a 'end' listener to the zoom behavior. When the user releases the wheel
with zoom in [0.3, 0.5) or [1.8, 2.0), the viewport eases back to 0.5 or 1.8
respectively over 150ms. Exports snapTarget() for unit testing. LOD_SNAP_BOUNDARIES
lives in @variscout/core/canvas/viewport alongside LOD_THRESHOLDS.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): real LOD cross-fade + d3-transition snap (4.1/4.2 final)

LODSwitcher now renders both outgoing and incoming renderers in stacked
absolute divs during a 150ms window, then unmounts the outgoing. Uses
useState+useEffect+setTimeout — no external animation library needed.

useCanvasViewportInput snap-to-LOD uses d3-transition via
selection.transition().duration(150).call(zoomBehavior.transform, ...).
Adds d3-transition + @types/d3-transition to @variscout/hooks deps.

Tests: 4 LODSwitcher tests assert dual-render during transition and
single-render after 150ms via fake timers.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): per-Hub canvas viewport blob helpers in blobClient

Closes 8f followup HIGH #1 part 1/2 — adds loadBlobCanvasViewport +
saveBlobCanvasViewport mirroring the updateBlobEvidenceSnapshots
ETag-conditional pattern. Per ADR-081 §2 (Azure = IndexedDB + Blob sync
with ETag per ADR-079) and ADR-079.

Also adds getLocalViewportUpdatedAt to @variscout/stores so the Azure
lifecycle hook can compare timestamps without reading Dexie directly.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): wire Azure canvas viewport lifecycle to Blob sync

Closes 8f followup HIGH #1 part 2/2 — useCanvasViewportLifecycle (Azure)
now rehydrates from Blob after Dexie cache, debounced-persists to both
Dexie and Blob with ETag, and treats precondition-failed as last-write-
wins per spec §11 with App Insights telemetry on the conflict path.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): expose 4 remaining response-path CTAs at L3 column granularity

Closes 8f followup MEDIUM #9 — LocalMechanismView previously only
exposed Quick Action. Spec §5.3.a lists 5 CTAs at column-mechanism
granularity (Quick Action / Focused Investigation / IP / Sustainment /
Handoff). Threaded the 4 step-level callbacks already on CanvasProps
through to LocalMechanismView; per-column button row added with new
i18n keys (8 new MessageCatalog keys across 32 locale files). Parent
callbacks are step-only; column is visible only within the card row.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(8f-followup): mobile L3 without focalStepId navigates to step-list

Closes 8f followup MEDIUM #10 — MobileLevelPicker previously called
setLevel('l2') before setZoom(2.5) as an explicit l2 redirect comment
implied. The final committed state was already l3 (setZoom(2.5) fires
inferLevel→l3), but the intent was undocumented. Updated comment to
clarify the atomicity: both calls run synchronously before React
re-renders, so the final state is l3 with no focalStepId, and canvas
renders NoFocalStepPrompt (the step-list surface) per spec §7.

Co-Authored-By: ruflo <ruv@ruv.net>

* perf(8f-followup): selector-scope canvasViewport subscribe in d3-zoom hook

Closes 8f followup MEDIUM #11 — useCanvasViewportInput previously
subscribed to the whole canvasViewportStore; every unrelated mutation
(setRailOpen, setViewMode, openChartCluster, etc.) fired
syncElementToStoreViewport (which has its own diff-check guard, but
still did needless work). Now tracks prevViewportRef and short-circuits
on reference equality of state.viewports[hubId] — sync is skipped
entirely when the hub's viewport slice hasn't changed. Test added:
setRailOpen → d3 element __zoom unchanged.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(8f-followup): rename canvasViewport STORE_LAYER to annotation-per-hub

Closes 8f followup LOW #15 — canvasViewportStore state is keyed by hubId
not projectId since the 8f shape change. The annotation-per-project
label was technically truthful (per-project umbrella, hub-keyed inside)
but invited confusion. Renamed to annotation-per-hub; layerBoundary
test + packages/stores/CLAUDE.md table updated. 'annotation-per-project'
is now in the reserved/unused set; 'annotation-per-hub' is live.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(8f-followup): mark 19 of 20 findings RESOLVED on followup branch

---------

Co-authored-by: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request May 14, 2026
… mismatches)

The beforeEach import fix in e73fca6 closes the responsesApi.test.ts
item from the deferred-tsc-errors entry. Adds item #4 capturing the
9 newly-surfaced SustainmentRecord + ProcessMap fixture-shape mismatches
that became visible once responsesApi.test.ts was unblocked.

Co-Authored-By: ruflo <ruv@ruv.net>
jukka-matti added a commit that referenced this pull request May 14, 2026
… Canvas decomposition + tsc hygiene (#168)

* fix(pwa): eliminate setState-in-render warning by replacing bare usePanelsStore() with individual field selectors

The bare `const store = usePanelsStore()` whole-store subscription in
`useAppPanels` violated the CLAUDE.md/ADR-078 "Never bare useStore()" rule.
In React 19 Strict Mode + Zustand 5 (useSyncExternalStore), the whole-store
snapshot causes tearing detection to fire on every panelsStore update
(panel-state transitions co-incident with LOD switches, frame-tab activation,
Lock canvas toggle), producing 8+ "Cannot update a component (AppMain) while
rendering" warnings per interaction.

Fix: rewrite useAppPanels.ts to use 24 individual usePanelsStore(s => s.field)
selectors — one per state field and action. useEffect dependency arrays cleaned
accordingly (no more `store` object in deps). App.tsx return interface unchanged.

Regression test added in apps/pwa/src/__tests__/App.test.tsx: mounts App,
exercises showFrame() panel transition, asserts zero setState-in-render warnings.
All 40 PWA test files green; pwa build green.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(investigations): add commit hash + correct rule attribution

Spec-review followup: add commit hash 6c5bc1a to the setState-in-render
resolution paragraph, and correct rule attribution from "CLAUDE.md / ADR-078"
to "packages/stores/CLAUDE.md:18 (cites ADR-041)" — ADR-078 covers the
6-stores-across-3-layers model, not selector discipline.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(pwa): extract openDataTableAtRow compound action + drop dead _vi import

Code-review followup: per feedback_fix_absorbed_violations_at_seam, lift the
two bare usePanelsStore.setState() calls in useAppPanels.openDataTableAtRow
into a single store-action openDataTableAtRow(index, isDesktop). Drops the
last bare-setState seam violation in the hook. Also removes a dead `vi as _vi`
import from App.test.tsx.

Co-Authored-By: ruflo <ruv@ruv.net>

* feat(cleanup): brand ProcessHubId opaque type + WallCanvas sentinel removal

Define `ProcessHubId = string & { readonly __brand: 'ProcessHubId' }` in
`packages/core/src/processHub.ts` (the only definition point). Add
`asProcessHubId()` (throws on empty) and `isProcessHubId()` predicate;
update `DEFAULT_PROCESS_HUB_ID` and `normalizeProcessHubId` to return
`ProcessHubId`. Re-export from stores for back-compat consumption.

Replace `hubId ?? '__wall-canvas-unbound__'` sentinel in WallCanvas with
`hubId ?? null`; update `useCanvasViewportInput` to accept `ProcessHubId | null`
with a null short-circuit (no store writes when hub is absent).

25-file sweep across packages/hooks/ui/apps: all `string`-typed hub slots
at store boundaries cast/narrowed to `ProcessHubId`; test fixtures use
`const h = (id: string) => id as ProcessHubId` helper. Both app lifecycle
hooks (PWA + Azure) use `normalizeProcessHubId(hubId)` → `boundHubId` so
the raw `string | null | undefined` param never reaches store calls.

Closes LOW #19 from the 8f retrospective (docs/investigations.md updated).

Co-Authored-By: ruflo <ruv@ruv.net>

* fix(cleanup): move h() cast helper after imports in mapwall test

Prettier placed the const between two import statements during the
pre-commit format pass. Move it after all imports to keep ES module
import grouping clean.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(stores): sweep ProcessHubId imports to @variscout/core

Removes the back-compat re-export shim at canvasViewportStore.ts:16 per
feedback_no_backcompat_clean_architecture; 7 consumers now import the
branded type directly from @variscout/core/processHub. Barrel index.ts
updated to re-export ProcessHubId from @variscout/core/processHub directly
(not via the store file) so existing code that happens to pull from the
barrel continues to compile.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(cleanup): finish ProcessHubId import sweep to @variscout/core

Sweep the remaining ~15 consumers missed by the earlier pass; barrel
shim removal exposed the gaps via TS error. All ProcessHubId imports
now go directly to @variscout/core/processHub.

Co-Authored-By: ruflo <ruv@ruv.net>

* test(core, hooks): cover asProcessHubId/isProcessHubId + useCanvasViewportInput null short-circuit

Two Important test gaps from PR2 code review: factory throw-on-empty
(asProcessHubId, isProcessHubId) and the new hubId:null no-op path in
useCanvasViewportInput. Both verify load-bearing contracts that were
shipped without exercise.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(canvas): extract useCanvasHypothesisDrawing hook

Moves all drawing-mode pointer/keyboard event handlers and the
reset effect out of Canvas/index.tsx into a dedicated hook. The
hook returns stable handler refs plus endpointLabel and
parseEndpointElement helpers — 12 vitest tests cover all branches.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(canvas): extract useCanvasHypothesisArrows hook

Moves arrowSegments state, cardElements ref, and both useLayoutEffects
(ResizeObserver setup + DOM measurement) out of Canvas/index.tsx into a
dedicated hook. Measurement is stable equality-guarded to avoid needless
re-renders. 8 vitest tests cover empty, ResizeObserver attach/detach, and
remeasure-on-viewport-change paths.

Co-Authored-By: ruflo <ruv@ruv.net>

* refactor(canvas): extract CanvasLevelRouter sub-component

Moves the lens-validity gate and all l1/l2/l3 content composition
out of Canvas/index.tsx into an internal sub-component. Canvas drops
from 1135 to 848 lines. CanvasAuthoringMode and CanvasL3Archetype are
defined in CanvasLevelRouter and re-exported from Canvas to avoid a
circular import. 10 vitest tests cover the routing, lens-invalid empty
state, archetype switching, and mode-toggle visibility. Barrel updates
and CanvasWorkspace.test.tsx mock additions for the two new hooks land
in this commit.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(types): add vite-env.d.ts + trivial tsc fixes in core/hooks (pre-existing)

Category A — add minimal ImportMeta.env / ImportMeta.glob augmentation .d.ts
files to packages/core/src/ and packages/hooks/src/ so that import.meta.env.DEV
and import.meta.glob(...) resolve without requiring vite as a direct dep.
Overloaded signatures distinguish eager (→ T) from lazy (→ () => Promise<T>)
so calls into registerLocaleLoaders (which expects LocaleLoaderMap) type-check.

Category C — two trivial fixes:
  - packages/hooks/src/__tests__/setup.ts: cast (window as unknown as Record...)
    to satisfy TS2352 (neither type sufficiently overlaps).
  - packages/hooks/src/__tests__/findingSourceLensCapture.test.ts: add _filters
    param to the vi.fn mock that takes one argument; was inferred as 0-arg.
  - packages/hooks/src/__tests__/setup.ts: /// <reference types="vitest/globals" />
    so beforeEach is recognised by standalone tsc (globals:true is vitest-only).

All pre-existing; unrelated to PR1/PR2/PR3 logic.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(test): cast DataRow fixtures + log deferred tsc errors (pre-existing)

Category B — cast Record<string,unknown>[] test fixtures to DataRow[] at the
constant definition site so useParetoChartData and useYamazumiChartData calls
type-check without changing test behaviour:
  - packages/hooks/src/__tests__/timeLensWiring.test.ts: add DataRow import +
    cast PARETO_100 at buildParetoRows(100) assignment.
  - packages/hooks/src/__tests__/useYamazumiChartData.test.ts: add DataRow
    import + change EMPTY_DATA type annotation from Record<string,unknown>[] to
    DataRow[].

docs/investigations.md — new entry "Pre-existing tsc errors deferred from
PR #168" listing the 3 remaining items that are out of scope for a trivial-cast
pass: d3 type deps (useCanvasViewportInput.ts:2-4), tuple-mock fetch typing
(useHubCommentStream.test.ts:274-277), and beforeEach globals in
responsesApi.test.ts:862.

All pre-existing; unrelated to PR1/PR2/PR3 logic.

Co-Authored-By: ruflo <ruv@ruv.net>

* chore(test): import beforeEach in responsesApi.test.ts

One-line addendum to the pre-existing-tsc-error cleanup commit: the
responsesApi.test.ts file uses beforeEach at line 862 but the vitest
import on line 1 omits it. Same category as the other ImportMeta /
test-globals fixes in afd8c8b.

Co-Authored-By: ruflo <ruv@ruv.net>

* docs(investigations): close item #3 + log item #4 (core fixture-shape mismatches)

The beforeEach import fix in e73fca6 closes the responsesApi.test.ts
item from the deferred-tsc-errors entry. Adds item #4 capturing the
9 newly-surfaced SustainmentRecord + ProcessMap fixture-shape mismatches
that became visible once responsesApi.test.ts was unblocked.

Co-Authored-By: ruflo <ruv@ruv.net>

---------

Co-authored-by: ruflo <ruv@ruv.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file javascript Pull requests that update javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant