AMIGO PlatformRisk Audit
AMIGO — Accelerate Your Implementations
Release NotesSeptember 12, 2026

AMIGO v2.32.0 Release Notes — Summer '26

IN THIS RELEASE

New Features

  • Cutover Plan dependency-driven rescheduling. Moving a Cutover Task's start date or changing its

duration now pushes its successors later, at every plan size. Plans up to 5,000 tasks reschedule live in the Gantt (push-later only: tasks keep a start-no-earlier-than floor at their planned start and are never pulled earlier; a typed start date sticks, with a Must-Start-On pin offered when the chain rejects it; finished and started tasks never move). Larger plans, collapsed groups the Gantt has not loaded, and very long chains are rescheduled by a new server-side pass at the end of every save (SchedulePropagationEngine + CtSchedulePropagationQueueableHelper), after which the Gantt refetches. The bulk-mode "manually scheduled" workaround and the engine's habit of pulling every successor earlier on open are gone. Save-path fixes ship with it: a save row that carries only an owner or a custom field no longer wipes a task's scheduling constraint, an engine date move and a custom-field edit on the same task are both kept, and large update payloads are written in batches.

  • Organization Configuration hub. The Organization record page now has a single Configuration

tab hosting a vertical-navigation panel (organizationConfigurationPanel) that clubs the three organization-level configuration areas in one place:

  • CFG Configuration (new cfgConfigurationGrid LWC + CFGConfigurationController) — all of the

organization's CFG Approval rows in one inline-editable grid: per-object RACI approval roles (Responsible / Accountable / Consulted / Informed), Auto Approval Days, and Remaining Days Email. Includes search-by-object filtering, client-side validation of the day ranges and the Remaining ≤ Auto rule with row-level errors, an "Add missing configurations" backfill for the organization, and a "View Details" row action that opens the CFG Approval record page (Historical Comments / attachments). The table is its own scroll region — pinned column header and pinned Save/Cancel bar, sized to the viewport. Saves route through CustomExceptionHelper.upsertOperationOrThrow, so real DML and validation-rule messages reach the toast.

  • Type Configuration (manageTypesPanel) — rebuilt onto the same lightning-card header

blueprint as the other two panes: the Portfolio picker moves inline into the header's right side (with the scope sentence as field-level help) instead of stacking as two full-width rows above the grid, so all three panes now share one look.

  • Calendar Configuration — the existing organizationCalendarManager, unchanged.
  • EVM Scoring Configuration (new evmScoringConfiguration LWC +

EVMScoringConfigurationController) — ProjectCondition_c and ProgramConditionc were a plain CPI/SPI verdict; they are now a weighted composite across eight dimensions (CPI, SPI, open Risks, Issues, Actions, Key Decisions, Change Requests, Defects), each reduced to a Red/Yellow/Green score and combined by organization-configurable weights that must total 100%. Weights, RAG thresholds and a CPI/SPI hard-trigger override live as one JSON blob on Organizationc.EVMScoringConfig_c — one field rather than a new object, matching the existing *AutoApprovalDays_c org-level config pattern — with packaged defaults when it's blank. Project and Program are scored independently, not as a rollup of each other; only the risk-count thresholds differ between the two levels. EVMScoringRecalcQueueable re-scores every Project and Program in the org when the weights change, and ProjectCostRollupHandler now re-scores a Project immediately after its cost rollup and costs every logged Time Tracking entry except Rejected or Recalled ones (previously Approved-only for Actual Cost, so it counted fewer hours than Actual Effort did).

Panes mount lazily on first visit and are kept alive when switching, so unsaved grid drafts, the portfolio picker, and calendar edit state survive pane switching.

Subscriber note: orgs with a customized (unpacked) Organization record page will not pick up the new tab automatically — add the Organization Configuration component to the page, or revert to the packaged AMIGOOrganizationRecord_Page.

Cutover Plan Governance: an Owner, a RACI Chart, and a Real Approval Process

The Cutover Plan was the container the whole cutover module hangs off, and it had no accountability model at all — no owner, no RACI, no approval. Every other governed AMIGO record has one. Now it does too, built on the same CFG Approval and RACI engine as Deliverables and Work Packages.

  • A Cutover Owner. A single named point of accountability on the plan. The Cutover Plan is a

master-detail child of Project and so has no standard Owner field — this lookup fills that gap. The owner is informational and notified; approvers still come from RACI.

  • RACI on the plan. An Add RACI action assigns Responsible, Accountable, Consulted and

Informed members. Assignments write an audit note to the plan's historical comment feed.

  • An approval lifecycle. The plan's Current Status is now In Process → In Approval →

Rejected: In Process → Approved / Auto Approved. The Approvals action checks that every RACI role your organization requires actually has someone in it, then submits one approval request per qualifying member. An Approvals tab on the record page shows the history.

  • An auto-approval countdown. Seeded from the organization's CFG Approval configuration for

Cutover Plan — which now appears in the CFG Configuration grid described above — and counted down nightly, with a reminder email to whoever has not yet acted. At zero the plan auto-approves.

  • Ready To Execute moved down to the task. The plan's status is now purely an approval

lifecycle; readiness is tracked per Cutover Task, where it belongs. Existing plans sitting on the old value keep working.

Setup note: Salesforce approval processes cannot ship inside a 2GP package, so each org creates the Cutover Plan approval process once. The step-by-step is in the Cutover Plan feature documentation, including two gotchas specific to this object — it has no record owner, and its sharing is inherited from the parent Project.

Cutover Task Execution: Block, Skip, Log a Defect, and Run the Plan on Auto Pilot

During a live cutover there was no way to record why a step stopped. Teams deactivated tasks to get past them, which erased the difference between "not ready yet" and "no longer needed". Four new actions fix that, and the plan can now be driven from the toolbar rather than task by task.

  • Mark as Blocked pauses a task and its immediate successors, records who blocked it and when,

and names the defect that explains it. Tasks further downstream are not restamped — they simply never become eligible while a predecessor is blocked. Unblock releases the task and the successors that block paused.

  • Skip bypasses a task without deactivating it: the task is marked 100% complete with a

timestamped "skipped per instructions" comment and execution moves on. Built for mock cutovers where a step isn't ready yet, and deliberately leaves the record and its reason auditable.

  • Create Defect logs a defect against the task, with an Is Blocker flag. Logging a defect

deliberately does not halt the runbook — only Mark as Blocked does. Not every defect found during a cutover warrants stopping it.

  • Start Cutover releases the first wave of the plan from the toolbar. A preview shows exactly

which tasks will move before anything happens, and eligibility is re-derived on the server rather than trusted from the browser.

  • Auto Pilot (configured from the Gantt) makes completing or skipping a task release its eligible

successors automatically and notify their owners. Switch it off and successors wait to be started by hand.

All four actions are restricted to the Cutover Owner, the Project Manager, the task's own Primary, Secondary or Tertiary Owner, or a System Administrator — enforced on the server, and the buttons are hidden from everyone else rather than failing on click. Each action raises its own email alert to the task owners, the Project Manager and the Cutover Owner.


The Project Plan Creates and Edits Work Packages Through the Work Package Modal

The Project Plan Gantt had the same problem the Cutover Plan fixes below: creating a Work Package went through Bryntum's own task editor, with a phantom row appended to the tree and a hand-rolled combo cascade for Deliverable and Type. The toolbar +, the pencil column and a new Edit Work Package context-menu item now open bryntumWorkPackageModal instead; Bryntum's taskEdit feature is off and the phantom-task listeners and cascade helpers are gone.

  • Deliverable and Work Package Type are lightning-record-pickers. Deliverable offers the

