refactor(pmo-pert): 4-sheet output, PD-only effort, PMI-correct MR#7
Conversation
Foundation for the 4-sheet workbook refactor. The i18n module ships en/it label dicts and a t(lang, key, **fmt) accessor; config_compat backfills modern fields (pm/devops/alta uplift, calendar) on legacy JSON input and emits a single stderr warning so users know they're on the old format.
Replaces the legacy Resources (%-allocation) and Timeline (sequential Gantt) sheets with a single PD-based role × week matrix. Primary role per leaf is activity.resources[0]; phase weeks come from phase.start_week/end_week or fall back to a sequential layout sized by PERT duration. Cells flag overcommit (>5 PD/week per role) in red and warn (>=4.5 PD) in yellow.
… calendar duration - New rows: Tech PERT, PM Overhead, DevOps Overhead, Subtotal, Contingency, Fascia BASSA, Management Reserve, Fascia MEDIA, Fascia ALTA. MR is computed on the Fascia BASSA cell (Tech+Overhead+Contingency), no longer on Contingency alone (Issue #3, PMI PMBOK §4.3 compliant). - Calendar Duration is a single explicit number derived from config.calendar_total_weeks or phase start_week/end_week (Issue #2). Sequential-sum CI Duration block dropped. - Effort by Team computed from WBS primary role of each leaf in real PD, not as a %-allocation cross-ref to Resources (Issue #1). - Sensitivity Scenarios listed as text rows when provided in config. - Sheet name localized via i18n (Riepilogo in IT).
build() now accepts an optional wbs_info argument. When provided, the
Management Reserve cell uses the PMI PMBOK §4.3-compliant base:
=(WBS!H{total}*(1+pm_pct+devops_pct)+L{contingency_total})*mr_pct
When omitted (legacy callers/tests without WBS), the cell falls back to
the original =L{total}*pct formula. The pipeline (generate_excel.py) is
wired in the next batch to always pass wbs_info.
generate_excel.py now: - routes JSON through helpers.config_compat.normalize_config() (legacy warning + default backfill); - builds WBS, Resource Plan, Risks, Summary in that order; - passes wbs_info into wb_risks.build() so the MR formula picks up the PMI-compliant base. Risks sheet name is now localized (Rischi in IT). Summary cross-references the Risks sheet by its actual name (single-quoted when needed). The validate_template.py script and its tests accept the 4-sheet layout and both English / Italian sheet-name aliases.
SKILL.md, workflow.md, template-criteria.md, excel-schema.md updated to describe the 4-sheet layout (WBS, Resource Plan / Pianificazione Risorse, Risks / Rischi, Summary / Riepilogo) and the v2 JSON schema fields: pm_overhead_pct, devops_overhead_pct, alta_uplift_pct, calendar_total_weeks, phase.start_week/end_week, scenarios[]. Includes a migration example for legacy JSON, the PMI-correct MR formula, the primary-role convention (resources[0]), and Resource Plan capacity rules.
…ation - sample-input.json updated with v2 fields (pm/devops overhead, alta uplift, calendar_total_weeks, phase start_week/end_week, scenarios). - Scenarios 1-5 backfilled with v2 defaults and phase weeks; xlsx regenerated against the 4-sheet generator. - Scenario 6 (PA portal integration) added as an anonymized public- sector scenario in Italian (lang=it). Exercises overlapping phases, 20% MR on the PMI-correct base, PM/DevOps overhead, and the alta uplift band — the new capabilities together. - validation-summary.md rewritten to cover the 4-sheet layout and the five real-world issues that motivated the refactor.
…rate template - Delete scripts/helpers/wb_timeline.py and scripts/helpers/wb_resources.py along with their test modules. Both modules implemented sheets that the v2 refactor removed (Issue #1 — Resources held % presented as effort; Issue #4 — Timeline Gantt was sequential and misleading). - Regenerate assets/pert-template.xlsx by running the v2 generator on the updated sample-input.json so the bundled reference template matches the 4-sheet layout. - Test suite is green (135 tests) and the structural CI test suite passes. - End-to-end smoke: sample workbook opens with 4 sheets, Resource Plan totals are =SUM formulas over per-week PD numerics, Summary shows the Low/Medium/High bands plus Calendar Duration = 12 weeks.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7d31d29514
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| starts = [int(p["start_week"]) for p in phases if "start_week" in p] | ||
| ends = [int(p["end_week"]) for p in phases if "end_week" in p] | ||
| if starts and ends: | ||
| return max(ends) - min(starts) + 1 |
There was a problem hiding this comment.
Derive calendar duration from all phases
The starts/ends shortcut returns max(end)-min(start)+1 as soon as any phase has explicit weeks, which undercounts duration for mixed inputs where other phases omit start_week/end_week and are scheduled sequentially in the Resource Plan. In that case Summary can report a shorter calendar duration than the generated plan (e.g., one explicit phase W1–W2 plus one implicit 2-week phase still shows 2). This breaks the new calendar-duration metric and should fall back to rp_info["total_weeks"] unless every phase has explicit bounds.
Useful? React with 👍 / 👎.
Summary
Refactor of the
pmo-pert-estimateskill: the generated workbook is now a4-sheet PMI-compliant deliverable — WBS · Resource Plan
(Pianificazione Risorse) · Risks (Rischi) · Summary (Riepilogo) — with
PD as the single effort unit, correct Management Reserve base, native
PM/DevOps overhead, calendar-aware duration, and i18n-ready labels.
Why
Five issues observed in real-world usage drove the refactor:
meaningless Summary rollups (e.g. "Effort by Team = 2400" from
summing percentages).
Total PERT Durationsummed leaf durations sequentially →over-stated calendar duration by 2–3× when phases ran in parallel.
Contingency × pct, not(Tech + Overhead + Contingency) × pct→ violates PMI PMBOK §4.3.no real parallelism, misleading for clients.
them as fake WPs.
The 4-sheet layout, the new
Resource Plan(role × week PD matrix), andthe correct MR base resolve all five issues at the root.
Key changes
i18n.py(en/it labels),config_compat.py(legacyJSON detection + soft backfill with stderr warning),
wb_pianificazione_risorse.py(role × week PD matrix).wb_summary.py(Fascia BASSA/MEDIA/ALTA, calendarduration, effort by team via WBS primary role, sensitivity scenarios),
wb_risks.py(MR formula onWBS!H{total} × (1 + pm_pct + devops_pct) + Contingency).pm_overhead_pct,devops_overhead_pct,alta_uplift_pct,calendar_total_weeks,phase.start_week/end_week, top-levelscenarios[].wb_timeline.py,wb_resources.py, and their testmodules.
workbook with sensible defaults and a single stderr warning.
references/template-criteria.md rewritten for the 4-sheet layout.
anonymized
scenario-6-pa-portal-integration(Italian, 8 phases,parallel build/integrations, 20% MR) added.
assets/pert-template.xlsxregenerated from thev2
sample-input.json.Test plan
bash tests/ci/run-structural-tests.sh)python3 generate_excel.py --input examples/sample-input.json --output /tmp/x.xlsxproduces 4 sheets in canonical orderPianificazione Risorse,Rischi,Riepilogo)validate_template.pyaccepts the regenerated template (valid: true, no errors)#REF!errors.xlsxin Excel/LibreOffice and verify Resource Plan totals match WBS!H{total} (±1 PD)