project's approved-for-work deliverables; Work Package Type is filtered by the chosen deliverable's Deliverable Type and clears itself when that changes. The Predecessor / Successor textareas are removed — dependencies are drawn on the Gantt.

  • New Work Packages are created by the modal, then the plan refetches and reloads. New is blocked

only while the store has unsaved edits (the plan's change set always carries a project aggregate entry, which no longer counts).

  • The post-create refetch was returning stale data. fetchTaskDataStreaming was cacheable, so

the reload after creating a Work Package came back from the client cache without the new row. It is no longer cacheable.

The modal itself has been cleaned up in the same pass. Its footer could show ten buttons at once, and two of its tabs were unfinished.

  • The status actions are one Actions menu. Defer, Out of Scope and Mark As Completed were

three peer buttons competing with Edit, Send For Approval, Approve, Reject and Close for footer width. They are now items in a single menu, each keeping its own status guard, and the menu is suppressed entirely when none of them apply — an approved Work Package shows no menu at all. Defer and Out of Scope ask for confirmation first: as buttons they carried visual weight, as menu rows they are one careless click from changing status and closing the modal.

  • RACI can be added without leaving the modal. The RACI tab was read-only, so adding a member

meant opening the record. It now offers Add RACI, which appears only on that tab — the same way Add Action Item and Add Defect Log already behave — and opens the Add RACI wizard described below. On save the modal refetches and stays on RACI rather than dropping back to Details.

  • The footer Close button is gone. The modal header already renders an X, so Close was a second

control doing the same job. The new-record cancellation signal that told the Gantt to roll back an abandoned draft used to live only on that button; it now lives on the modal's close path, so closing with the X or Escape rolls the draft row back exactly as before.

  • The Attachments tab works. It previously rendered nothing at all — the tab opened onto an

empty panel. It now lists each attached file with its type icon, size, uploader and date, and offers Preview, Download and Delete per file, with a confirmation before a delete. Files can be added with the upload button or by dropping them on it. Approved Work Packages get the list read-only, matching how the Action Item, Defect and narrative tabs already behave.


A Lightning New/Edit Form for Cutover Tasks

Creating and editing a task on the Cutover Plan Gantt went through Bryntum's own "Task information" dialog — a Bryntum widget, not a Lightning form. It had no record pickers, no lookup filters, no rich text, no field sets, and none of the AMIGO save conventions. It also showed an Effort spinner bound to a Bryntum-only field: CutoverTask_c has no Effort field, so that input never persisted anything.

It is replaced by a Lightning form (cutoverTaskDetailsForm) mounted in the Task Details tab of the Cutover Task modal. The pencil column, the task context menu and the toolbar + Create button all open it; Bryntum's editor is switched off entirely.

  • Task Details opens by default for both actions. New tasks get that tab alone — there is no

execution log, dependency chain or evidence on a record that does not exist yet — while editing an existing task keeps every tab, just landing on Task Details.

  • The fields: Cutover Task Name, Cutover Task Type, Parent Task, Planned Start and Finish, and

Duration with its unit, plus the Primary, Secondary and Tertiary Task Owners, the Cutover Task Procedure as rich text, and any customer-added amigo_set field-set fields — which until now had nowhere in the modal to be edited at all.

  • Owners and Parent Task use lightning-record-picker. The owner pickers are filtered to users

associated with the plan's Organization; Parent Task is limited to tasks in the same plan, cannot be the task itself, and a parent that is one of the task's own subtasks is refused rather than creating a loop the Gantt tree cannot render.

  • Start, Finish and Duration are interlocked. Editing Start or Duration recomputes Finish;

typing a Finish recomputes Duration in the current unit. A day is the working day from the plan's Calendar — 8 hours by default — so the form and the Gantt bar agree. A Finish before its Start blocks the save. Note the arithmetic is calendar-sized but not calendar-aware: it does not skip weekends or non-working hours, and Bryntum reconciles that when the plan reloads.

  • Save writes immediately. The task is created or updated on Save and the Gantt reloads — no

second trip to the toolbar Save button. Saves route through CustomExceptionHelper.upsertOperationOrThrow, so trigger messages reach the toast as real text.

  • Two rules made visible before the save rather than after. A name already used in the project is

flagged inline as you type, and a task with a duration but no Primary Task Owner warns that it will be saved as Not Plan Ready — which is what CutoverTaskTriggerHelper does, silently, today.

  • Cutover Task Sequence Number is not an input. The trigger assigns it, as it always has.

The Grid now goes through the same form. The same product action used to behave differently depending on which tab you were on: the Grid's pencil navigated to the standard Edit override — whose save and cancel both end on the Cutover Task record page, so you never came back to the plan and the Grid was left stale — and its Create button appended a phantom row for inline entry, the same pattern the Gantt just dropped. All three Grid entry points (View, Edit, New) now open the Cutover Task modal, and the Grid stays put and refetches in place. The CutoverTask_c New/Edit action override itself is untouched: the record page, the Cutover Task tab and list views keep the existing form, where navigating away is correct and the Organization → Portfolio → Program → Project → Plan picker is needed.


A Real Dependency Chain on the Cutover Task Screen

The Cutover Task modal's "Dependency Chain" tab was not a chain — it listed the immediate predecessors, the task, and the immediate successors, one hop in each direction. It now shows the full transitive trace, as a read-only Gantt with the same Backward / Both / Forward filter the Work Package modal has.

  • Hops are signed and sorted. Each row carries its distance from the focused task — -3

upstream, 0 at the task itself, +2 downstream — and rows run upstream, then the task, then downstream, so the line of descent reads top to bottom.

  • Backward answers "what has to finish before this can start", Forward answers "what does

this hold up if it slips", and Both shows the whole line. Switching between them re-filters what is already loaded rather than going back to the server.

  • The blocking callout stays. "N predecessors are not satisfied — this task cannot start yet"

sits above the diagram, and the tab still carries the blocking count. A structural chain shows shape; it does not answer whether the task can start, so both are on screen.

  • The chain is trimmed at 50 hops each way and says so — a cutover plan can be a single line of

a thousand tasks, and a thousand-row diagram is not a diagram.

Under the hood, getDependencyChain loads the plan in one query and walks it in memory. The Work Package equivalent runs one query per hop, which is fine for the short chains it was built for but would exhaust the query limit on the first real cutover plan. A regression test builds a 200-link chain and fails if the query count ever starts scaling with chain length.

Dependency editing is unchanged and still lives in the Cutover Plan Gantt. The tab is a viewer, matching the Work Package one.


Project Health & Metrics, and a Recalculate You Can Preview First

The Project Metrics tiles and a new EVM scorecard, built on the composite scoring above, are combined into one Project Health & Metrics card, with a Recalculate action that shows what a full recalculation would change before committing to it.

  • Recalculate previews, then applies. ProjectMetricsRecalcController.preview runs the

completion and cost rollups inside a savepoint that is always rolled back, so the modal can show every Field: Old → New the org's own formulas would produce with no risk to the data. Apply re-runs it for real and writes a Historical Comment naming exactly which fields changed.

  • Root causes, not just numbers. The preview also names why a value is off — Time Tracking

entries pending approval, approved hours with no Responsible RACI resource, hours with no Billing or Cost Rate covering the entry date, a stale-looking rollup — each with the specific User and Work Package it found, capped at five names with an "and N more" tail. A clean project gets one explicit "No issues found" line rather than an empty panel.

  • projectHealthCard renders Cost, Schedule and the overall Condition tiles colored by their

own RAG, backs them with the eight-dimension scorecard from the new EVM Scoring Configuration, and shows the CPI/SPI override note when it fired. Recalculate refreshes both the metrics tiles and this card in one action.

  • Amounts render in the record's own currency, not the viewing user's default — a USD project

no longer shows its numbers under an INR symbol in a multi-currency org.

  • Tile order changed: Planned % Complete now sits before Actual % Complete, and the

condition tiles moved into the health card, leaving one combined card instead of two.


A Full-Screen Project Page

Opening a Project now lands on a dedicated full-screen page, the same treatment the Cutover Plan gets below. The Project record page had grown into a stack of tabs around a Gantt that never had the room it needed; the plan is now the page, and everything else docks around it. A View action override (desktop and mobile) on Project__c mounts an Aura shell (projectFullScreen — Aura only because the Approvals, Add RACI and Clone quick actions are still Aura overlays) around projectFullScreenShell:

  • A single-row header (projectPlanHeader): project name, an Actual % Complete chip and the

Current Status pill, then a view switcher (Gantt, Taskboard or Resource Plan — Gantt by default, mirrored into ?c__view= so the address is shareable) leading the Details / Dashboard / Feed group, then Manage Deliverables, Add RACI and Approvals with a More menu holding Edit, Delete, Clone and Add Template.

  • Modals instead of tabs. Details opens the record's field sections behind a status chevron

(projectStatusPath, a Lightning Data Service port of the old DynamicCustomPath — a Rejected stage never renders as complete); Dashboard hosts the project chart components full-size; Feed hosts the activity feed; Manage Deliverables hosts the deliverable tree grid full-size. Delete confirms, deletes through LDS and returns to the list view.

  • The four viewers fill the shell. Project Plan, Task Board, Resource Utilization and the

deliverable grid gained an embeddedFullScreen mode that fills the shell's slot and hides their own full-screen buttons; the Project Plan's own full-screen button now targets this page. Saving completion on the Gantt refreshes the header's % chip.

The old AMIGOProjectRecord_Page flexipage stays packaged as a restore-only fallback.

Known gaps. The full-screen page does not yet surface everything the old record page's tabs did: Work Package Overview, Methodology Activity, Approval History, Other Related, Insights & Accelerators, the RACI related list and the historical comment overview are reachable only by restoring the flexipage for now.

Subscriber note: the AMIGO app carried 26 app- and profile-level View assignments that pointed Project__c at the old flexipage. They are reset in the packaged app (deployed as type=Default — a plain removal is ignored by the Metadata API), but an org that had customized any of them keeps its copy until it is cleared once in App Builder.


A Full-Screen Cutover Plan Page

Opening a Cutover Plan now lands on a dedicated full-screen page instead of the standard record flexipage — the same treatment the Time Report view already has. A View action override (desktop and mobile) on CutoverDeliverable_c mounts the new shell:

  • A 48px header with the plan name, its status pill, the Auto Pilot badge, live task-status

count chips, and the plan's actions — Approvals, Add RACI, Ready to Execute, Edit. Header data comes from Lightning Data Service; the page adds no new Apex.

  • A collapsible details strip (lightning-record-view-form) under the header, and a

Gantt ⇄ Grid toggle so both cutover views live on one page.

  • Docked side drawers for Approval History and the Feed, so acting on the plan and reading its

history no longer means leaving it.

  • Task deep links. ?ctaskId=<id>&ctaskMode=view|edit&c__view=gantt|grid opens a task's

execution screen straight from the URL — the link an execution-alert email can now carry — and opening a task from the plan mirrors it into the URL, so the address bar is always shareable.

The old flexipage stays packaged as a restore-only fallback.

Subscriber note: the app-level assignment that pointed the AMIGO app at the old flexipage is removed from the packaged app, but app-level action overrides merge on deploy rather than replace — an org that had the previous version keeps the stale assignment until it is removed once in App Builder. The step-by-step is in the Cutover Plan feature documentation.


Large Cutover Plans Load to Level 5 and Expand on Demand

A 13,500-task cutover plan (depth 8) used to arrive in one 15.8 MB payload that took the Apex side 4.6 s to build before the Gantt even started laying it out. Most of those rows sit below level 5 — on the reference plan 1,788 tasks are at levels 1-5 and 11,739 below — so the Gantt now ships only the top five levels and fetches a parent's subtree the moment it is expanded.

  • Depth cut. fetchCutoverPlanData / fetchCutoverPlanDataBulk take a maxDepth (the LWC

passes 5) and inline levels 1..5. A level-5 parent with children arrives as a Bryntum load-on-demand node (children: true, collapsed, lazyParent marker) spanning its stored planned dates. The reference plan's initial load dropped from 4.6 s / 15.8 MB to 1.35 s / 2.4 MB; the largest single expand is ~500 rows and returns in about 100 ms.

  • Expand on demand. A TaskStore subclass overrides Bryntum's loadChildren and calls the new

fetchCutoverSubtree, which returns up to five levels beneath the parent (a deeper plan is cut again at the next multiple of five) plus every dependency edge touching those rows, from both the Successor and Predecessor sides. Links whose other end is loaded are attached immediately; the rest resolve when their subtree loads. The attach is a load, not an edit: attached rows, resolved links and the engine's recomputed parent span are scrubbed from Bryntum's change tracking, so Save after an expand reports "No changes to save" and sends nothing.

  • Expansion survives a refetch. Every reload (Play, Ready to Execute, the Task Details form's

close-reconcile, refreshData) sends the expanded cut parents back as expandedParentIds; the server inlines those subtrees in one extra query so the tree reopens where the user left it.

  • Header chips are server counts. With part of the tree unloaded the old client-side tally

under-counted, so the full-screen header now reads getLeafStatusCounts (leaf tasks by status, total minus parents) on load and after every save, and moves a chip locally when a loaded task changes status in between.

  • Guards. Dropping rows onto, or indenting under, a parent whose children are not loaded is

refused with an "Expand first" toast; parent/leaf checks understand the load-on-demand marker.

  • Knobs. MAXINITIALDEPTH (5) and LAZYMINTASKS (0 = every plan; raise it to exempt small

plans) sit next to BULKLOADTHRESHOLD in bryuntumCutoverPlan.

  • Links into collapsed groups are visible and still gate execution. A dependency whose other

end is inside a group that is not loaded yet is not something Bryntum can hold (it prints an empty token per unresolved link, which is what first shipped as ;;;;;). Those links now stay out of the store and ride on the task instead: the Predecessors / Successors cells show the loaded links as before plus a muted "+N hidden" badge. Hovering it lists each hidden task with its status and the path to it — "in GroupSub-group" — and the group name is a link: clicking it loads and expands that collapsed group, scrolls to it, and the badge gives way to a normal link token. A far end the server cannot find any more is labelled Deleted task rather than shown as a raw Id, and the tooltip says so: a link to a deleted task still blocks Start until it is removed. The server sends a small farEnds map (name, status and parent of every task a loaded row links to but which is not in the payload) plus an ancestors map (the far ends' parents up to the first loaded row) so the Play gate still honours a hidden predecessor's status — an unknown status blocks, like the server's own eligibility check. Single-select Unlink on a task with hidden links asks for the expand first instead of removing only the visible half. The status column's dead-end ▲ no longer fires on collapsed parents or on tasks whose successors are hidden.

  • Milestones get View Details and Edit. The eye and pencil icons used to be hidden on every 0-day row,

a leftover from when zero duration meant a summary placeholder. They now show on any saved task, so a milestone's dependency chain can be inspected in the modal; only the execution icon stays duration-gated.

Known limits: the name filter and multi-select linking only see loaded rows (the search box says so on hover); a hidden predecessor's status is refreshed on the next reload or when its group loads; the Grid view still loads the whole plan. Calling the plan fetch without maxDepth (as the Grid does) is unchanged.

Add RACI as a Lightning Wizard

The Add RACI quick action has been an Aura component (RaciCharNewDesign) since AMIGO 1.x — one server call per role pool, a save that returned "Success" on swallowed failures, and no path to the newer LWC surfaces. It is rebuilt as an LWC wizard (addRaciWizard, with addRaciMultiSelectPicker and an addRaciWizardModal host) keeping the same five-step design — role pickers, clickable path, overview pills, change description — on a new AddRaciWizardController:

  • Two round trips instead of one per role. The controller resolves the RACI junction from

AmigoMetadataMapping, fetches the user pool once for every role, and saves through a single insert (with the trigger's has-run latch). Failures throw the real error to the toast.

  • All 26 Add-RACI objects are whitelisted in the controller, with pool modes that mirror the

legacy ReusableListController ladder exactly — Program's self-sentinel with org-keyed helpers, org-level-only pools for Business Process and Job Role, the extra org-level users for Cutover Plan, and the SensitiveData_c filter for Program Financial and the Benefits / Cost Tracking details. Enabling the wizard on any further object is now a quick action plus a layout entry.

  • Live on Stakeholder Group, Gate, Benefit and Job Role in this release, through a new quick

action on each. A released quick action's type cannot be flipped from Aura to LWC in place, so each of the four gets a new action and the legacy one is retired (Benefit's new action is AddRACIWizard, because Add_RACI was the name the Aura one already held). The other 22 objects keep the Aura action for now.

Benefit and Job Role are added to AmigoMetadataMapping's RACI and historical-comment maps together (the User Timeline dereferences the second unguarded once the first is present).


@Mentions in the Comment Editor

The Add a Comment box on the activity feed now supports mentions. Typing @ opens a keyboard-driven picker (a modal docked to the editor — the rich-text editor's closed shadow root means no caret access, so the picker cannot follow the cursor):

  • @username offers the people who belong to the record's organization, portfolio or program

user pool — not the whole org.

  • @record searches across the six mentionable AMIGO objects (the package's first SOSL search)

and inserts a link to the record.

Mentions are inserted as plain text while typing and rewritten to links when the comment posts. The link carries the object and record id, so a later notification fan-out can recover who was mentioned without any new field — no notification is wired up in this release.

Two long-standing feed bugs are fixed in the same component: the editor is now cleared after posting, and new feed items show their own timestamp instead of the page-load time.


Redesigned Emails: One Component Stack, Dark-Mode Safe

The shared email components are redesigned — solid-fill status pills, an inset record-context card with the teal accent, a left-aligned call-to-action — and, more importantly, made safe in dark-mode email clients: a shared dark-mode style block (prefers-color-scheme / data-ogsc) ships in AmigoEmailHeader, so every consuming template stays readable in Apple Mail and Outlook dark themes, and a new am-strong class keeps emphasised words from disappearing (templates that set near-black bold text inline vanished on the dark surface).

The consistency problem was never in the components, though — it was the 714 inline callout panels across the 91 templates, in five border colors, four paddings and three font sizes, plus the system-generated notice pasted into 65 of them. Two new global components close that gap:

  • AmigoEmailCallout — one panel, four tones (info / warn / danger / success), with a

sentence-case inline lead-in instead of an uppercase heading row.

  • AmigoEmailBody — a real table wrapper for body copy. Template bodies were bare <tr><td>

fragments outside any table, which email clients drop, so their padding and typography silently never applied.

A type-and-icon scale is now locked in the AmigoEmailHeader comment block and applied across all five components (the same "eyebrow" role had drifted to four different size/tracking combinations), and the system-generated notice moves into AmigoEmailFooter behind an opt-in systemNote attribute — off by default, because unmigrated templates still carry their own inline copy and would otherwise print it twice.

The six cutover templates are migrated onto the stack as the first consumers — including fixing two whose call-to-action linked the parent plan while the subject named the task, and collapsing three near-identical 60-line branches in the approval-reminder template into one. The remaining 85 templates still carry the previous inline markup and migrate incrementally in future releases.

The four Cutover Task templates (Authorized To Start for the PM and the owner, Execution Alert, Defect Logged) now deep-link into the full-screen Cutover Plan with the named task's modal already open, instead of the bare task record page. AmigoEmailContext gains an optional recordUrl attribute for that; left blank it falls back to the record-Id link, so every other template is unchanged.


Work Package and Test Plan Emails Open Inside the Plan

The cutover deep-link treatment now covers the other two plans. Every Work Package and Test Plan Detail email hyperlink opens the full-screen Project Plan or Test Plan with the record's modal already up, instead of dropping the reader on a bare record page with no sense of where the item sits, what blocks it, or what comes next.

The mode rides in the parameter name rather than a second query parameter, because a Visualforce email template double-escapes a literal & into &#38; and the # truncates the link — so an email-borne URL can carry exactly one parameter:

| Link | Opens | | ----------------------------------------------------------- | --------------------------------------- | | …/amigo1Projectc/<planId>/view?cwpId=<wpId> | the Work Package modal on its details | | …/amigo1Projectc/<planId>/view?cwpApprovalId=<wpId> | the Work Package modal on Approvals | | …/amigo1__Test_Planc/<planId>/view?ctpdId=<detailId> | the Test Component's execution screen |

Approval and auto-approval-countdown emails use the Approvals form, so an approver lands on the Approve / Reject buttons they were emailed about; assignment and Authorized-To-Start emails open the plain details form. The plan mirrors the open modal back into the address bar, so any state you reach by clicking is a shareable link.

Nine templates are retargeted (four Work Package, four Test Plan Detail, Test Results Approval), and each keeps a secondary direct link to the record itself through two new AmigoEmailFooter attributes, altLabel / altUrl. That fallback is not decorative: an org that pins the legacy record page over the full-screen View override, or a reader with access to the Work Package but not its parent Project, would otherwise land on the plan with no indication which record the email concerned — strictly worse than the old direct link.


Test Plan Notification Gaps Closed

An audit of Test Plan against Work Package turned up four workflow moments that notified nobody, or notified badly:

  • RACI assignment on a Test Plan or Test Plan Detail sent a blank email. SendEmailTo_RACI had

no branch for either object in its subject or in any of its four role sections, and RACIEmailTemplateHandler left the object name empty when checking notification preferences — which also meant the recipient's per-object notification settings were ignored. Both objects now have full Responsible / Accountable / Consulted / Informed sections, and the Test Component link deep-links into the plan.

  • The auto-approval countdown for Test Plan Details was silent. The object was already registered

with the approval SLA engine, so its countdown ticked down, but no reminder template was mapped and nothing was ever sent. A new Test Plan Detail: Remaining Approval Days template gives it the same reminder Work Package has had.

  • A component parked as Not Plan Ready told nobody. The new Test Plan Detail: Not Plan Ready

template goes to the Test Plan's Project Manager and its Accountable members — deliberately not the component's own RACI, since the absence of RACI is precisely why it parked — and names the blocking reason.

  • Next Component Assignment was packaged but sent by nothing. A component released by the Auto

Pilot successor cascade received the same "the plan has started" email as an initial release. The cascade is now distinguished from a first release, so the next tester in the chain gets a message that reads as their turn arriving.

TestPlanDetailReadyto_Execute had no caller either; it is marked superseded and its dead sender method removed.


Multi-Select Dependency Linking on the Project Plan and Test Plan

The Cutover Plan's multi-select Link action comes to the other two Bryntum plans. Select the rows to connect (shift-click or ctrl/cmd-click), then pick a shape from the new toolbar Link menu — also available from the right-click task menu:

  • Chain sequentially — each selected task becomes the predecessor of the next, in row order

(drawing links one at a time chained them in click order, which is why the built-in menu items stay disabled).

  • Start all after first — the first selected task fans out to every other one.
  • Converge to last — every selected task fans in to the last one.
  • Remove dependencies — with several rows selected, removes only the links between them; with

a single row selected, removes every link touching that task.

Pairs already linked in either direction are skipped and counted in the toast — the save path appends without duplicate detection, so the client-side guard is what keeps a re-chain from writing the same link twice. On the Test Plan, parent rows (scenarios and cases, whose dates derive from their children) are excluded from chains. Links are staged in the plan and persist on Save through the existing save pipeline — no new Apex.


The Project Plan Is Work Packages Only Again

The Action Item and Defect Log child rows nested under Work Packages are removed from the Project Plan Gantt. Nesting children under a WP turned it into a Bryntum summary row whose dates derive from the children — a Work Package stopped being a singleton task with its own start, duration and finish the moment an action item landed under it, silently reshaping the plan. The plan now renders a flat, WP-only task list; Action Items and Defect Logs keep their own home in the Deliverable tree grid, and their records and data are untouched — they just no longer render (or schedule) inside the Project Plan.

Because the drag-linking era allowed cross-type links, existing org data can hold Action Item / Defect Log ids inside a Work Package's Successors__c. All three dependency read paths (full, paginated, streaming) now filter successor ids by the Work Package key prefix, so legacy cross-type entries no longer produce dangling arrows — the filter is by id prefix rather than by membership in the loaded page, so links whose target arrives in a later pagination batch still draw.


A Gate Phase Management Tab on the Program

Gates had no home on the Program record page beyond a plain related list, which showed neither where a gate sat in the methodology nor how much of its metrics work was actually done. A new Gate Phase Management tab (gatePhaseManagementFromProgram) renders the Program's phases as a stepper — done, current or future, sourced from the Program's Multi Phases selection or, when that is blank, its Methodology's phases — with each phase expanding to the Gates in it as cards.

  • Each card is a live progress bar of approved actual results — metric rows in **Gate Metrics

Results Approved or Auto Approved** status, counted from the rows themselves rather than the Gate's own TotalNumberofActualResultsApproved_c, which is a plain incremental counter that undercounts (a gate with three approved metrics was storing 1) and can never be reconciled against the row count it should equal.

  • Clicking a card opens its details panel in place — description, Phase/Milestone pill, and

the embedded gateMetricesComponentForGate metrics grid — with Edit, Delete and Add Gate Metrics and Results actions. Delete asks for confirmation first and, on success, refreshes the phase list so the card disappears without a page reload. A Refresh button re-reads both the phase context and the open gate's details, since both Apex calls are cacheable and a re-render alone would replay stale results.

  • gateMetricesComponentForGate is now independently exposed (isExposed: true) so it can be

dropped on its own Lightning page rather than only reachable embedded here.

  • Submit Final Results and the RACI Chart button are present but inert on this surface — both open

Aura components (GateTakeAction, the RACI chart) that only an Aura host can raise, and the Program page has none; they work as before from the Gate's own record page.


Improvements

  • Notification Settings save failures are now surfaced. userNotificationSettingController.saveNotificationSetting

previously swallowed every exception around a partial-success Database.update, so a failed save showed the user a false "Success" toast while their toggles silently didn't stick. It now saves via CustomExceptionHelper.upsertOperationOrThrow (logs to ExceptionLog_e, throws the real DML error), and the userNotificationSetting component shows an error toast with the actual message.

  • Cutover progress is now tracked and rolled up. Cutover Tasks have a Percentage Complete, and

the Cutover Plan shows the rolled-up figure across its tasks. Completed and Skipped tasks both count as fully done — a skipped task was deliberately bypassed, not left outstanding — and zero-duration milestones are excluded so they don't dilute the number.

  • Dragging a progress bar in the Cutover Gantt now actually saves. The value had been read from

the browser since the Bryntum views were built, but never written to a field, so progress silently reset on reload.

  • Blocked and Skipped are visible at a glance in both the Gantt and the Grid — blocked tasks

render red, skipped tasks grey.

  • Every Bryntum toolbar is now an SLDS header strip. The Project, Portfolio, Program, Test and

Cutover Plans, the Cutover Grid, the Task Board, Resource Utilization and the Timesheet all drew their toolbars with Bryntum widgets — a different look from the rest of the app, unthemed by SLDS, and (see the Timesheet below) exposed to a platform regression. Each view now renders its header with lightning-* components: button groups for the actions, comboboxes for view presets and filters, a native search input, and the same badges and status pills as the full-screen pages. The toolbar action handlers are unchanged, so every existing action still dispatches the same way. The per-component toolbar config files (ganttToolbarConfig, ProjectPlanToolbar, TaskBoardToolbar, TimesheetToolbar, gridToolbarConfig) are deleted.

  • The Timesheet view survived a platform change. A Lightning Web Security update distorted

Range.insertNode, which Bryntum Calendar's toolbar-description path runs through mid-constructor: the timesheet painted but was dead, and the Add New Effort modal's mini day calendar crashed the same way. With the Bryntum toolbar gone, its SLDS header (actions, a Week | Overview mode toggle, and badges for status, hours, report scope and timezone) renders the "Week N, Month YYYY" description through the component's own text, so no string content flows through the crashing pipeline. The switch-to-sibling-month button now shows regardless of approval status: it is navigation only, so the approved half of a shared ISO week can still jump to its in-process sibling report.

  • The deliverable tree grid gets search and deliverable-level approvals. A search box in the card

header filters the whole tree — Deliverables, Work Packages, Action Items and Defect Logs — by name, keeping a match's ancestors visible; the filter survives Refresh and clears on add. An Approvals row action on Deliverable rows opens the approval modal in place, and rows are striped by approval status. Under the Aura-hosted full-screen Project page, Open Record and exit-fullscreen had stopped working: NavigationMixin.GenerateUrl resolves a record page to javascript:void(0) there and the Lightning CSP blocks it, so both now build the /lightning/r/…/view URL by hand. The row Actions column now surfaces its three highest-frequency actions — Open Record, Edit, Approvals — as their own colored icon buttons instead of hiding all of them behind one menu; everything else (adds, delete) stays in a More overflow with the same items the right-click menu shows.

  • **Work Packages, Action Items and Defect Logs can be reordered by drag on the Project Plan

Gantt.** A row drop only moves the record in Bryntum's tree — position isn't a persisted model field — so it never reached the save payload before; a drag is now captured on its own change channel and saved as a new tasks.reordered payload so RowNumber_c is written for every affected sibling without riding the field-edit channel, where any field missing from a row's payload is treated as "clear it." Nesting one Work Package under another via drop is blocked — WPs have no parent-WP relationship, so a nested drop would look applied and then vanish on reload.

  • Paging through someone else's Time Report no longer bounces you to your own. The week

navigator's fetchOrCreateTimeReportsForWeek looked up and created reports for the running user only, so an approver stepping through another user's weeks from the Time Report view was silently switched to their own timesheet. It now takes the Time Report on screen as context and stays within its owner; reports are still only ever created for the running user's own timesheet, so a foreign week with none shows "User has no Time Report for week N of YYYY" instead of a generic error.

  • Eight SLDS icon names that don't resolve in this org are replaced, found by auditing every

icon reference against the org's utility/standard/action/doctype/custom sprites: utility:piechartutility:donutchart (15 chart card headers), utility:stamputility:hourglass (My Approvals pending view), utility:historyutility:clock (billing View History), utility:forkutility:monthlyview (timesheet month-split marker), utility:libraryfolderutility:table, utility:sossessionutility:connectedapps, standard:bugstandard:incident, doctype:emaildoctype:attachment. Separately, every Gantt/timeline toggle across the five plan headers used utility:steps — a dotted-outline square, not a broken reference, but easy to mistake for one — swapped to utility:org_chart. No behavior change.

  • Cutover Task owner slots are now explicit end to end. The Gantt rendered all three owners

through a single unordered Bryntum assignment column, so the server had to flatten the set into the Primary / Secondary / Tertiary fields and compacted it on removal — clearing the Secondary owner promoted the Tertiary into that slot, and no server-side fix was possible because the slot the user meant never reached Apex. Each slot is now its own column, editing a single user through a type-ahead combo and rendering an avatar badge (photo, or color-coded initials). The Grid keys those columns on the User Id instead of the display name, so two AMIGO users with the same full name no longer collapse onto one unselectable entry. Fixed alongside, all in the Grid's save path: owners chosen on a brand-new row were silently discarded, every save wiped the task's scheduling constraint, and every save shifted the task's dates by the org's UTC offset. Owner editing now also works in bulk mode (plans over 5000 tasks), and the Bryntum editor's slot-unaware Resources tab is disabled so nothing can reintroduce the shift.

  • Rules and Requirements distinguishes rules from requirements. Choosing Business Rule in

the new/edit form now surfaces a Rule Type picklist (hidden again for Business Requirement), and the "Source of Requirement" field is relabeled "Source of Requirement/Rule" to match.


Under the Hood

  • Every remaining trigger now writes User Timeline through the generic engine. The last two

bespoke pipelines — GenericUserTimeline3 (2,488 → 224 lines) and ObjectMessaging (6,047 → 649 lines) — plus seven per-object TimeLineUpdate / SingleApprover classes are reduced to no-op stubs (signatures, @future annotations and the Hcom static kept so existing tests and AMIGOAPEXCLASS_PERMISSION entries still resolve); all 21 remaining triggers now route through GenericUserTimelineHelper.startRecordChangeCaptureGenericUserTimelineFuture, driven entirely by AmigoMetadataMapping. The legacy pipelines were not just redundant: all 21 assigned scalars inside a for (Trigger.new) loop, so a bulk update wrote timeline rows for the last record in the batch only, seven double-wrote, and every failure was swallowed into System.debug.

  • Two config extensions replace nine bespoke classes. RACIVIAFIELD on

objectRaciFieldApiMap() lets an object with no RACI of its own borrow a parent's (Change Request Log from its Change Review Board; the Data Mapping and Rules objects from their Work Package). objectNotifyFieldApiMap() maps a field API name to a role for objects whose recipients are named User lookups rather than RACI members, and is not gated by the CFG RACI checkboxes since these people hold no RACI role.

  • Configurable parent-level notificationNotifyParentProjectRACI_c,

NotifyParentProgramRACI_c and ParentNotificationRACITypes_c on CFGApprovals_c — replaces the hardcoded, undeduped Deliverable → Work Package fan-out that had produced 84 rows for a single Key Decision approval. Off by default; recipients are stamped "I am Informed" and a user already a direct RACI member gets no duplicate row.

  • Five defects fixed while migrating: RACI fan-out was gated on an email template existing,

so an object with no template entry silently produced one actor row instead of notifying every RACI member; a blank hierarchy Organization__c matched no CFG row and produced zero rows with no error (ten objects now read AssociatedOrganization_r.Name directly; Job Role and Benefit, which had no hierarchy entry at all, now do); startRecordChangeCapture threw on objects with no status field (Portfolio) rather than treating it as a field-only edit; the Historical Comment query was wrongly gated on RACI configuration, dropping WorkflowMessage_c for objects with no RACI lookup; and "Not Applicable" is now honoured for org/portfolio/program hierarchy values, not just project.

  • Expected behavior changes: Informed RACI members no longer get a timeline row where the

object's CFG "Informed" checkbox is off, and a bulk update now produces each record's own rows rather than only the last one processed.

  • The Project cost rollup and its condition re-scoring now run off the triggering transaction.

A single Time Tracking or Expense save used to charge ~32 SOQL queries (ProjectCostRollupHandler

  • EVMCompositeScoreService) plus up to nine further trigger cascades to whichever transaction

happened to save the timesheet. ProjectCostRollupQueueable chunks the affected Projects (20 per job, chaining as needed) and hands off to a new RecordConditionRecalcQueueable (10 Programs per job) once every Project is rolled up, so the six-object condition restatement that used to fire six more trigger stacks inline now runs on its own budget too. Queueable rather than Batchable because updating a Project or Program fires trigger logic that enqueues @future work, which cannot be called from a batch.

  • Removed the legacy CMDT-based notification-settings configuration. The

ObjectSetting_mdt and GroupSettings_mdt custom metadata types and all 178 of their records (which carried hardcoded internal developer usernames, including an email address that shipped to every subscriber org) are removed from the package. The toggles were never read by any notification-sending code, the records could not represent per-user preferences, and their save path (an Apex-driven metadata deployment against packaged records) cannot work in subscriber orgs. The live notification settings — the User picklist fields served by userNotificationSettingController and the userNotificationSetting utility-bar component — are unaffected. NotificationSettingsHelper remains in the package as a no-op stub: its only consumer, the emailNotificationTable LWC removed in 2.29, persists in subscriber orgs as a deprecation stub that still references its @AuraEnabled methods, and 2GP blocks deleting Apex that deprecated components depend on (the 2.29 upgrade-install failure). The unused MyCallback deploy-callback class is deleted outright.

  • The cutover execution cascade moved from JavaScript into Apex. Block, Skip and the Auto Pilot

successor release are routed from CutoverTaskTrigger on status transitions, so they behave identically whether the change comes from the Gantt, the Grid, the record page, the API or Data Loader. Before this, every cutover cascade lived in bryuntumCutoverPlan.js and the Grid had none at all, so the same edit produced different results depending on which view you were in. The Play/Complete path is still client-side and remains Gantt-only — reconciling it is a follow-up.

  • Fixed a non-deterministic email-template mix-up in the cutover task notifications.

CutoverTaskStartWorkImplementation.sendEmailToPMsAndRes selected its two templates with a WHERE DeveloperName IN :list query and then indexed the result positionally. SOQL does not guarantee ordering without ORDER BY, so the Project Manager and task-owner templates could be swapped, and an org missing either template threw a list-index error rather than skipping the send. Templates are now resolved by name. The same pattern is still present in WorkPackageReadyToExecuteImplementation and is not fixed in this release.

  • Cutover Plan and Cutover Task registered in the shared frameworks. The plan is now mapped in

AmigoMetadataMapping (CFG label, RACI junction, historical comments, hierarchy, approval status, reminder and status templates) and in AmigoApprovalSLARegistry, so it is served by the same generic approval, SLA-countdown and User Timeline engines as every other approvable object rather than by bespoke code. Cutover Plan RACI routes through RACIChartExtension__c because RACIChart_c has consumed 38 of its 40 relationship fields.

  • Bryntum upgraded from 7.0.0 to 7.3.5. All six bryntum_* static resources are replaced with

the 7.3.5 builds (the FontAwesome payload in bryntum_theme stays pruned to the css/webfonts subset the code loads). Three regressions the upgrade surfaced are fixed in the same change:

  • 7.3.5's widget factory registers a mixed-case type under both its given and lowercased names,

so the registry-derived column-type store threw "Id collision on wpType" and killed Gantt creation outright. The custom column types are now all-lowercase (wptype, statuscol), and column layouts saved under the old name are normalized on load so the restore doesn't add a duplicate column.

  • 7.3.5 renamed highContrastLight.css to high-contrast-light.css; the theme resource keeps

the stock filename and bryntumThemeService points at it, so future repackages from a stock Bryntum build no longer break the default theme.

  • The resourceassignment column's chip renderer dies on the same Lightning Web Security Range

distortion that hit the timesheet calendar, aborting rendering of every later row. All four consumers (project plan, test plan, dependency chain, deliverable workbench) now render the assigned resource names as plain text — the visible change is names instead of chips.

  • Three passes over manifest/package.xml removed members no longer in the package.

Technical Changes

New Custom Fields

  • CutoverDeliverable_cCutoverOwner_c, CutoverOwnerName__c, AutoPilot_c,

PercentageCompletec, approverc, AutoApprovalDays_c, RemainingDaysEmail__c, MergeCurrentStatus__c, RejectionFlag_c, and four hierarchy name formulas (OrganizationName_c, PortfolioName_c, ProgramName_c, ProjectName_c). The CurrentStatus_c value set is replaced with the approval lifecycle.

  • CutoverTask_cPercentageComplete_c, BlockedBy_c, BlockedDateTime__c,

BlockingDefect_c, SkippedBy_c, SkippedDateTime__c, plus Blocked and Skipped added to CurrentStatus_c.

  • DefectLog_cCutoverTask_c, IsBlocker_c, plus DefectLogCondition__c (the

EVM composite scoring RAG).

  • RACIChartExtension__cCutoverDeliverable_c.
  • EVM composite scoring RAG fieldsActionItemCondition__c,

ChangeRequestLogCondition_c, IssueLogCondition__c, KeyDecisionCondition__c and RiskRegisterCondition__c (alongside DefectLogConditionc above), one per scored RAID object, plus Organizationc.EVMScoringConfig__c — the org's weight/threshold JSON blob.

  • CFGApprovals_cNotifyParentProjectRACI_c, NotifyParentProgramRACI_c,

ParentNotificationRACITypes_c — opt-in parent-level RACI notification for the User Timeline engine.

New Apex

  • CutoverTaskStartWorkImplementation gains the execution engine: blockTask, unblockTask,

skipTask, blockSuccessors, readyToExecuteSuccessors, startCutoverPlan, getCutoverStartPreview, updateCutoverAutoPilot, sendExecutionAlert, canActOnTask.

  • CutoverDeliverableTriggerHelper gains the approval lifecycle: CFG seeding, terminal-status

derivation, per-RACI-member submission, auto-approve at zero days, and the rejection cascade.

  • AmigoCoreUtils.cutoverCompletionRollupHelper — the plan completion rollup.
  • DefectLogController.getDefectLogsForCutoverTask and getDeliverablesForProject.
  • AddCutoverTaskHelper.getCutoverTaskForPlanning — the Cutover Task read for the Gantt's Task

Details form, which needs the scheduling fields (Parent Task, the planned dates, duration and unit) that getCutoverTaskRecords deliberately does not select. Kept separate because the quick-action form writes back every field it reads.

  • CutoverTaskStartWorkImplementation.getDependencyChain — the transitive dependency chain for the

modal's Dependency Chain tab, with ChainTask and DependencyChainResult wrappers. Reuses the existing parseDependencyIds, so a free-text token that is not a Cutover Task Id is dropped rather than drawn as an edge to nothing.

  • CutoverGanttBryntumHelper.fetchCutoverSubtree — the subtree beneath one Cutover Task for the

Gantt's expand-on-demand, and getLeafStatusCounts — leaf-task counts by status for the full-screen header. fetchCutoverPlanData / fetchCutoverPlanDataBulk gain maxDepth and expandedParentIds; both keep loading the whole plan when called without them. Cut-mode and subtree payloads carry a farEnds map (name + status of linked tasks outside the payload, read in SYSTEM_MODE like predecessorStatuses, chunked WHERE Id IN).

  • AmigoMentionSearchController — the people and record search behind @mentions: people scoped to

the record's organization/portfolio/program user pool via UserAssociationHelper, records via the package's first SOSL search.

  • AddRaciWizardController — the LWC Add RACI wizard's backend: getWizardContext (junction, CFG

required roles, existing members and the user pool for all four roles in one call) and the single insert save. POOLSOURCEFIELDS whitelists all 26 Add-RACI objects.

  • CutoverGanttBryntumHelper.queryAncestors — walks each far end's parents up to the first loaded row

(one SOQL per hop, chunked, 30-hop cycle guard) and writes the ancestors map the "+N hidden" tooltip's drill path reads. farEnds entries gain parentId.

  • ProjectGanttBryntumHelper.fetchTaskDataStreaming is no longer cacheable=true.
  • TPDReadyToExecuteImplementation.sendNotPlanReadyEmail — notifies the Test Plan's Project Manager

and Accountable members when a component is parked as Not Plan Ready. Replaces sendReadyToExecuteEmailToRes, which had no callers. sendEmailToPMsAndRes now picks NextComponentAssignment for a component released by the Auto Pilot cascade and TestPlanDetailAuthorizedTo_Start for everything else, off a transaction-scoped marker set — deliberately not a second direct send from the cascade, which is how the Work Package equivalent ends up double-sending.

  • bryuntumProjectPlan.openWorkPackage({ recordId, mode }) and

bryuntumTestPlan.openDetail({ recordId }) — the deep-link entry points, routed through the same modal pipelines the action columns use. The Test Plan one queues until the Gantt exists, because the execution modal reads the task store to build its prev/next component list.

  • RACIEmailTemplateHandler recognises TestPlan_c and TestPlanDetails__c when resolving the

object name and subject.

  • AmigoApprovalSLARegistry registers amigo1__TestPlanDetails__c for pending-actor reminder

emails; AmigoMetadataMapping.slaReminderTemplateMap maps it to its new template.

  • RecordAttachmentControllergetFilesForRecord and deleteFile, the parent-agnostic version

of TestPlanBryntumHelper.getStepFiles / deleteStepFile, so any record surface can render a full attachment panel without Apex of its own. Two queries whatever the file count, and deleteFile confirms the ContentDocumentLink between the record and the document before deleting it — ContentDocumentLink cannot appear in a semi-join, so without that check any ContentDocument Id passed in would be deletable.

  • EVMCompositeScoreService — the eight-dimension weighted RAG engine behind

ProjectCondition_c / ProgramCondition_c, with explainProject / explainProgram scorecards and recalcRecordConditions for the six scored RAID objects. EVMScoringConfigurationController reads and saves the org's weight/threshold JSON; EVMScoringRecalcQueueable re-scores every Project and Program after a weight change.

  • ProjectCostRollupQueueable and RecordConditionRecalcQueueable — move the Project cost

rollup and its downstream condition restatement off the triggering Time Tracking/Expense transaction, chunking and chaining as needed.

  • ProjectHealthController — backs the projectHealthCard LWC, including getRecordCurrency

for rendering tile amounts in the Project/Program's own CurrencyIsoCode rather than the viewing user's default.

  • ProjectMetricsRecalcControllerpreview (rolled back in a savepoint) and apply for the

Project Health & Metrics card's Recalculate action, plus the root-cause analysis (pending Time Tracking, missing Responsible RACI, uncovered Billing/Cost Rate) written into the Historical Comment.

New Metadata

  • LWC recordAttachments — the shared attachment panel (upload, list, preview, download, delete)

behind the Work Package modal's Attachments tab. bryntumChildItemModal's Attachments tab is still an upload-only lightning-file-upload and can adopt this component unchanged.

  • LWC cutoverTaskDetailsForm — the Cutover Task new/edit form, with taskScheduleUtils for the

Start / Finish / Duration interlock.

  • LWC cutoverTaskDependencyChain — the read-only transitive dependency Gantt.
  • Quick actions CutoverDeliverable_c.AddRACI and CutoverDeliverable__c.Take_Action.
  • Email folders CutoverPlan and CutoverTask, with CutoverPlanEmail_Template,

CutoverPlanRemainingApprovalDays, CutoverTaskExecutionAlert and CutoverTaskDefectLogged.

  • Global value set additions: Cutover Plan in Approval_Objects, and

amigo1__CutoverDeliverable_c in AllowEmailNotification_Global.

  • Aura cutoverPlanFullScreen (shell only — the Aura layer exists because the TakeActionAll and

RaciCharNewDesign quick actions are Aura components) hosting the new LWCs cutoverPlanFullScreenShell, cutoverPlanHeader and cutoverPlanDrawer, plus the CutoverDeliverable_c View action override (desktop and mobile) that routes to it.

  • LWC amigoMentionPickerModal — the keyboard-driven mention picker, alongside the reworked

amigoMentionRichText comment editor.

  • Visualforce email components AmigoEmailBody and AmigoEmailCallout (global, alongside the

redesigned AmigoEmailHeader, AmigoEmailContext and AmigoEmailFooter).

  • Aura projectFullScreen (shell only — hosts the Aura Approvals, Add RACI and Clone quick-action

overlays) with the new LWCs projectFullScreenShell, projectPlanHeader, projectStatusPath, projectDetailsModal, projectDashboardModal, projectFeedModal, projectManageDeliverableModal and projectAddTemplateModal, plus the Project__c View action override (desktop and mobile) that routes to it.

  • LWCs addRaciWizard, addRaciMultiSelectPicker and addRaciWizardModal, with quick actions

StakeholderGroups_c.AddRACI, Gate_c.AddRACI, JobRole__c.AddRACI and Benefit_c.AddRACIWizard and their layout and record-page entries.

  • Email templates TestPlanDetail/TestPlanDetailRemainingApproval_Days (the auto-approval

countdown reminder the object never had) and TestPlanDetail/TestPlanDetailNotPlan_Ready.

  • AmigoEmailFooter attributes altLabel / altUrl — the secondary direct-record link behind a

plan deep link.

  • LWC evmScoringConfiguration — the EVM Scoring Configuration pane on the Organization

Configuration hub, wired in alongside CFG, Type and Calendar configuration.

  • LWCs projectHealthCard and projectMetricsRecalcModal — the Project Health scorecard and the

Recalculate preview/apply modal, both hosted inside projectMetrics.

  • LWC gatePhaseManagementFromProgram — the Program record page's new Gate Phase Management

tab, plus gateMetricesComponentForGate exposed for independent use on its own Lightning page.

Removed Metadata

  • The four legacy Aura RACI quick actionsBenefit__c.AddRACI, Gate_c.RACI_Chart,

JobRole_c.RACIChart and StakeholderGroups__c.Raci_Chart — are removed from the package now that each object has an LWC wizard action. Gate and Stakeholder Group had been showing both buttons since the wizard landed; the Gate record page in fact listed only the legacy one, so it gains the wizard here. Benefit's legacy button never worked at all — ControllerAddRaciFromLightning has no Benefit insert branch, so it saved nothing. The RaciCharNewDesign Aura component itself stays: 22 other quick actions and the three full-screen Aura shells still open it. Existing orgs are unaffected: on upgrade the four actions are marked deprecated in place, so any custom layout that references one keeps working; they simply stop shipping to fresh installs.

  • Bryntum's taskEdit feature on the Cutover Plan Gantt is disabled, and its configuration,

its beforeTaskEditShow / afterTaskEdit / beforeTaskSave listeners and the phantom-task create path are removed with it. The Grid's phantom-row create path and its navigate-away edit are removed in the same spirit — task create and edit now have exactly one entry point in both views.

  • Bryntum's taskEdit feature on the Project Plan Gantt is disabled, with its phantom-task

listeners and the Deliverable / Type combo cascade helpers; the Work Package modal is the one create/edit path. The nine Bryntum toolbar config files under the plan, grid, task-board and timesheet components are deleted with the SLDS header conversion.

  • The AMIGO app's 26 View assignments for Project__c are reset to type=Default in AMIGO.app

so the Project__c View action override reaches the full-screen page. AMIGOProjectRecord_Page stays packaged as a restore-only fallback.

  • The AMIGO app's flexipage assignment for Cutover Deliverable is removed from AMIGO.app in

favor of the View action override. App-level action overrides merge on deploy rather than replace, so upgraded orgs keep the stale assignment until it is removed once in App Builder — documented in the Cutover Plan feature docs. The flexipage itself stays packaged as a restore-only fallback.

  • PortfolioEvaluationRequest__c.BeldenRequested_c is removed from the package. The checkbox

was 2.28-era groundwork for the BELDEN AI evaluator, which ships from a separate extension package; no Apex, LWC, Aura, flow, layout, or automation ever read it, and no record had it set. Its AMIGOCOREFIELD_PERMISSIONS grant is removed with it.

Subscriber note: on upgrade from 2.31 or earlier the field becomes a deprecated stub — it is hidden rather than erased, and any stored values are retained. Extension packages that need a BELDEN opt-in flag must now supply their own field.

  • Project__c.ActualPercentCompleteKPI_c is removed from the package — an orphaned

Percent field nothing ever wrote to; projectMetrics already computed Actual % Complete from the effort-based rollup fields instead. Its AMIGOCOREFIELD_PERMISSIONS grant is removed with it.

Permission Set Updates

All new fields are granted in AMIGOCOREFIELD_PERMISSIONS and mirrored into the Organization, Portfolio and Program Level User profiles. The two Defect Log fields follow the Program Level User profile's existing posture, which grants no Defect Log access.

SHARE

◆ SEE IT LIVE

Run your transformation on AMIGO.

Schedule a demo