Skill: redkiwi1688-prog/construction-law (version 2.11.5)

--- name: construction-law description: "FIDIC (Red/Yellow/Silver), PSSCOC, SIA, and Singapore SOP Act toolkit. Generate notices, claims, EOT applications, and obligations registers. Computes statutory deadlines against eGazette-verified holiday data. Use when (1) analysing contract clauses, risk allocation, or obligations; (2) preparing or reviewing claims (delay, disruption, prolongation, EOT, loss & expense); (3) comparing contract forms or advising on procurement strategy; (4) drafting or reviewing notices, correspondence, or contract documents; (5) building obligations registers or notice calendars; (6) discussing dispute resolution (DAB/DAAB, adjudication, arbitration, mediation, CAB); (7) Singapore-specific construction law (SOP Act, BCA, SIArb); (8) MDB procurement frameworks (ADB, World Bank). NOT for: non-construction commercial contracts, pure property/real-estate conveyancing, or insurance law." --- # Construction Law: FIDIC, PSSCOC, SIA & Singapore SOP Act <!-- Remove v2.11.0 banner after 2026-08-17 --> > **⚠️ v2.11.0 users — action required if you computed non-SG deadlines.** > v2.11.0 shipped with bundled best-effort holiday data for AE, MY, and GB that was **not verified against authoritative sources**. If you ran the FIDIC Deadline Calculator against a non-SG seat using v2.11.0, **re-check those deadlines** against your jurisdiction’s official gazette. From v2.11.1 onward, only Singapore holidays are bundled (gazette-verified); other jurisdictions require `--holidays-file` with your own verified data. See the [FIDIC Deadline Calculator](#fidic-deadline-calculator) section for details. Analyze construction contracts, claims, notices, payment timelines, risk allocation, and dispute pathways across major standard forms, with strong international and Singapore-focused coverage. ## Why install this? - ✅ Avoid missed notice deadlines and time-bar mistakes - ✅ Structure claims and EOT submissions faster - ✅ Compare contract risk and obligations more consistently - ✅ Prompts for the correct contract form **and edition** before analysis ## Who this skill is for This skill is built for: - Construction lawyers - In-house counsel - Contract managers - Commercial managers - Quantity surveyors - Claims consultants - Project managers ## What this skill does Use this skill to: - Identify the correct contract form and edition before analysis - Review clauses for obligations, rights, risks, and time-bars - Generate notice calendars and obligations registers - Draft structured claim, EOT, variation, and payment templates - Compare FIDIC forms across key topics - Calculate Singapore SOP Act payment timelines - Assess delay events, concurrency, EOT exposure, and LD risk - Triage dispute resolution pathways ## Supported forms and frameworks - FIDIC Red Book 2017 (Construction) - FIDIC Yellow Book 2017 (Plant & Design-Build) - FIDIC Silver Book 2017 (EPC/Turnkey) - PSSCOC (Construction Works) - SIA Conditions (9th Edition) - NEC (NEC3, NEC4) — notice calendar only - JCT — pending - Singapore SOP Act workflows ## Why this skill matters Construction outcomes often turn on details such as: - the exact contract form and edition - amended or bespoke clauses - notice timing - record quality - causation - quantification - governing law This skill helps you structure analysis quickly and consistently so you can spot risks early and avoid missing critical deadlines. > 🇸🇬 **Singapore matters — BCA circular awareness:** BCA frequently updates SOP Act timelines, plan fees, CORENET-X procedures, BC1/structural codes, cost-sharing schemes, productivity grants, and buildability rules through circulars at https://www1.bca.gov.sg/resources/circulars/. If you maintain a local mirror (e.g. `bca-circulars/` in your workspace, refreshed via a weekly heartbeat task), check it before relying on general knowledge. See `references/singapore.md` for details. > > ℹ️ This skill does not fetch live BCA updates itself. If you maintain a local circulars mirror in your workspace, use it as an up-to-date reference alongside the skill. ## CLI overview ``` Construction Law Skill — Unified CLI Usage: construction_law.py <command> [options] Available commands: intake 🏗️ Matter intake — guided issue triage (recommended starting point) wizard 🧙 Interactive guided prompts for tools notices Generate notice/obligations calendar for a contract form claims Generate claim notice/EOT/VO/disruption letters sop Singapore SOP Act payment timeline calculator compare Compare FIDIC contract forms side-by-side obligations Generate party-by-party obligations register register Generate Excel workbook of obligations + notices delay Delay analysis & EOT entitlement calculator deadline FIDIC deadline calculator — Singapore bundled; bring-your-own-holidays for other seats Run any command with --help for its specific options, e.g.: python3 construction_law.py notices --help python3 construction_law.py claims --help ``` --- ## Start here ### Recommended for all users: Matter Intake The intake mode triages a construction issue and produces a professional report with clause buckets, deadline checks, amendment warnings, confidence labels, and recommended next steps. ```bash python3 scripts/construction_law.py intake # or python3 scripts/intake.py ``` Supports non-interactive mode for automation: ```bash python3 scripts/intake.py --file matter.json --output report.md --save-matter answers.json ``` Use non-interactive mode for repeatable internal workflows, templates, or batch matter intake. ### Sample Matter Intake output Example: delay / EOT issue under FIDIC Red 1999 ```text ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ MATTER INTAKE — OUTPUT REPORT ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Contract: FIDIC Red 1999 Governing: Singapore Party: Contractor Issue: Delay / Extension of Time (EOT) Objective: Both EOT and additional payment 1. ISSUE SUMMARY This appears to be a delay / EOT issue arising from late access to site. The likely focus is notice compliance, EOT entitlement, causation, and supporting records. 2. LIKELY CLAUSE BUCKETS - Clause 2.1 Right of Access to Site - Clause 8.4 Extension of Time - Clause 20.1 Contractor's Claims 3. DEADLINE / TIME-BAR CHECK Trigger: Awareness of delaying event Deadline: 28 days from awareness Status: ⚠️ Notice not confirmed Risk: Potential time-bar if late notice applies 4. AMENDMENT SENSITIVITY FLAGS - Notice periods may be amended - EOT wording may be narrowed - Particular Conditions may override the standard form 5. RECOMMENDED NEXT STEPS - confirm exact clause wording and edition - verify whether notice was served in time - gather programme and contemporaneous records - prepare claim narrative and supporting documents 6. CONFIDENCE LABELS Deadline calculation: High confidence Clause identification: High confidence Entitlement position: Needs review This is a workflow and analysis aid only. It is not legal advice. ``` > 🎯 **For strategic claim planning**, see the companion skill `construction-claim-strategy` on ClawHub (v1.5.0). It covers the 7-Dimension strategy framework, argument ranking, delay analysis methods (SCL Protocol, TIA, Windows Analysis), concurrent delay strategy, disruption claims, quantum calculation examples (Eichleay/Hudson/Emden/Measured Mile), ADR strategy (adjudication vs arbitration), notice compliance, expert engagement, risk assessment, pacing delays, legal precedents, and 22 printable reference documents — all BEFORE you select clauses or start drafting. ### Interactive Wizard For tool-specific tasks (notices, claims, SOP calculator, etc.), use the wizard: ```bash python3 scripts/construction_law.py wizard # or python3 scripts/wizard.py ``` ### For power users: Unified CLI ```bash python3 scripts/construction_law.py --list python3 scripts/construction_law.py notices --form fidic-red python3 scripts/construction_law.py notices --form fidic-silver python3 scripts/construction_law.py claims --form fidic-red --type disruption-claim python3 scripts/construction_law.py claims --form fidic-yellow --type eot-application python3 scripts/construction_law.py claims --form fidic-silver --type notice-of-claim python3 scripts/construction_law.py sop --claim-date 2026-05-15 python3 scripts/construction_law.py compare --forms red,yellow,silver --topic claims python3 scripts/construction_law.py obligations --form fidic-silver --party both python3 scripts/construction_law.py register --form fidic-red --type both --output reg.xlsx python3 scripts/construction_law.py register --form fidic-silver --type both --output silver.xlsx python3 scripts/construction_law.py delay --baseline-start 2026-05-01 --baseline-end 2026-12-31 python3 scripts/construction_law.py deadline --seat SG --trigger 2026-05-15 --period 28 --mode exclude_ph python3 scripts/construction_law.py deadline --seat AE --trigger 2026-03-18 --period 28 --mode exclude_ph --holidays-file ae_holidays.json ``` > 💡 **All three FIDIC colours supported:** `fidic-red`, `fidic-yellow`, `fidic-silver`. Also: `psscoc`, `sia`. ## Critical rule: always confirm the contract edition first Before any clause analysis, confirm: - contract form - edition/year - governing law - amendments or particular conditions - whether bespoke terms override the standard form Do not assume the latest edition applies. ### Common editions still in use - PSSCOC: 2017, 2020 - PSSCOC D&B: 2014, 2020 - FIDIC: 1999, 2017 - SIA: 9th Ed, 11th Ed - NEC: NEC3, NEC4 ## Core workflows ### 1. Clause analysis For any clause question, this skill helps you: - identify the relevant clause - explain the obligation, entitlement, or risk - flag notice periods and time-bars - cross-reference related clauses - highlight where amendments may change the default position ### 2. Claims and EOT analysis For delay, disruption, prolongation, and related claims, use this structure: 1. Entitlement 2. Causation 3. Notice compliance 4. Substantiation 5. Quantification ### 3. Notice calendars Build notice calendars that capture: - clause reference - trigger event - notice period - recipient - consequence of non-compliance ### 4. Risk allocation review Assess whether risk is allocated to the party best able to: 1. identify it 2. control it 3. mitigate it 4. absorb it ### 5. Delay and LD exposure Review: - delay event chronology - criticality - concurrency - potential EOT entitlement - potential liquidated damages exposure ## Included tools ### Interactive Wizard Guided prompts for common tasks. ```bash python3 scripts/wizard.py ``` ### Notice Calendar Generator Generate notice and obligations calendars. ```bash python3 scripts/notice_calendar.py --form fidic-red --format md python3 scripts/notice_calendar.py --form fidic-yellow --format md python3 scripts/notice_calendar.py --form fidic-silver --format md python3 scripts/notice_calendar.py --form psscoc --format csv --output notices.csv ``` ### Claims Template Generator Generate structured templates for claim notices and related submissions. ```bash python3 scripts/claims_template.py --list python3 scripts/claims_template.py --form fidic-red --type notice-of-claim --output notice.md python3 scripts/claims_template.py --form fidic-yellow --type eot-application --output eot_yellow.md python3 scripts/claims_template.py --form fidic-silver --type notice-of-claim --output notice_silver.md python3 scripts/claims_template.py --form psscoc --type eot-application --output eot.md ``` ### Obligations Register Generator Create obligations registers by party and category. ```bash python3 scripts/obligations_register.py --form fidic-red --party both --format md python3 scripts/obligations_register.py --form fidic-yellow --party contractor --format md python3 scripts/obligations_register.py --form fidic-silver --party both --format md python3 scripts/obligations_register.py --form psscoc --party contractor --format csv --output obligations.csv ``` ### SOP Act Payment Timeline Calculator Calculate statutory payment deadlines from a Singapore payment claim date. ```bash python3 scripts/sop_calculator.py --claim-date 2026-06-30 python3 scripts/sop_calculator.py --claim-date 2026-06-30 --response-period 14 --format csv --output timeline.csv ``` ### FIDIC Contract Comparator Compare FIDIC forms side by side. ```bash python3 scripts/fidic_comparator.py --forms red,yellow,silver --topic risk python3 scripts/fidic_comparator.py --forms red,yellow,silver --topic all --format csv --output comparison.csv ``` Topics: `overview`, `risk`, `claims`, `disputes`, `payment`, `termination`, `all` ### FIDIC Deadline Calculator (Seat-Aware) Compute contractual deadlines based on the seat country's public holidays. > The FIDIC Deadline Calculator supports Singapore out of the box, with holiday data verified against the eGazette. Singapore data covers gazetted years (currently 2025–2026); the 2027 entry is provisional until MOM gazettes it (expected late 2026). For projects with a seat in any other jurisdiction, you must supply your own holiday list — the tool will not ship pre-loaded holiday data for non-Singapore seats. This is deliberate: holiday calendars vary by sub-jurisdiction (Malaysian state, UK constituent country, individual emirate), shift by moon-sighting, and are gazetted by your own government's authoritative source. Use that source, not ours. Supports three day-counting modes: - **calendar** — calendar-day counting; use where the relevant clause defines or operates on calendar days - **exclude_ph** — calendar days excluding public holidays of the seat country - **working** — excludes weekends AND public holidays (for contracts defining "working day") ```bash python3 scripts/fidic_deadline.py --list-seats python3 scripts/fidic_deadline.py --seat SG --trigger 2026-05-15 --period 28 python3 scripts/fidic_deadline.py --seat SG --trigger 2026-05-15 --period 28 --mode exclude_ph python3 scripts/fidic_deadline.py --seat AE --trigger 2026-03-18 --period 28 --mode exclude_ph --holidays-file ae_holidays.json python3 scripts/fidic_deadline.py --seat MY --trigger 2026-02-15 --period 28 --mode working --holidays-file my_holidays.json ``` Bundled seat: `SG` (Singapore — gazette-verified). For any other jurisdiction, supply `--holidays-file`. See `docs/holiday-file-format.md` for the JSON schema and a worked example. > 💡 **Which mode to use?** Check your contract's definition of "day". FIDIC 2017 standard = calendar days. If Particular Conditions amend this to exclude public holidays, use `exclude_ph`. If the contract uses "working days", use `working`. ### Delay Analysis Calculator Assess delay events, concurrency, EOT exposure, and LD risk. ```bash python3 scripts/delay_calculator.py --baseline-start 2026-05-11 --baseline-end 2030-05-10 \ --add "Late access|2026-06-01|2026-06-30|employer|critical" \ --add "Weather|2026-07-15|2026-07-25|neutral|critical" ``` ### Excel Register Generator Export notice calendars and obligations registers to .xlsx. ```bash python3 scripts/excel_register.py --form fidic-red --type both --output contract_admin.xlsx --commencement 2026-05-11 python3 scripts/excel_register.py --form fidic-yellow --type both --output yellow_admin.xlsx python3 scripts/excel_register.py --form fidic-silver --type both --output silver_admin.xlsx python3 scripts/excel_register.py --form psscoc --type obligations --output obligations.xlsx ``` Requires: `openpyxl` (`pip3 install openpyxl`) ## Example outputs ### Notice calendar — concrete sample ``` Clause: FIDIC 20.2.1 Trigger: Event giving rise to claim Deadline: 28 days from awareness Recipient: Engineer Risk: Late notice may prejudice entitlement (time-bar) ``` ### Notice calendar — fields - Clause reference - Trigger event - Notice deadline - Recipient - Time-bar consequence ### Claims template - Background - Contract basis - Event chronology - Causation - Notice compliance - Relief sought - Reservation of rights - Supporting documents ### Obligations register - Clause - Obligation - Responsible party - Timing - Priority - Status - Notes ## Best use cases - preliminary clause review - contract administration checklists - claim structure and document preparation - notice and deadline tracking - form comparison - SOP timeline calculation - delay event triage ## Important limitations This skill is a workflow and analysis aid. It is not a substitute for legal advice. Use caution where: - the contract is heavily amended - bespoke EPC or project-specific drafting applies - governing law may materially change the outcome - local statutory regimes override standard form assumptions - adjudication, arbitration, or court submissions require final review Always verify: - the contract edition - amendments and particular conditions - governing law - notice requirements - jurisdiction-specific treatment of concurrency, good faith, prevention, and time-bars ## Key principles - Read the contract first - Standard form positions mean little if amended - Time-bars can be fatal - Notice compliance should be checked before merits - Concurrency treatment differs by jurisdiction - Good faith is jurisdiction-specific - Prevention issues may affect LD exposure - Fitness for purpose and reasonable skill and care must be distinguished carefully ## Reference files - references/fidic.md - references/singapore.md - references/claims.md - references/disputes.md - references/procurement.md ## Live knowledge sources (Singapore) For up-to-date Singapore regulatory context, consult the **BCA circulars page** — the authoritative source for changes to SOP Act timelines, plan fees, CORENET-X, BC1/structural codes, cost-sharing schemes, productivity grants, and buildability requirements: - **Source:** https://www1.bca.gov.sg/resources/circulars/ - **Recommended setup:** Maintain a local PDF mirror (e.g. `bca-circulars/` in your workspace) refreshed weekly via a heartbeat or cron task. Track seen titles in a `seen.json` index to detect new circulars. When advising on Singapore matters touching SOP Act timelines, plan fees, CORENET-X, BC1/structural codes, cost-sharing schemes, productivity grants, or buildability requirements, **check the latest circulars first** before relying on general knowledge — BCA updates can change deadlines, rates, and procedural requirements. If your local mirror looks stale (>2 weeks old), trigger a fresh fetch. ## 🔒 Security and safety All Python scripts in this skill are designed as safe, local template and register generators. - ✅ **No network access** — no API calls, no HTTP requests - ✅ **No subprocess execution** — no shell commands, no external programs - ✅ **No dynamic code loading** — sibling scripts are imported as plain Python modules (no `importlib`, no `exec`, no `eval`) - ✅ **No telemetry from skill code** — the bundled scripts do not collect or transmit data. (Note: your LLM provider’s normal data handling still applies.) - ✅ **No filesystem traversal** — only writes to the user-specified `--output` path - ✅ **Read-only static reference data** — contract clauses bundled with the skill - ✅ **ClawScan:** Benign - ✅ **Static analysis:** Benign - ℹ️ VirusTotal status is shown on the listing page **Safe to install and use.** 🛡️ ### Files written Scripts write files **only** when you pass explicit output flags. If no output flag is provided, all output goes to stdout. | Script | Flag | What is written | Format | |--------|------|----------------|--------| | Any script | `--output FILE` | Generated report/template/calendar | UTF-8 (Markdown, CSV, or plain text) | | `excel_register.py` | `--output FILE.xlsx` | Obligations/notices workbook | Excel (.xlsx, requires openpyxl) | | `claims_template.py` | `--output FILE.docx` | Claim letter | Word (.docx, requires python-docx) | | `sop_calculator.py` | `--output FILE` | SOP payment timeline | UTF-8 Markdown or CSV | | `fidic_deadline.py` | `--output FILE` | Deadline calculation | UTF-8 text or Markdown | No files are created, modified, or read beyond the explicit input flags (`--file`, `--holidays-file`, `--events-csv`). ## Dependencies Core scripts use only the Python standard library. Optional features require: | Package | Required For | Install | |---------|-------------|--------| | `openpyxl` | Excel register output | `pip3 install openpyxl` | | `python-docx` | Word document export | `pip3 install python-docx` | Declared in `pyproject.toml` as optional extras: ```bash pip3 install .[excel] # Excel only pip3 install .[all] # Excel + Word pip3 install .[test] # pytest + hypothesis ``` ## Testing The skill includes a multi-layer test suite (73 tests): **Layer 1 — Golden file** (`test_sop_golden.py`): 8 hand-computed scenarios frozen in `tests/data/golden_timelines.csv`. Covers CNY cluster, Vesak/Hari Raya Haji, Christmas/New Year cross-year, National Day in-lieu, baseline, claim-on-PH, 14-day response, and s.17(2) +7 extension. **Layer 2 — Property-based** (`test_sop_properties.py`): Hypothesis tests over 2025–2027 date range. Properties: deadline never on PH, strictly monotonic, round-trip sop_days_between, adding a holiday can only push later, result ≥ N calendar days. **Layer 3 — Boundary** (`test_sop_boundary.py`): End-of-month, end-of-year, s.17(2) extension (verified as SOP days with PH skipping), claim on PH, consecutive holidays (3+ non-SOP days), out-of-range year (fails loud), Silver Book fitness-for-purpose assertion. **Register tests** (`test_registers.py`): All forms produce valid MD/CSV, Silver Book has no Engineer, entry structure validation. ```bash cd skills/construction-law pip3 install .[test] python3 -m pytest tests/ -v # or without pytest: python3 -m unittest discover tests ``` ## Changelog ### v2.11.5 (May 2026) - **MUST-FIX:** `_check_year_coverage` now called from all public functions (`is_sop_day`, `add_sop_days`, `sop_days_between`) — previously only called from `calc_timeline`. Dates in uncovered years (e.g. 2028) now raise `ValueError` instead of silently treating all days as working days. Year-crossing within `add_sop_days` also checked. - **Docs:** `is_sop_day` docstring clarifies: returns True for Saturdays/Sundays (they count as SOP days); raises ValueError for uncovered years (does not silently return False); ad-hoc holidays (e.g. Polling Day) require manual addition - **Docs:** `add_sop_days(start, 0)` semantics documented (returns start unchanged; caller responsible for whether start is a working day) - **Docs:** Ad-hoc holiday warning added to timeline output - **Docs:** Error message now uses actual config path (`_HOLIDAY_JSON.name`) instead of hardcoded string - **Tests:** 73 → 85. New: `TestSaturdayDeadline` (deadline on Saturday stays), `TestInLieuCollision` (synthetic collision sets exercise while-loop), `TestOutOfRangeYear` expanded (4 new: `add_sop_days`, `is_sop_day`, `sop_days_between`, year-crossing), golden row 9 (Saturday deadline + Labour Day PH skip) - **Tests:** Property test date bounds tightened (`MAX_DATE_FOR_ADD = 2027-10-01`) to avoid crossing into uncovered 2028 ### v2.11.4 (May 2026) - **Security:** Sanitised test docstrings and comments — removed function-call patterns that static analysis scanners match against English text ### v2.11.3 (May 2026) - **Security:** Replaced string-grep forbidden-imports check with `ast.parse` tree-walking — properly catches `compile(...)`, `exec(...)`, `eval(...)` regardless of whitespace or indirection; no longer false-positives on comments, docstrings, or strings containing those words ### v2.11.2 (May 2026) - **Title:** Updated to "Construction Law: FIDIC, PSSCOC, SIA & Singapore SOP Act" - **Advisory:** Added v2.11.0 user advisory banner for non-SG deadline re-check - **Docs:** Added CLI overview (`--help` output) to SKILL.md so users can evaluate commands without installing - **Docs:** Tightened "No telemetry" statement to distinguish skill code from LLM provider data handling - **Docs:** Added "Files written" section documenting exactly what each script writes and when - **Docs:** SKILL.md changelog backfilled with v2.10.0–v2.11.1 entries (CHANGELOG.md remained the source of truth; SKILL.md was out of sync) - **Security:** Added `test_security.py` — scans all 13 scripts for forbidden imports (subprocess, socket, requests, urllib.request, http.client, importlib, pickle, marshal, os.system, exec, eval, compile), enforcing the no-network/no-subprocess/no-dynamic-code claim at test time - **Docs:** Recommend `python3 -m unittest` (stdlib) alongside pytest ### v2.11.1 (May 2026) - **Scope correction:** Removed bundled best-effort holiday data for AE, MY, GB — shipping unverified holiday data in a legal-deadline tool was the wrong call - **FIDIC Deadline Calculator** now ships with **Singapore holidays only** (gazette-verified). Other jurisdictions: supply your own verified holiday data via `--holidays-file` - Added `docs/holiday-file-format.md` with JSON schema, worked example, and source guidance - Reduced golden deadline tests to Singapore-only; retained generic property tests ### v2.11.0 (May 2026) - **New:** FIDIC Deadline Calculator (`fidic_deadline.py`) — computes contractual deadlines in three modes: `calendar` (calendar-day counting), `exclude_ph` (excludes public holidays only), and `working` (excludes weekends + public holidays) - **Singapore calendar bundled and maintained** — verified against eGazette / MOM source data - **Important:** Holiday data covers **Singapore only**. For all other jurisdictions, users must supply their own gazette-verified holiday file via `--holidays-file`. The tool will prompt clearly if a non-SG seat is used without one. ### v2.10.1 (May 2026) - Reconciled CHANGELOG v2.8.1/v2.9.1 duplication - Recategorized out-of-range ValueError as legal accuracy change - Added per-year eGazette URL, MOM gazette cite, and holiday names to `data/sg_holidays.json` - Added moon sighting notes for Hari Raya Puasa / Hari Raya Haji dates ### v2.10.0 (May 2026) - **3-layer test suite (57+ tests):** golden-file, Hypothesis property-based, and boundary tests for SOP calculator; register tests for all forms - **Out-of-range year protection:** Calculator now raises ValueError with a clear message when claim date's year has no holiday data (no silent wrong answers) - **`pyproject.toml`** with optional extras (`[excel]`, `[word]`, `[all]`, `[test]`) - **`data/sg_holidays.json`** as single source of truth with per-year provenance - **Disclaimer injection** on all generated templates (visible text + HTML comment) - **Deprecated:** `--add` pipe-delimited flag; replaced with `--add-event` (structured) and `--events-csv` (batch) - **Added:** `CHANGELOG.md` with categorized convention ### v2.9.0 (May 2026) - **FIDIC Silver Book (EPC/Turnkey) 2017 added as a fully-supported form.** All 7 claim templates now have fidic-silver versions (notice-of-claim, eot-application, variation-claim, interim-claim, disruption-claim, loss-and-expense, final-account). Templates are tailored to EPC/Turnkey context: no Engineer (Employer administers directly via Employer's Representative), narrower EOT grounds under Sub-Clause 8.5, Contractor's broader risk assumption, lump sum pricing, fitness for purpose obligations, and design responsibility under Sub-Clause 5. - **fidic-silver obligations register added** — 33 contractor obligations (including EPC-specific design, fitness for purpose, higher physical conditions threshold) and 11 employer obligations. - **fidic-silver notice calendar added** — 12 key notices (claims, design, variations, disputes, payment) with Silver Book-specific recipients (Employer, not Engineer). - **Excel register now produces fidic-silver sheets** for both obligations and notices. - Full support matrix is now **35 combos** (7 claim types × 5 forms: fidic-red, fidic-yellow, fidic-silver, psscoc, sia). NEC4 and JCT remain pending. - Updated cross-references to companion skill `construction-claim-strategy` v1.5.0. ### v2.8.1 (May 2026) — SOP holiday correctness fix - **Sunday → Monday in-lieu rule now applied automatically.** Under the Holidays Act 1998 s.4(2), when a public holiday falls on a Sunday the following Monday is a public holiday in lieu. The previous bundled holiday list missed four such Mondays (1 Jun 2026 — Vesak in-lieu; 10 Aug 2026 — National Day in-lieu; 9 Nov 2026 — Deepavali in-lieu; 8 Feb 2027 — CNY Day 2 in-lieu). The SOP day arithmetic now derives in-lieu Mondays from the gazetted Sunday holidays automatically, so future gazette updates won't drift. - This affects any SOP timeline whose computed window crosses a Sunday public holiday — deadlines could be off by one day under v2.8.0 and earlier. Re-run any SOP timelines you generated previously if the period crossed those dates. ### v2.8.0 (May 2026) - **FIDIC Yellow Book 2017 added as a fully-supported form.** All 7 claim templates now have fidic-yellow versions (notice-of-claim, eot-application, variation-claim, interim-claim, disruption-claim, loss-and-expense, final-account). Templates are tailored to Plant & Design-Build context: design responsibility (Cl. 5), Employer's Requirements (Cl. 1.9), milestone-based payment (Schedule of Payments), Tests after Completion (Cl. 12), and the 8.5 EOT grounds. - **fidic-yellow obligations register added** — 33 contractor obligations (including design-specific clauses 5.1–5.8) and 12 employer obligations. - **Excel register now produces fidic-yellow obligations sheets** in addition to notices. - All new templates are edition-tagged in the HTML comment header and visible body. - Full support matrix is now **28 combos** (7 claim types × 4 forms: fidic-red, fidic-yellow, psscoc, sia). NEC4 and JCT remain pending. ### v2.7.0 (May 2026) - **6 new claim templates** filling the PSSCOC + SIA gap: `eot-application`, `variation-claim`, and `interim-claim` now have full PSSCOC (7th Ed., 2014 rev. 2020) and SIA (9th Ed., 2010 rep. 2016) versions. - All new templates are **edition-tagged** in an HTML comment header and in the visible body, so users know exactly which standard form edition the clauses correspond to. - Interim-claim templates explicitly dual-purpose as SOP Act s.10 payment claims with the s.10(3) requirements ticked off. - Full support matrix is now **21 combos** (7 claim types × 3 forms). ### v2.6.0 (May 2026) - **SOP calculator now holiday-aware.** Periods are computed in SOP days (excluding Singapore public holidays per SOP Act s.2 read with the Holidays Act 1998). Previously used calendar-day arithmetic which silently produced wrong dates around holiday clusters. - **SOP timeline conceptual fix.** Removed misleading min/max determination and payment-due rows; replaced with single statutory deadlines and an explicit s.17(2) +7-day extension note. - **Argparse no longer crashes** on `claims_template.py` for `fidic-yellow`, `nec4`, or `jct` — unsupported forms are now rejected at parse time with a pointer to `--list`. Unsupported (form, type) combos within registered forms also fail with a helpful message. - **Excel register no longer writes half-empty workbooks.** Pre-flight coverage check refuses combos like `--form fidic-yellow --type obligations` and prints what is supported. - **Version sprawl resolved.** New `scripts/version.py` is the single source of truth; intake.py / wizard.py / delay_calculator.py / sop_calculator.py footers all aligned to v2.6.

path: CHANGELOG.md
content: # Changelog

All notable changes to the Construction Law Skill are documented here.

🚨 = Legal accuracy change (review before relying on existing output)
✨ = New feature  |  🔧 = Maintenance  |  🐛 = Bug fix

## [2.11.5] — 2026-05-17

### 🚨 Critical fix + test hardening
- **MUST-FIX:** `_check_year_coverage` wired into all public functions (`is_sop_day`, `add_sop_days`, `sop_days_between`). Previously only called from `calc_timeline` — direct callers of the lower-level functions got silent wrong answers for uncovered years. Year-crossing within `add_sop_days` also checked.
- `is_sop_day` docstring: clarifies Saturday/Sunday semantics, ValueError on uncovered years, ad-hoc holiday caveat
- `add_sop_days(start, 0)` semantics documented
- Ad-hoc holiday (e.g. Polling Day) warning added to timeline output
- Error message uses `_HOLIDAY_JSON.name` instead of hardcoded path
- Tests: 73 → 85. New classes: `TestSaturdayDeadline`, `TestInLieuCollision`, expanded `TestOutOfRangeYear`. Golden row 9 (Saturday deadline). Property test bounds tightened.

## [2.11.4] — 2026-05-17

### 🔧 Maintenance
- Sanitised test docstrings and comments to avoid static-analysis false positives on function-call patterns in English text

## [2.11.3] — 2026-05-17

### 🔧 Maintenance
- Replaced string-grep forbidden-imports test with `ast.parse` tree-walking — catches forbidden calls regardless of whitespace/indirection, no false-positives on comments/docstrings/strings

## [2.11.2] — 2026-05-17

### 🔧 Maintenance — Trust-gap fixes
- **Title updated** to "Construction Law: FIDIC, PSSCOC, SIA & Singapore SOP Act"
- **v2.11.0 user advisory banner** added to SKILL.md top for non-SG deadline re-check (with removal-date comment: 2026-08-17)
- SKILL.md changelog backfilled with v2.10.0–v2.11.1 entries (CHANGELOG.md remained the source of truth; SKILL.md was out of sync)
- Added CLI overview (unified dispatcher `--help` output) to SKILL.md
- Tightened "No telemetry" statement: "No telemetry from skill code — the bundled scripts do not collect or transmit data. (Note: your LLM provider’s normal data handling still applies.)"
- Added "Files written" section documenting all script output paths
- Added `test_security.py` — scans all 13 scripts for forbidden imports (subprocess, socket, requests, urllib.request, http.client, importlib, pickle, marshal, os.system, exec, eval, compile)
- Added `python3 -m unittest` as recommended test runner (stdlib-only alternative to pytest)
- Updated test count to 73 (72 existing + 1 security)

## [2.11.1] — 2026-05-10

### 🚨 Legal Accuracy — Action required if you used v2.11.0
- If you ran v2.11.0's FIDIC Deadline Calculator against an AE, MY, or GB seat, the bundled holiday data for those jurisdictions was best-effort and not verified against authoritative sources. Re-check those deadlines against your jurisdiction's official gazette or equivalent before relying on them.
- v2.11.1 removes the unverified data and replaces it with a bring-your-own-holidays mechanism (see below).

### 🔧 Maintenance — Scope correction
- v2.11.0 shipped with bundled best-effort holiday data for AE, MY (federal only), and GB (England & Wales only). Verifying that data against authoritative sources for each jurisdiction was outside the maintainer's capacity, and shipping unverified holiday data in a legal-deadline tool was the wrong call.
- v2.11.1 narrows the supported surface to Singapore (gazette-verified) and adds a `--holidays-file` mechanism for users in other jurisdictions to supply their own verified data.

### ✨ Features
- **FIDIC Deadline Calculator (Singapore seat; bring-your-own-holidays for other jurisdictions)** — `fidic_deadline.py` computes contractual deadlines in three modes: `calendar` (calendar-day counting), `exclude_ph` (excludes PHs only), and `working` (excludes weekends + PHs).
- **Singapore holiday data bundled and maintained** — only SG ships out of the box, verified against eGazette / MOM source data.
- **User-supplied holiday support for non-SG seats** — use `--holidays-file` with your own jurisdiction/year-specific JSON file.
- Added `docs/holiday-file-format.md` with JSON schema, worked example, and source guidance.

### 🔧 Maintenance
- Removed bundled AE / MY / GB holiday files from the supported surface.
- Reduced golden deadline scenarios to Singapore-only cases; retained generic property tests against user-supplied holiday data.
- Added helpful CLI error for non-SG seat use without `--holidays-file`.

## [2.10.1] — 2026-05-09

### 🔧 Maintenance
- Reconciled CHANGELOG v2.8.1/v2.9.1 duplication — merged in-lieu fix into single v2.8.1 entry with explicit "this is the only version that changed in-lieu logic" note; v2.9.1 now only lists Silver Book features
- Recategorized out-of-range ValueError as 🚨 Legal Accuracy (was 🔧 Maintenance)
- Added per-year source field to `data/sg_holidays.json` (MOM gazette cite, eGazette URL, moon sighting notes)
- Added holiday names array per year in `data/sg_holidays.json`
- Attempted dynamic version resolution via `[tool.setuptools.dynamic]` in pyproject.toml — reverted in v2.11.0 (see above)

## [2.10.0] — 2026-05-09

### 🚨 Legal Accuracy
- **Out-of-range year protection:** Calculator now raises `ValueError` with a clear message when the claim date's year has no holiday data (previously silently computed using weekday-only arithmetic, producing wrong dates). Scripts using 2028+ claim dates will now fail — update `data/sg_holidays.json` with gazetted holidays first.

### 🔧 Maintenance
- Added `pyproject.toml` with optional extras (`[excel]`, `[word]`, `[all]`, `[test]`)
- Added comprehensive test suite: 57 tests across golden-file, property-based (Hypothesis), and boundary layers
- Added `data/sg_holidays.json` as the single source of truth for holiday data
- Added disclaimer injection to all generated templates (visible text + HTML comment)
- Deprecated `--add` pipe-delimited flag in delay_analysis.py; replaced with `--add-event` and `--events-csv`
- Added `CHANGELOG.md` with categorized convention (🚨 Legal Accuracy vs ✨ Features)

### ✨ Features
- (Rolled from v2.9.1) FIDIC Silver Book obligations register (33 contractor + 11 employer), notice calendar (12 entries), Excel register

## [2.9.1] — 2026-05-09

### ✨ Features
- Complete FIDIC Silver Book support: added obligations register (33 contractor + 11 employer), notice calendar (12 entries), and Excel register
- v2.9.0 had claim templates only — this completes the full Silver Book toolkit across all 4 tools

## [2.9.0] — 2026-05-09

### ✨ Features
- Added FIDIC Silver Book (EPC/Turnkey) 2017 as a fully-supported form
- Added fidic-silver obligations register (33 contractor obligations, 11 employer obligations)
- Added fidic-silver notice calendar (12 key notices)
- Excel register now produces fidic-silver sheets for obligations and notices
- Expanded full support matrix to 35 combos (7 claim types × 5 forms)

### 🔧 Maintenance
- Updated cross-references to companion skill `construction-claim-strategy` v1.5.0

## [2.8.1] — 2026-05-09

### 🚨 Legal Accuracy
- **Sunday → Monday in-lieu rule now applied automatically** under the Holidays Act 1998 s.4(2)
- Fixed missing in-lieu Mondays for 1 Jun 2026 (Vesak), 10 Aug 2026 (National Day), 9 Nov 2026 (Deepavali), and 8 Feb 2027 (CNY Day 2)
- SOP day arithmetic now derives in-lieu Mondays from gazetted Sunday holidays automatically — no manual listing needed
- **Action required:** Re-run any previously generated SOP timelines if they crossed those dates. This is the only version that changed in-lieu logic; v2.9.0+ builds on this fix without further changes to holiday handling.

## [2.8.0] — 2026-05-09

### ✨ Features
- Added FIDIC Yellow Book 2017 as a fully-supported form
- Added fidic-yellow obligations register (33 contractor obligations, 12 employer obligations)
- Excel register now produces fidic-yellow obligations sheets in addition to notices
- All new templates are edition-tagged in HTML comments and visible body
- Expanded full support matrix to 28 combos (7 claim types × 4 forms)

## [2.7.0] — 2026-05-09

### ✨ Features
- Added 6 new claim templates filling the PSSCOC + SIA gap for eot-application, variation-claim, and interim-claim
- Added full PSSCOC (7th Ed., 2014 rev. 2020) and SIA (9th Ed., 2010 rep. 2016) versions for those templates
- Edition-tagged all new templates in HTML comment header and visible body
- Interim-claim templates now dual-purpose as SOP Act s.10 payment claims with s.10(3) requirements ticked off
- Expanded full support matrix to 21 combos (7 claim types × 3 forms)

## [2.6.0] — 2026-05-09

### 🚨 Legal Accuracy
- SOP calculator now uses holiday-aware SOP day arithmetic instead of calendar-day arithmetic
- SOP timeline conceptual fix: removed misleading min/max determination and payment-due rows; replaced with single statutory deadlines and a +7-day extension note

### 🔧 Maintenance
- Argparse now rejects unsupported forms and unsupported (form, type) combinations at parse time with helpful messages
- Excel register now refuses half-empty workbooks via pre-flight coverage checks
- Version sprawl resolved with `scripts/version.py` as the single source of truth


path: REVIEW-FEEDBACK.md
content: # External Review — Construction Law v2.2.1

_Source: ChatLLM (Abacus.ai) review, 2026-05-04_
_Saved for reference. Priority items already applied to SKILL.md._

## Honest assessment ratings

- Subject-matter positioning: 8.5/10
- Practical utility: 8/10
- Trust/safety communication: 7.5/10
- Conversion/readability of listing page: 6.5/10
- Professional product polish: 7/10

> Core is strong. Main gap is presentation, trust framing, and expectation management — not the idea itself.

## Top-6 priority improvements (least effort, biggest gain)

1. ✅ Rewrite the top description / value proposition
2. ✅ Move wizard + use cases higher in the README
3. ⏳ Add sample outputs (1 short preview per tool)
4. ✅ Add explicit legal disclaimer / limitations
5. ⏳ Enforce edition/year input everywhere (UX layer)
6. ⏳ Clarify supported vs unsupported scope

## Full feedback summary

### Quick wins
- Lead with one-line value prop, not security block
- Sharpen positioning: name the audiences (lawyers, contract managers, QS, claims consultants, PMs)
- Add concrete sample outputs for each tool
- Stronger legal disclaimer (educational, not legal advice; verify time-bars; local law overrides)
- Clear "Supported / Use caution" boundaries
- Make wizard the hero feature — surface it earlier
- Distinguish intelligence modes: template gen vs date math vs clause analysis vs comparison
- Keyword-rich description for discoverability
- Add "Best use cases" + "Bad use cases" sections

### Recommended README order
1. What this skill does
2. Who should use it
3. Supported forms / jurisdictions
4. Top 5 use cases
5. Quick start
6. Wizard
7. Tool list with sample outputs
8. Important limitations / disclaimer
9. Security & safety
10. Reference files / architecture

### Future product-quality ideas (bigger lift)
- **Matter intake mode** — guided flow (form, edition, governing law, project type, issue, dates, notices served, amendments, relief sought) → outputs issue summary, missing facts, deadline checklist
- **Amendment sensitivity** — checklist warning system for bespoke amendments that change notice periods, EOT entitlement, design responsibility, dispute steps
- **Confidence labels** on each output (High: dates/comparisons; Med: standard-form clause; Low: bespoke interpretation)
- **Document ingestion** — upload contract → detect form/edition → identify amendments → auto-build registers (biggest differentiator)

### Listing/marketplace text suggestions

**Title (recommended):** Construction Law: FIDIC, NEC, PSSCOC, SIA Claims & Notices

**Tagline:** Analyze construction contracts, notices, claims, EOTs, SOP timelines, and dispute routes across major standard forms, with strong Singapore-focused support.

**Short description:** Construction contract analysis and workflow automation for FIDIC, NEC, PSSCOC, SIA, and JCT — covering clause review, notice calendars, claims, EOTs, SOP Act timelines, risk allocation, and dispute pathways.

**3 value hooks:**
- Reduce deadline risk with notice calendars and SOP timelines
- Speed up claims prep with structured templates and clause guidance
- Compare contract risk quickly across FIDIC and other common forms


path: _meta.json
content: ownerId: kn77g2eearfhaq251ab7jtrctn854v1s
slug: construction-law
version: 2.8.2
publishedAt: 1778332920988

path: data/holidays/README.md
content: # Country Holiday Data

This directory contains public holiday data used by the FIDIC Deadline Calculator.

## Bundled data

Only **Singapore** (`SG.json`) is bundled and maintained by the skill author, verified against the MOM gazette and eGazette.

## Other jurisdictions

For any non-Singapore seat, users must supply their own holiday file via `--holidays-file`. See `docs/holiday-file-format.md` for the JSON schema, a worked example, and source recommendations.

## File naming

`<ISO-3166-1-alpha-2>.json` — e.g. `SG.json`

## Refresh procedure

Check annually (typically Q4 when MOM publishes next year's gazette) for updated Singapore holidays. Update `SG.json`, run tests, and bump the skill version.

## Why only Singapore?

Holiday calendars vary by sub-jurisdiction (Malaysian state, UK constituent country, individual emirate), shift by moon-sighting, and are gazetted by each government's authoritative source. Rather than ship best-effort data that users might rely on without verification, we provide a clean extension mechanism and let users bring verified data from their own jurisdiction's gazette.


path: data/holidays/SG.json
content: {
  "_meta": {
    "country": "Singapore",
    "iso": "SG",
    "source": "Ministry of Manpower (MOM) gazette via eGazette.gov.sg",
    "last_verified": "2026-05-10",
    "notes": "HRP and HRH subject to moon sighting (±1 day). Sunday PHs generate Monday in-lieu under Holidays Act 1998 s.4(2) — derived automatically by sop_calculator.py, not listed here.",
    "in_lieu_rule": "auto_sunday_to_monday",
    "verification": "SKILL_MAINTAINED",
    "verification_note": "Singapore holidays are verified annually against the MOM gazette (mom.gov.sg/newsroom/press-releases) and eGazette. This is the authoritative source for SOP Act calculations. Maintained by the skill author."
  },
  "2025": {
    "source": "eGazette No. 2493 — Singapore Public Holidays 2025 (published 5 Aug 2024)",
    "url": "https://assets.egazette.gov.sg/2024/Government%20Gazette/Others/2493.pdf",
    "dates": [
      "2025-01-01",
      "2025-01-29",
      "2025-01-30",
      "2025-03-31",
      "2025-04-18",
      "2025-05-01",
      "2025-05-12",
      "2025-06-07",
      "2025-08-09",
      "2025-10-20",
      "2025-12-25"
    ],
    "names": [
      "New Year's Day",
      "Chinese New Year Day 1",
      "Chinese New Year Day 2",
      "Hari Raya Puasa",
      "Good Friday",
      "Labour Day",
      "Vesak Day",
      "Hari Raya Haji",
      "National Day",
      "Deepavali",
      "Christmas Day"
    ],
    "notes": "HRP and HRH are subject to moon sighting and may shift by ±1 day; gazette is authoritative."
  },
  "2026": {
    "source": "eGazette No. 2258 — Singapore Public Holidays 2026 (published 2025)",
    "url": "https://assets.egazette.gov.sg/2025/Government%20Gazette/Others/2258.pdf",
    "dates": [
      "2026-01-01",
      "2026-02-17",
      "2026-02-18",
      "2026-03-21",
      "2026-04-03",
      "2026-05-01",
      "2026-05-27",
      "2026-05-31",
      "2026-08-09",
      "2026-11-08",
      "2026-12-25"
    ],
    "names": [
      "New Year's Day",
      "Chinese New Year Day 1",
      "Chinese New Year Day 2",
      "Hari Raya Puasa",
      "Good Friday",
      "Labour Day",
      "Hari Raya Haji",
      "Vesak Day",
      "National Day",
      "Deepavali",
      "Christmas Day"
    ],
    "notes": "HRP and HRH are subject to moon sighting and may shift by ±1 day; gazette is authoritative.",
    "mom_press_release": "https://www.mom.gov.sg/newsroom/press-releases/2025/0616-public-holidays-for-2026"
  },
  "2027": {
    "source": "MOM gazette — Singapore Public Holidays 2027 (provisional — verify when gazetted, expected Nov 2026)",
    "url": "https://www.mom.gov.sg/employment-practices/public-holidays",
    "dates": [
      "2027-01-01",
      "2027-02-06",
      "2027-02-07",
      "2027-03-26",
      "2027-05-01",
      "2027-05-11",
      "2027-05-21",
      "2027-08-09",
      "2027-10-28",
      "2027-12-25"
    ],
    "names": [
      "New Year's Day",
      "Chinese New Year Day 1",
      "Chinese New Year Day 2",
      "Hari Raya Puasa",
      "Labour Day",
      "Vesak Day",
      "Hari Raya Haji",
      "National Day",
      "Deepavali",
      "Christmas Day"
    ],
    "notes": "Provisional — verify when gazetted (expected Nov 2026). HRP and HRH subject to moon sighting."
  }
}

path: data/sg_holidays.json
content: {
  "_meta": {
    "source": "https://www.mom.gov.sg/employment-practices/public-holidays",
    "last_verified": "2026-05-09",
    "refresh_procedure": "Check MOM gazette annually (typically published Oct-Nov for next year). Update this file, run tests, bump version.",
    "notes": "Sunday in-lieu days are derived automatically by sop_calculator.py per Holidays Act 1998 s.4(2) — do NOT list them here. Only list the gazetted dates."
  },
  "2025": {
    "source": "eGazette No. 2493 — Singapore Public Holidays 2025 (published 5 Aug 2024)",
    "url": "https://assets.egazette.gov.sg/2024/Government%20Gazette/Others/2493.pdf",
    "dates": [
      "2025-01-01",
      "2025-01-29",
      "2025-01-30",
      "2025-03-31",
      "2025-04-18",
      "2025-05-01",
      "2025-05-12",
      "2025-06-07",
      "2025-08-09",
      "2025-10-20",
      "2025-12-25"
    ],
    "names": [
      "New Year's Day",
      "Chinese New Year Day 1",
      "Chinese New Year Day 2",
      "Hari Raya Puasa",
      "Good Friday",
      "Labour Day",
      "Vesak Day",
      "Hari Raya Haji",
      "National Day",
      "Deepavali",
      "Christmas Day"
    ],
    "notes": "HRP and HRH are subject to moon sighting and may shift by ±1 day; gazette is authoritative."
  },
  "2026": {
    "source": "eGazette No. 2258 — Singapore Public Holidays 2026 (published 2025)",
    "url": "https://assets.egazette.gov.sg/2025/Government%20Gazette/Others/2258.pdf",
    "dates": [
      "2026-01-01",
      "2026-02-17",
      "2026-02-18",
      "2026-03-21",
      "2026-04-03",
      "2026-05-01",
      "2026-05-27",
      "2026-05-31",
      "2026-08-09",
      "2026-11-08",
      "2026-12-25"
    ],
    "names": [
      "New Year's Day",
      "Chinese New Year Day 1",
      "Chinese New Year Day 2",
      "Hari Raya Puasa",
      "Good Friday",
      "Labour Day",
      "Hari Raya Haji",
      "Vesak Day",
      "National Day",
      "Deepavali",
      "Christmas Day"
    ],
    "notes": "HRP and HRH are subject to moon sighting and may shift by ±1 day; gazette is authoritative.",
    "mom_press_release": "https://www.mom.gov.sg/newsroom/press-releases/2025/0616-public-holidays-for-2026"
  },
  "2027": {
    "source": "MOM gazette — Singapore Public Holidays 2027 (provisional — verify when gazetted, expected Nov 2026)",
    "url": "https://www.mom.gov.sg/employment-practices/public-holidays",
    "dates": [
      "2027-01-01",
      "2027-02-06",
      "2027-02-07",
      "2027-03-26",
      "2027-05-01",
      "2027-05-11",
      "2027-05-21",
      "2027-08-09",
      "2027-10-28",
      "2027-12-25"
    ],
    "names": [
      "New Year's Day",
      "Chinese New Year Day 1",
      "Chinese New Year Day 2",
      "Hari Raya Puasa",
      "Labour Day",
      "Vesak Day",
      "Hari Raya Haji",
      "National Day",
      "Deepavali",
      "Christmas Day"
    ],
    "notes": "Provisional — verify when gazetted (expected Nov 2026). HRP and HRH subject to moon sighting."
  }
}

path: demo/README.md
content: # Demo Folder — Tutorial Recording Assets

Files in this folder support the v2.5.0 YouTube tutorial recording.

## Files

- **`matter.json`** — sample Matter Intake input for Demo 1 (FIDIC Red 1999, Singapore, Contractor, late site access, EOT + additional payment)
- **`run-demos.sh`** — orchestrator that runs the three demos with pauses between each, ready for live screen recording

## Usage

From the skill root (`skills/construction-law/`):

```bash
bash demo/run-demos.sh
```

Press Enter between each demo to advance. Each demo clears the screen so the recording stays clean.

## Standalone commands (if you prefer to run them individually)

```bash
# Demo 1 — Matter Intake (FIDIC Red EOT, late site access)
python3 scripts/intake.py --file demo/matter.json

# Demo 2 — FIDIC Comparator (risk allocation: Red vs Yellow vs Silver)
python3 scripts/construction_law.py compare --forms red,yellow,silver --topic risk

# Demo 2b — Export claims comparison to CSV
python3 scripts/construction_law.py compare --forms red,silver --topic claims --format csv --output comparison.csv

# Demo 3 — SOP Act timeline (Payment Claim 30 Jun 2026)
python3 scripts/sop_calculator.py --claim-date 2026-06-30
```

## Note

These demo artefacts are excluded from the published skill via `.gitignore` / publish manifest if needed — they're recording aids, not user-facing skill assets.


path: demo/matter.json
content: form_id: fidic-red
edition: 1999
governing_law: Singapore
procurement: Construction (Build-only)
amendment_status: unknown
issue_key: 1
description: Late access to site by Employer; Contractor unable to commence on planned start date, causing critical-path delay to programme.
party: Contractor
objective: Both EOT and additional payment
urgency: Planning ahead — no immediate deadline

path: demo/run-demos.sh
content: #!/usr/bin/env bash
# Construction Law Skill — Tutorial Demo Runner
# Run from the skill root: bash demo/run-demos.sh
# Each section pauses so you can hit Enter when ready (good for live recording).

set -e
clear

pause() { read -rp "  ── press Enter for next demo ── " _; clear; }

echo "╔════════════════════════════════════════════════════════════╗"
echo "║  CONSTRUCTION LAW SKILL — TUTORIAL DEMO RUNNER              ║"
echo "║  v2.5.0 · MIT-0 · Offline                                   ║"
echo "╚════════════════════════════════════════════════════════════╝"
echo
echo "  Three demos coming up:"
echo "    1) Matter Intake     — kills the repetition"
echo "    2) FIDIC Comparator  — kills the clause hunt"
echo "    3) SOP Calculator    — kills the timeline-memorising"
echo
pause

# ─── DEMO 1: Matter Intake (FIDIC Red 1999, late site access, SG) ───
echo "▶ DEMO 1 — Matter Intake"
echo "  Scenario: FIDIC Red 1999 · Singapore · Contractor · Late site access · EOT + money"
echo
python3 scripts/intake.py --file demo/matter.json
pause

# ─── DEMO 2: FIDIC Comparator (Red vs Yellow vs Silver, risk topic) ───
echo "▶ DEMO 2 — FIDIC Comparator (Risk allocation: Red vs Yellow vs Silver)"
echo
python3 scripts/construction_law.py compare --forms red,yellow,silver --topic risk
echo
echo "  Now exporting Red vs Silver claims comparison to CSV..."
python3 scripts/construction_law.py compare --forms red,silver --topic claims --format csv --output comparison.csv
echo "  ✓ Saved: comparison.csv"
pause

# ─── DEMO 3: Singapore SOP Act payment timeline ───
echo "▶ DEMO 3 — SOP Act Calculator (Payment Claim served 30 Jun 2026)"
echo
python3 scripts/sop_calculator.py --claim-date 2026-06-30
echo
echo "╔════════════════════════════════════════════════════════════╗"
echo "║  Demo complete.                                              ║"
echo "║  Install: openclaw skills install construction-law           ║"
echo "║  Listing: clawhub.ai/redkiwi1688-prog/construction-law       ║"
echo "╚════════════════════════════════════════════════════════════╝"


path: docs/holiday-file-format.md
content: # Holiday File Format

When using the FIDIC Deadline Calculator with a non-Singapore seat, you must supply your own holiday data file via `--holidays-file`. This document describes the required JSON schema.

## Schema

```json
{
  "_meta": {
    "country": "Country Name",
    "iso": "XX",
    "source": "Description of your authoritative source",
    "last_verified": "YYYY-MM-DD",
    "notes": "Any caveats (moon sighting, regional variations, etc.)",
    "weekend": ["Sat", "Sun"],
    "in_lieu_rule": "none"
  },
  "2026": {
    "source": "Specific gazette/legislation reference for this year",
    "url": "URL to authoritative source",
    "dates": ["2026-01-01", "2026-04-03", "..."],
    "names": ["New Year's Day", "Good Friday", "..."]
  }
}
```

## Field reference

### `_meta` (required)

| Field | Required | Description |
|-------|----------|-------------|
| `country` | Yes | Human-readable country name |
| `iso` | Yes | ISO 3166-1 alpha-2 code (e.g. `GB`, `AE`, `MY`) |
| `source` | Yes | Name of the authoritative source you used |
| `last_verified` | Yes | Date you last verified this data (YYYY-MM-DD) |
| `notes` | No | Caveats — moon sighting, sub-national scope, etc. |
| `weekend` | No | Array of weekend day names. Default: `["Sat", "Sun"]`. Use `["Fri", "Sat"]` for UAE. |
| `in_lieu_rule` | No | One of: `none`, `auto_sunday_to_monday`, `rest_day_replacement`, `substitute_next_working_day`. Default: `none`. |

### Year entries (one per year)

| Field | Required | Description |
|-------|----------|-------------|
| `source` | Yes | Specific gazette or decree reference for this year |
| `url` | No | URL to the authoritative source document |
| `dates` | Yes | Array of date strings in `YYYY-MM-DD` format |
| `names` | No | Array of holiday names (same order as `dates`) |

## In-lieu rules

| Rule | Behaviour |
|------|-----------|
| `none` | No automatic substitution. List substitute days explicitly in `dates`. |
| `auto_sunday_to_monday` | PH falling on Sunday → Monday is automatically treated as in-lieu. (Singapore statutory rule.) |
| `rest_day_replacement` | PH falling on a weekend → next working day is in-lieu. Only applies in `exclude_ph` mode. |
| `substitute_next_working_day` | Same as `rest_day_replacement`. Used for UK-style substitution. |

If your jurisdiction has an in-lieu rule but you're unsure how to model it, set `in_lieu_rule` to `none` and list all substitute holidays explicitly in the `dates` array. This is always safe.

## Worked example: UK England & Wales 2026

Source: [gov.uk/bank-holidays](https://www.gov.uk/bank-holidays) (England and Wales), accessed 2026-05-10.

```json
{
  "_meta": {
    "country": "United Kingdom (England & Wales)",
    "iso": "GB",
    "source": "gov.uk/bank-holidays — England and Wales",
    "last_verified": "2026-05-10",
    "notes": "England & Wales only. Scotland and Northern Ireland have different bank holidays. Does NOT cover local/regional holidays.",
    "weekend": ["Sat", "Sun"],
    "in_lieu_rule": "substitute_next_working_day"
  },
  "2026": {
    "source": "gov.uk/bank-holidays England and Wales 2026",
    "url": "https://www.gov.uk/bank-holidays",
    "dates": [
      "2026-01-01",
      "2026-04-03",
      "2026-04-06",
      "2026-05-04",
      "2026-05-25",
      "2026-08-31",
      "2026-12-25",
      "2026-12-28"
    ],
    "names": [
      "New Year's Day",
      "Good Friday",
      "Easter Monday",
      "Early May bank holiday",
      "Spring bank holiday",
      "Summer bank holiday",
      "Christmas Day",
      "Boxing Day (substitute: 28 Dec, as 26 Dec is Saturday)"
    ]
  }
}
```

> **Note:** The 2026-12-28 entry is the substitute for Boxing Day (26 Dec falls on Saturday). Because `in_lieu_rule` is set to `substitute_next_working_day`, the tool will also auto-derive substitutes — so you could omit 2026-12-28 and let the rule handle it. Including it explicitly is safer and more transparent.

## How to use

```bash
# Save your file (e.g. gb_holidays.json), then:
python3 scripts/fidic_deadline.py --seat GB --trigger 2026-04-01 --period 14 --mode exclude_ph --holidays-file gb_holidays.json
```

## Source recommendations by jurisdiction

| Jurisdiction | Authoritative source |
|-------------|---------------------|
| Singapore | MOM gazette / eGazette (bundled — no file needed) |
| UAE | FAHR decree (shuraa.ae) |
| Malaysia (federal) | kabinet.gov.my / Jadual Hari Kelepasan Am |
| UK (England & Wales) | gov.uk/bank-holidays |
| Hong Kong | gov.hk General Holidays Ordinance |
| Australia (state-specific) | Your state's gazette |

For any jurisdiction: find your country's official gazette or ministry of manpower/labour equivalent. Do not rely on third-party holiday aggregator websites.

## Important caveats

1. **The year matters.** Moon-sighting holidays (Hari Raya, Eid, Vesak in some calendars) are gazetted close to the date. Any data for future years is a prediction until officially confirmed.

2. **The sub-jurisdiction matters.** "MY" is one file, but Malaysian state holidays vary. "GB" covers England & Wales only — not Scotland. "AE" is federal only — individual emirate observances differ. Your contract's governing law determines which calendar applies.

3. **Verify before reliance.** This tool is a workflow aid. The deadline it produces is only as good as the holiday data you feed it.


path: pyproject.toml
content: [project]
name = "construction-law"
version = "2.11.0"
description = "Construction contract analysis, claims templates, SOP calculator, and obligations registers for FIDIC, PSSCOC, SIA, and NEC"
license = "MIT-0"
requires-python = ">=3.9"

# Zero dependencies for core use
dependencies = []

[project.optional-dependencies]
excel = ["openpyxl>=3.1.0"]
word = ["python-docx>=1.0.0"]
all = ["openpyxl>=3.1.0", "python-docx>=1.0.0"]
test = ["pytest>=8.0", "hypothesis>=6.0"]

[tool.pytest.ini_options]
testpaths = ["tests"]


path: references/claims.md
content: # Claims, EOT & Delay Analysis — Reference

## Table of Contents
1. [Claims Framework](#claims-framework)
2. [Extension of Time (EOT)](#eot)
3. [Delay Analysis Methods](#delay-analysis)
4. [Disruption Claims](#disruption)
5. [Prolongation Costs](#prolongation)
6. [Loss & Expense](#loss-expense)
7. [Global Claims](#global-claims)
8. [Concurrent Delay](#concurrent-delay)
9. [Acceleration](#acceleration)
10. [Notice Requirements Summary](#notices)

---

## Claims Framework {#claims-framework}

### Five-Step Claims Process

| Step | Action | Key Question |
|------|--------|-------------|
| 1. Entitlement | Identify contractual basis | Which clause gives the right to claim? |
| 2. Causation | Establish cause-and-effect | What event caused what impact? |
| 3. Notice | Verify compliance with notice requirements | Was notice given on time? |
| 4. Substantiation | Compile supporting evidence | What records prove the claim? |
| 5. Quantification | Calculate time and/or cost | How much time/money is the impact? |

### Entitlement — Common Contractual Bases

| Ground | FIDIC Clause | PSSCOC Clause | SIA Clause |
|--------|-------------|---------------|------------|
| Variations | 13.1-13.3 | 14 | 11 |
| Unforeseeable ground conditions | 4.12 | Depends on edition | — |
| Employer's risk events | 17/18 | Depends | — |
| Late access/possession | 8.4 / 8.5 | 20 | — |
| Suspension by Employer | 8.9 | — | — |
| Exceptionally adverse weather | 8.5 | 23 | 23 |
| Force majeure / exceptional events | 18 | FM clause | — |
| Changes in law | 13.6 | — | — |

### Evidence Required
- Contemporary records (daily reports, site diaries, progress photos)
- Correspondence (letters, emails, meeting minutes)
- Programme updates (baseline vs actual)
- Resource records (labour, plant, material deliveries)
- Cost records (invoices, payroll, plant hire agreements)
- Weather records (Met Service data)
- Instructions and drawings (RFIs, AI, VO, SI)

---

## Extension of Time (EOT) {#eot}

### EOT Entitlement Checklist
1. ✅ Is there a contractual right to EOT for this event?
2. ✅ Was the event beyond the Contractor's control?
3. ✅ Did the event actually cause delay to the **critical path**?
4. ✅ Was notice given within the required period?
5. ✅ Has the Contractor taken reasonable steps to mitigate?

### EOT vs Prolongation Costs
| | EOT | Prolongation Costs |
|---|-----|-------------------|
| What | Extension of contract completion date | Compensation for additional time-related costs |
| Effect | Removes exposure to liquidated damages | Reimburses site overhead, preliminaries, etc. |
| Entitlement | May exist without cost entitlement | Requires both delay + cost entitlement |
| Example | Adverse weather: EOT yes, cost usually no | Employer variation: EOT yes, cost yes |

### Prevention Principle
- If the Employer causes delay and there is **no EOT mechanism** for that type of delay → liquidated damages clause may become unenforceable
- Employer cannot benefit from their own act of prevention
- Solution: ensure EOT clause covers all employer-caused delays
- **Peak Construction v Wilson Homes [2001]**: If no EOT clause, time becomes "at large" and employer can only claim general damages for delay (must prove actual loss)

---

## Delay Analysis Methods {#delay-analysis}

### SCL Protocol Methods (Society of Construction Law)

| Method | Description | Prospective/Retrospective | Complexity |
|--------|-------------|--------------------------|------------|
| **As-Planned vs As-Built** | Compare planned programme with actual completion | Retrospective | Low |
| **Impacted As-Planned** | Add delay events to baseline programme; measure impact | Prospective/Retrospective | Medium |
| **Collapsed As-Built** | Remove delay events from as-built programme; see what completion would have been | Retrospective | High |
| **Time Impact Analysis (TIA)** | Insert delay events sequentially into updated programme at point of impact | Both | Highest |
| **Windows Analysis** | Divide project into time windows; analyse delay in each window | Retrospective | High |

### As-Planned vs As-Built
- Simplest method — compare two programmes
- **Weakness**: does not prove causation; only shows what happened vs what was planned
- Useful as starting point; insufficient alone for complex claims
- Does not account for concurrent delays

### Impacted As-Planned
- Insert delay events into the **baseline** programme
- Shows theoretical impact of each event on planned completion
- **Weakness**: relies on accuracy of baseline programme; does not reflect actual progress
- Best used: early in project, prospective analysis, when as-built data limited

### Collapsed As-Built
- Start from **actual** completion → subtract delay events → shows "but-for" completion date
- More reliable than impacted as-planned (based on reality)
- **Weakness**: subjective selection of which events to collapse; hindsight bias
- Best used: post-completion analysis

### Time Impact Analysis (TIA)
- **Gold standard** for delay analysis
- Insert each delay event at the point it occurred into an updated programme
- Shows cumulative and individual impact of each delay
- **Requirements**: regularly updated programmes, good contemporaneous records
- **Weakness**: data-intensive; requires detailed programme updates throughout project
- Preferred by tribunals and courts for complex disputes

### Windows Analysis
- Divide project timeline into discrete periods (windows)
- Analyse critical path and delay causes within each window
- Shows how critical path shifted over time
- Good for projects with multiple delay events over long duration
- **Weakness**: window selection can be disputed; boundary effects

### Choosing the Right Method
- **Simple delays, early stage**: As-planned vs as-built or impacted as-planned
- **Complex delays, post-completion**: TIA or collapsed as-built
- **Long projects, many events**: Windows analysis
- **Tribunal preference**: TIA generally preferred; but any properly applied method accepted

> 📚 **For deeper coverage** — including Retrospective Longest Path, negative float & EOT entitlement, pacing delays, concurrent delay strategy (Malmaison/North Midland/City Inn), the full SCL Protocol 22 Core Principles, and 15 key case citations — see the companion skill `construction-claim-strategy` on ClawHub.

---

## Disruption Claims {#disruption}

### Disruption vs Delay
| | Delay | Disruption |
|---|-------|-----------|
| Effect | Late completion | Loss of productivity (may or may not cause delay) |
| Measurement | Time (days/weeks) | Cost (labour/plant inefficiency) |
| Critical path | Must affect critical path | Need not affect critical path |
| Example | Late drawings → cannot start activity | Working in congested conditions → slower output |

### Disruption Quantification Methods

| Method | Description | Reliability |
|--------|-------------|------------|
| **Measured Mile** | Compare productivity in disrupted vs undisrupted period on same project | Highest |
| **Earned Value Analysis** | Compare planned vs actual productivity using earned value metrics | High |
| **Industry Studies** (Leonard, MCAA) | Apply published productivity loss factors | Medium |
| **Total Cost** | Claim difference between planned and actual cost | Lowest (last resort) |

### Measured Mile
- Compare productivity of **same crew, same work** in disrupted vs undisrupted period
- Most persuasive method — uses project's own data
- Requires: identifiable undisrupted period on the same project
- **Weakness**: not always available if entire project was disrupted

---

## Prolongation Costs {#prolongation}

### Typical Prolongation Cost Heads
| Category | Examples |
|----------|---------|
| **Site overhead** | Site office rental, utilities, security, cleaning |
| **Staff costs** | Project manager, engineers, QS, supervisors, admin |
| **Plant & equipment** | Crane hire, scaffolding, hoisting equipment |
| **Insurance** | Extended CAR/EAR, third-party liability |
| **Bonds & guarantees** | Extended performance bond, advance payment guarantee |
| **Head office overhead** | Calculated using formula (Emden, Hudson, Eichleay) |
| **Finance charges** | Interest on capital tied up, bank charges |
| **Profit** | If contractually entitled (FIDIC: Cost + profit for some events) |

### Head Office Overhead Formulae

**Emden Formula** (UK/Singapore preferred):
```
HO overhead = (Contract Sum / Contract Period) × (HO overhead % / 100) × Delay Period
```

**Hudson Formula** (older, less favoured):
```
HO overhead = (HO overhead % in tender / 100) × (Contract Sum / Contract Period) × Delay Period
```

**Eichleay Formula** (US):
```
1. Allocable overhead = (Billings on contract / Total billings) × Total HO overhead
2. Daily rate = Allocable overhead / Days of performance
3. Claim = Daily rate × Days of delay
```

> **Singapore courts** generally prefer Emden; Hudson criticised because it uses tender allowance rather than actual overhead.

---

## Loss & Expense {#loss-expense}

### Common Heads of Claim
1. Prolongation costs (see above)
2. Disruption costs (productivity loss)
3. Acceleration costs (if instructed or constructively required)
4. Increased material/labour costs (if no price adjustment clause)
5. Finance charges / interest
6. Loss of profit (on delayed project or lost opportunities)
7. Additional preliminaries

### Proof Required
- **Direct loss**: flowing naturally from the breach — easier to prove
- **Consequential loss**: not flowing naturally — must show foreseeability (Hadley v Baxendale)
- Many construction contracts **exclude consequential loss** — check the contract

---

## Global Claims {#global-claims}

### What Is a Global Claim?
- Claim where multiple events caused loss, but claimant cannot (or does not) link specific events to specific losses
- Instead: total loss attributed to all events collectively

### Legal Position
- **Walter Lilly v Mackay [2012]**: Global claims are permissible BUT:
  - Must show at least some causal link between events and loss
  - Must show none of the events are the claimant's own fault
  - Tribunal can apportion as it sees fit
- **John Holland v Kvaerner [2004]** (Singapore): Global claims permitted where impractical to separate causes
- Generally disfavoured — should be last resort when separation genuinely impossible

---

## Concurrent Delay {#concurrent-delay}

### Definition
Two or more delay events occurring at the same time, where at least one is Employer risk and one is Contractor risk, both independently causing critical delay.

### Approaches by Jurisdiction

| Approach | Description | Jurisdiction |
|----------|-------------|-------------|
| **Dominant cause** | Identify the dominant cause of delay; that party bears responsibility | Less common now |
| **Apportionment** | Apportion delay between parties based on relative contribution | Singapore (preferred), some civil law |
| **Malmaison approach** | Contractor gets EOT but no prolongation costs | England & Wales (traditional) |
| **SCL Protocol** | If true concurrency, Contractor entitled to EOT but not costs | UK (influential, not binding) |

### Key Cases
- **Henry Boot v Malmaison [1999]**: Contractor entitled to EOT if employer delay event would have caused delay regardless of concurrent contractor delay
- **De Beers v Atos [2010]**: Applied Malmaison; EOT granted for concurrent delays
- **Saga Cruises v Fincantieri [2016]**: Burden on Contractor to demonstrate the employer event would have caused delay independently

### Singapore Position
- Courts have accepted **apportionment** of concurrent delays
- SO/Architect may grant partial EOT for employer-caused portion
- More flexible than strict English Malmaison approach

---

## Acceleration {#acceleration}

### Types
| Type | Description | Entitlement |
|------|-------------|-------------|
| **Instructed** | Employer directs Contractor to accelerate | Contractor entitled to costs |
| **Constructive** | Employer refuses valid EOT, forcing Contractor to accelerate to avoid LDs | Contractor may claim costs (harder to prove) |
| **Voluntary** | Contractor accelerates at own cost to recover own delays | No entitlement |

### Constructive Acceleration Requirements
1. Contractor was entitled to EOT
2. Contractor applied for EOT properly
3. EOT was wrongfully refused or not assessed
4. Contractor was facing LDs exposure
5. Contractor notified intent to accelerate
6. Contractor incurred additional costs to accelerate

---

## Notice Requirements Summary {#notices}

| Contract | Claim Notice | EOT Notice | Key Consequence |
|----------|-------------|------------|-----------------|
| FIDIC 2017 | 28 days from awareness (Cl. 20.2) | Under claim procedure | Time-barred |
| PSSCOC | 28 days from delay event (Cl. 23) | 28 days from delay event | May lose entitlement |
| SIA | Written notice required (Cl. 23) | Written notice required | May lose entitlement |
| NEC4 | Early warning (Cl. 15); compensation event notification (Cl. 61) | 8 weeks from awareness | Time-barred |

> **Golden rule**: When in doubt, give notice. A late or unnecessary notice is always better than no notice at all.


path: references/disputes.md
content: # Dispute Resolution in Construction — Reference

## Table of Contents
1. [ADR Spectrum](#adr-spectrum)
2. [Negotiation & Mediation](#mediation)
3. [Adjudication](#adjudication)
4. [DAB / DAAB (FIDIC)](#daab)
5. [Arbitration](#arbitration)
6. [Conflict Avoidance Board (CAB)](#cab)
7. [Key Cases](#cases)
8. [Enforcement](#enforcement)

---

## ADR Spectrum {#adr-spectrum}

| Method | Binding? | Speed | Cost | Formality |
|--------|----------|-------|------|-----------|
| Negotiation | No | Fast | Lowest | Informal |
| Mediation | No (unless settled) | Fast | Low | Semi-formal |
| Conciliation | Non-binding recommendation | Medium | Low-Medium | Semi-formal |
| Conflict Avoidance Board | Parties decide | Ongoing | Medium | Structured |
| Adjudication (statutory) | Temporarily binding | Very fast (weeks) | Medium | Formal |
| DAB/DAAB | Binding (subject to NOD) | Medium | Medium-High | Formal |
| Arbitration | Final & binding | Slow | High | Formal |
| Litigation | Final & binding | Slowest | Highest | Most formal |

---

## Negotiation & Mediation {#mediation}

### Mediation in Construction
- Facilitative process — mediator helps parties reach agreement, does not impose decision
- **Cheapest ADR mechanism** available (Gillion)
- Very high resolution rate at SMC (Singapore Mediation Centre)
- Typically completed in **1–2 days**: position paper → mediator → workshop → plenary
- Over 25 years of construction practice, **mediation is underused**
- Non-binding unless parties sign settlement agreement

### When Mediation Works Best
- Parties have ongoing relationship (want to preserve)
- Dispute is commercial rather than purely legal
- Both parties willing to compromise
- Confidentiality important
- Early in dispute lifecycle (before positions harden)

### When Mediation May Not Work
- One party acting in bad faith
- Significant power imbalance
- Pure legal question requiring binding precedent
- Party needs urgent interim relief

---

## Adjudication {#adjudication}

### Statutory Adjudication (Singapore SOP Act)
- **Temporarily binding** — pay now, argue later
- Designed for **cash flow** protection, not final resolution
- Cannot be contracted out of (Section 36 SOP Act)

### Process
1. Payment claim served
2. Payment response due within 21 days
3. If dispute → adjudication application within 7 days
4. Adjudication response within 7 days
5. Adjudicator determines within 7–14 days
6. Payment within 7 days of determination

### Key Principles
- **Respondent's payment response is critical** — failure to respond = "smash and grab" (respondent cannot raise withholding reasons)
- Determination is temporarily binding — can be reopened in arbitration/litigation
- Adjudicator's jurisdiction is narrow — only the payment claim in dispute
- Multiple adjudications possible — fresh claims each payment cycle

### UK Adjudication (Housing Grants Act 1996)
- Similar concept — 28-day determination
- "Pay now, argue later" principle
- Right cannot be contracted out of
- Widely used in UK construction industry

---

## DAB / DAAB (FIDIC) {#daab}

### Evolution
| Edition | Body | Type |
|---------|------|------|
| Pre-2017 | DAB (Dispute Adjudication Board) | Ad hoc or standing |
| 2017 | DAAB (Dispute Avoidance/Adjudication Board) | **Standing** (mandatory for Red/Yellow) |

### 2017 DAAB — Dual Role
1. **Avoidance**: Regular site visits, early engagement, informal opinions
2. **Adjudication**: Formal binding decisions on referred disputes

### Referral to DAAB
1. Either party refers dispute after Engineer's determination (or failure to determine)
2. DAAB has **84 days** to decide (extendable by agreement)
3. Decision is **binding** — immediate compliance required
4. NOD within **28 days** → dispute can proceed to arbitration
5. No NOD → decision becomes **final and binding**

### Non-Compliance
- 2017 clarification: non-compliance is a **separate dispute**
- Can be referred **directly to arbitration** — no need to go back to DAAB
- Can seek **partial award** for non-compliance while merits continue
- Persero case (Singapore) confirmed this approach

### DAAB vs SMC CAB

| Feature | FIDIC DAAB | SMC CAB |
|---------|-----------|---------|
| Primary role | Dispute resolution (reactive) | Dispute **avoidance** (proactive) |
| Mediation? | No (unless separately agreed) | **Yes** — strong emphasis (Rule 7) |
| Composition | 1 or 3 members | Default 1, flexible per issue |
| Decision timeframe | 84 days | No fixed timeframe |
| Site visits | Yes (standing DAAB) | Yes — predetermined agenda |
| Binding? | Yes (subject to NOD) | Parties decide per issue |

---

## Arbitration {#arbitration}

> 📚 **For arbitration tactics, prolongation strategies, and adjudication vs arbitration comparison** — including Common Law vs Civil Law approaches, preparation checklists, and expert engagement tips — see the companion skill `construction-claim-strategy` on ClawHub.

### Key Features in Construction
- **Final and binding** — limited grounds for challenge (procedural irregularity, public policy)
- **Confidential** — unlike court proceedings
- **Party autonomy** — parties choose arbitrators, procedure, seat, language
- **Expert arbitrators** — can appoint construction specialists (unlike judges)
- **International enforcement** — New York Convention (1958)

### Common Arbitral Institutions for Construction
| Institution | Abbreviation | Base |
|-------------|-------------|------|
| Singapore International Arbitration Centre | SIAC | Singapore |
| Singapore Institute of Arbitrators | SIArb | Singapore |
| International Chamber of Commerce | ICC | Paris |
| London Court of International Arbitration | LCIA | London |
| Hong Kong International Arbitration Centre | HKIAC | Hong Kong |
| Kuala Lumpur Regional Centre for Arbitration | AIAC | Kuala Lumpur |

### Seat vs Venue
- **Seat** = legal jurisdiction governing the arbitration (procedural law)
- **Venue** = physical location of hearings (can differ from seat)
- Seat determines: court supervisory jurisdiction, enforcement regime, available challenges

### Singapore as Arbitration Seat
- International Arbitration Act (IAA) — based on UNCITRAL Model Law
- Minimal court intervention policy
- Strong enforcement track record
- Party to New York Convention
- Preferred seat for Asia-Pacific construction disputes

### Multi-Party / Multi-Contract Arbitration
- Common in construction (employer, contractor, subcontractors, consultants)
- **Joinder**: bringing additional parties into existing arbitration
- **Consolidation**: merging related arbitrations
- Requires: arbitration agreement permitting joinder/consolidation, or institutional rules allowing it
- SIAC Rules 2016: provisions for joinder and consolidation

### Interim Measures
- Arbitral tribunal can grant interim relief (preservation of evidence, security for costs, injunctions)
- Emergency arbitrator provisions available under most institutional rules
- Court may also grant interim measures in support of arbitration

---

## Conflict Avoidance Board (CAB) {#cab}

### SMC Integrated ADR Framework
- Standalone rules by Singapore Mediation Centre
- Can be **plugged into any contract** — not tied to specific standard form
- Combines dispute avoidance + mediation + determination

### Four Functions

| Function | Description | Binding? |
|----------|-------------|----------|
| 1. Dispute Avoidance | Regular site meetings, risk monitoring, cooperation | N/A |
| 2. Informal Assistance | Non-binding guidance on issues before they become disputes | Non-binding |
| 3. Mediation (Rule 7) | Formal mediation — position papers, mediator, plenary | N/A (facilitative) |
| 4. Opinion/Determination | Formal decision on referred disputes | Parties decide |

### Site Visit Agenda
- Progress summary
- Risk register update
- Claims/issues status
- Mitigation measures
- Completion dates review

### Advantages
- Proactive — prevents disputes from escalating
- Flexible — parties choose binding or non-binding per issue
- Cost-effective — cheaper than arbitration
- Includes mediation — built-in facilitative process

### Limitations
- Not widely adopted yet
- Requires parties willing to engage in good faith
- No established enforcement mechanism (unlike FIDIC DAAB)

---

## Key Cases {#cases}

### Persero (Singapore)
- Indonesian construction project, arbitration seated in Singapore
- Issue: must non-compliance with DAB decision be re-referred to DAB before arbitration?
- **Held**: No — can go directly to arbitration
- Significance: clarified enforcement of DAB/DAAB decisions globally

### Henry Boot v Malmaison [1999] (UK)
- Concurrent delay case
- **Held**: Contractor entitled to EOT if employer delay event would have caused delay regardless of concurrent contractor delay
- Foundation of "Malmaison approach" to concurrent delay

### Walter Lilly v Mackay [2012] (UK)
- Global claims case
- **Held**: Global claims permissible where events and losses cannot be individually linked
- Must show: causal connection exists; no claimant-fault events included

### Costain v Bechtel — Channel Tunnel Rail Link (UK)
- NEC contract — Clause 10.1 (mutual trust and cooperation)
- **Held**: Clause 10.1 imposes obligation of honesty and proper conduct
- BUT does not override contract mechanism or create new rights
- Good faith = guiding behaviour, not source of claims

### Yam Seng v ITC [2013] (UK)
- First implied duty of good faith in relational/commercial contracts
- **Later limited** by Quantum Advisory — good faith only for very specific contract forms

### Peak Construction v Wilson Homes [2001] (UK)
- Prevention principle case
- **Held**: If no EOT mechanism for employer-caused delay → time at large → LDs unenforceable

---

## Enforcement {#enforcement}

### Enforcing Arbitral Awards
- **New York Convention (1958)**: Awards enforceable in 170+ countries
- Limited grounds for refusal (Article V): procedural irregularity, lack of jurisdiction, public policy
- Singapore: enforcement under IAA Section 19 or Arbitration Act Section 46

### Enforcing Adjudication Determinations
- Singapore SOP Act: determination enforceable as a judgment debt
- If respondent fails to pay → claimant can apply for judgment
- Court will enforce unless adjudicator lacked jurisdiction or breach of natural justice

### Enforcing DAAB Decisions
- Binding immediately — must comply even if NOD issued
- Non-compliance → refer to arbitration for enforcement (partial award)
- No need to re-refer to DAAB (Persero)


path: references/fidic.md
content: # FIDIC 2017 Suite — Clause Reference

## Table of Contents
1. [Red Book (Conditions of Contract for Construction)](#red-book)
2. [Yellow Book (Conditions of Contract for Plant & Design-Build)](#yellow-book)
3. [Silver Book (Conditions of Contract for EPC/Turnkey)](#silver-book)
4. [Emerald Book (Conditions of Contract for Underground Works)](#emerald-book)
5. [Key Clauses Across All Books](#key-clauses)
6. [Time-Bars & Notice Requirements](#time-bars)
7. [DAAB Procedures](#daab)
8. [2017 vs Pre-2017 Changes](#changes)

---

## Red Book

### Risk Allocation
- **Employer** bears: quantity risk, unforeseeable ground conditions, employer's design errors, force majeure (shared)
- **Contractor** bears: rate risk, workmanship, programme, resources, subcontractor management

### Key Clauses
| Clause | Subject | Key Points |
|--------|---------|------------|
| 1.1.29 | Cost | Defined as expenditure reasonably incurred (or to be incurred), including overhead but NOT profit |
| 1.1.80 | Time for Completion | Date/period stated in Contract Data |
| 4.12 | Unforeseeable Physical Conditions | Contractor entitled to EOT + Cost + Profit if unforeseeable |
| 8.4 | EOT | Contractor entitled if delayed by listed causes; must give notice under 20.2 |
| 8.8 | Delay Damages | Employer entitled to LDs per Contract Data |
| 13.1 | Right to Vary | Engineer may initiate; Contractor must comply unless unable |
| 13.3 | Variation Procedure | Instruction → Contractor proposes → Engineer responds |
| 14.3 | Interim Payment | Monthly applications; Engineer certifies within 28 days |
| 14.6 | IPC Issuance | Engineer issues IPC within 28 days of receiving Statement |
| 15.1 | Notice to Correct | Employer may give notice if Contractor fails obligations |
| 15.2 | Termination by Employer | 14 days notice after Notice to Correct not complied |
| 16.1 | Suspension by Contractor | If Employer fails to pay within 42 days of IPC due date |
| 16.2 | Termination by Contractor | 14 days notice for listed defaults |
| 17.2 | Indemnities | Mutual indemnities for death/injury and property damage |
| 18.1 | Exceptional Events | Force majeure equivalent; both parties may claim EOT |
| 20.1 | Claims (Contractor) | 28-day notice requirement from awareness |
| 20.2 | Claims Procedure | Detailed procedure for notices and substantiation |
| 21 | Disputes | DAAB standing board; 28 days for decision |

## Yellow Book

### Key Differences from Red Book
- **Contractor designs** based on Employer's Requirements
- **Fitness for purpose** obligation (higher than reasonable skill & care)
- **Employer's Requirements** replace Drawings/Specifications
- Contractor bears **design risk** — errors in Employer's Requirements may still be Contractor's risk if discoverable
- Clause 5.1: Contractor's design obligation — must satisfy Employer's Requirements
- Clause 5.8: Design errors — Contractor responsible for errors in design documents

### Design Liability
- Standard of care: **fitness for purpose** (unless amended)
- Contractor must check Employer's Requirements for errors/defects — Clause 5.1
- If Contractor discovers error → must notify Engineer (Clause 5.1)
- If Contractor fails to discover error it should have found → Contractor's risk

## Silver Book

### Key Differences
- **Maximum risk transfer** to Contractor
- No Clause 4.12 (unforeseeable physical conditions) — Contractor deemed to have allowed for all conditions
- No Clause 18 exceptional events relief in some versions
- No Engineer role — replaced by Employer's Representative (or Employer administers directly)
- Lump sum pricing — no re-measurement
- Contractor bears risk of: ground conditions, design, errors in Employer's Requirements

### When to Use
- Well-defined scope with experienced contractor
- Employer wants price certainty
- BOT/PPP/concession projects
- Risk: good contractors may avoid bidding; weak contractors underprice then claim

## Emerald Book

### Tunnelling-Specific Provisions
- **Geotechnical Baseline Report (GBR)** — defines expected ground conditions
- Conditions worse than GBR → Employer's risk
- Conditions better than GBR → Employer benefits (cost savings shared)
- Specific provisions for TBM (tunnel boring machine) operations
- Changed conditions mechanism tailored for underground works

---

## Key Clauses Across All Books {#key-clauses}

### Clause 20.2 — Claims (2017 Edition)

**Notice requirement**: 28 days from date the Contractor became aware (or should have become aware) of the event/circumstance.

**Procedure**:
1. **Notice of Claim** — within 28 days (time-bar)
2. **Fully detailed claim** — within 84 days of Notice, or as agreed
3. **Engineer's initial response** — within 42 days
4. **Engineer's determination** — if parties cannot agree

**Time-bar effect**: Failure to give 28-day notice → claim deemed time-barred. BUT:
- 2017 edition added Clause 20.2.7: Engineer must notify Contractor if notice was late
- If Engineer fails to notify → time-bar may not apply (debated)

### Clause 3.7 — Engineer's Determination (2017)
- Engineer must act **neutrally** (not as Employer's agent) when making determinations
- Must consult both parties before determining
- 42-day time limit for determination
- New in 2017 — strengthens Engineer's independence

### Clause 14.7 — Payment (2017)
- Employer must pay within **56 days** of receiving Statement (if no IPC issued)
- Late payment → financing charges (Clause 14.8)
- Non-payment → Contractor may suspend (Clause 16.1) or terminate (Clause 16.2)

---

## Time-Bars & Notice Requirements {#time-bars}

| Event | Notice Period | Clause | Consequence |
|-------|--------------|--------|-------------|
| Contractor's claim | 28 days from awareness | 20.2.1 | Time-barred if late |
| Employer's claim | 28 days from awareness | 20.1 | Time-barred if late |
| Fully detailed claim | 84 days from Notice | 20.2.4 | Claim may be reduced |
| Variation proposal | As instructed | 13.3 | — |
| Unforeseeable conditions notice | As soon as practicable | 4.12 | Entitlement affected |
| Notice to Correct | Reasonable period | 15.1 | May lead to termination |
| Dispute referral to DAAB | 28 days after Engineer's determination (or failure) | 21.4 | Lose right if not referred |
| NOD (Notice of Dissatisfaction) | 28 days after DAAB decision | 21.4.4 | Decision becomes final & binding |

---

## DAAB Procedures (2017) {#daab}

### Standing DAAB
- Appointed at commencement (Red/Yellow) — not ad hoc
- Regular site visits, predetermined agenda
- Available throughout project life

### Referral Process
1. Either party refers dispute to DAAB
2. DAAB has **84 days** to give decision (extendable)
3. Decision is **binding** — must be complied with immediately
4. If no NOD within 28 days → decision becomes **final and binding**

### Non-Compliance with DAAB Decision
- **2017 clarification**: Non-compliance = separate dispute → refer directly to arbitration
- No need to re-refer to DAAB first (Persero case confirmed this for Singapore)
- Can seek **partial award** in arbitration for non-compliance

### Persero Case (Singapore)
- Indonesian construction project, arbitration seated in Singapore
- Court of Appeal to Supreme Court
- Held: party can go directly to arbitration for non-compliance — no need to go back to DAAB
- Landmark case for FIDIC dispute resolution

---

## 2017 vs Pre-2017 Key Changes {#changes}

| Feature | Pre-2017 | 2017 Edition |
|---------|----------|-------------|
| Engineer's role | Agent of Employer | Must act **neutrally** on determinations (3.7) |
| DAAB | Ad hoc or standing (DAB) | **Standing DAAB** mandatory (Red/Yellow) |
| Notice of Claim | 28 days (strict time-bar) | 28 days + Engineer must notify if late (20.2.7) |
| Advance Warning | Not explicit | **Early Warning** mechanism added |
| Non-compliance enforcement | Unclear | Direct referral to arbitration confirmed |
| Variation by Employer | Less structured | More detailed procedure (13.3) |
| Programme | Less emphasis | Detailed programme requirements (8.3) |


path: references/legal_systems.md
content: # Legal Systems in Construction — Orientation Reference

> ⚠️ **Disclaimer:** This is a high-level orientation guide, not an authoritative treatise. It is composed as a general overview to help practitioners identify which legal tradition applies and what questions to ask. Specific claims about how individual jurisdictions handle good faith, time-bars, parol evidence, or other doctrines should be verified against jurisdiction-specific sources before reliance. Always consult local counsel for jurisdiction-specific advice.
>
> This is a workflow and analysis aid only. It does not constitute legal advice.

## Table of Contents
1. [Overview — Common Law vs Civil Law](#overview)
2. [Jurisdiction Map](#jurisdiction-map)
3. [Impact on Construction Contracts](#impact-on-contracts)
4. [Impact on Claims & Disputes](#impact-on-claims)
5. [FIDIC Across Legal Systems](#fidic-across-systems)
6. [Mixed / Hybrid Systems](#mixed-systems)
7. [Practical Implications](#practical-implications)

---

## Overview — Common Law vs Civil Law {#overview}

The world's legal systems broadly fall into two families, with significant implications for how construction contracts are interpreted, claims are assessed, and disputes are resolved.

### Common Law

- **Source of law:** Primarily judge-made law through court decisions (precedent/case law), supplemented by statutes
- **Doctrine of precedent (stare decisis):** Courts are bound by prior decisions of higher courts
- **Contract interpretation:** Courts look at the express terms, implied terms, and surrounding circumstances; extensive case law on interpretation principles
- **Flexibility:** Judges can develop the law incrementally through new decisions
- **Key feature:** Adversarial court system — parties present their cases, judge decides

### Civil Law

- **Source of law:** Primarily written codes and statutes (codified law)
- **Role of precedent:** Court decisions are persuasive but generally not binding in the same way
- **Contract interpretation:** Closer to the written code provisions; gap-filling through code principles rather than case law
- **Codification:** Rights, obligations, and remedies are systematically set out in codes
- **Key feature:** Inquisitorial system — judge takes a more active role in investigating facts

---

## Jurisdiction Map {#jurisdiction-map}

### Common Law Jurisdictions

| Jurisdiction | Notes |
|-------------|-------|
| **Singapore** | English common law heritage; strong statutory overlay (SOP Act, Building Control Act); active judicial development of construction law |
| **England & Wales** | Origin of common law; leading construction case law (Keating, Hudson's); TCC specialist court |
| **Hong Kong** | Common law; follows English precedent closely; active construction arbitration hub |
| **Australia** | Common law; state-based SOP legislation (varies by state); active case law development |
| **Malaysia** | Common law; CIPAA 2012 (statutory adjudication); follows English/Singapore precedent |
| **India** | Common law; Arbitration & Conciliation Act 1996; extensive construction arbitration |
| **United States** | Common law (federal + state); extensive statutory codes alongside case law; AIA/ConsensusDocs standard forms |
| **Canada** | Common law (except Quebec — civil law); provincial construction lien/prompt payment legislation |

### Civil Law Jurisdictions

| Jurisdiction | Notes |
|-------------|-------|
| **Russia** | Civil code-based; government-codified pricing norms (ГЭСН/ФЕР/ТЕР); disputes resolved through code interpretation |
| **France** | Napoleonic civil code; strong codified construction obligations (décennale liability); CCAG standard forms |
| **Germany** | BGB (Civil Code) + VOB (construction-specific regulations); highly codified defects liability |
| **Japan** | Civil code-based; influenced by German civil law; strong emphasis on amicable settlement |
| **China** | Civil code (2021); extensive construction regulations; FIDIC adapted to local civil code framework |
| **UAE** | Civil code (Federal Law No.5/1985); FIDIC widely used but interpreted through civil code principles |
| **Saudi Arabia** | Civil law influenced by Sharia; government standard forms; FIDIC adapted locally |
| **South Korea** | Civil code-based; influenced by Japanese/German law; active infrastructure market |

### Mixed / Hybrid Systems {#mixed-systems}

| Jurisdiction | System | Notes |
|-------------|--------|-------|
| **Louisiana (US)** | Civil law within common law country | French/Spanish legal heritage; Louisiana Civil Code governs contracts |
| **Quebec (Canada)** | Civil law within common law country | Civil Code of Quebec; different construction lien regime |
| **Scotland** | Mixed civil/common law | Distinct from English law; own construction adjudication regime |
| **South Africa** | Mixed Roman-Dutch + common law | Roman-Dutch private law; English procedural law |
| **Philippines** | Mixed civil/common law | Spanish civil code heritage + American common law influence |

---

## Impact on Construction Contracts {#impact-on-contracts}

### Contract Interpretation

| Aspect | Common Law | Civil Law |
|--------|-----------|-----------|
| **Primary source** | Express contract terms + implied terms | Written code provisions + contract terms |
| **Gap-filling** | Implied terms (business efficacy, officious bystander tests); case law | Code provisions fill gaps automatically |
| **Ambiguity** | Contra proferentem; surrounding circumstances (factual matrix) | Literal interpretation of code; good faith principle |
| **Good faith** | Generally no implied duty (except some jurisdictions, e.g. Australia) | Fundamental principle — parties must act in good faith |
| **Parol evidence** | Generally excluded (written contract prevails) | More receptive to extrinsic evidence of intent |
| **Unfair terms** | Limited judicial intervention (freedom of contract) | Courts may strike down unconscionable terms more readily |

### Standard Forms Across Systems

| Form | Origin System | Used In |
|------|--------------|---------|
| **FIDIC** | Swiss (civil law origin) | International — both common and civil law jurisdictions |
| **NEC** | English (common law) | UK, international (growing adoption) |
| **PSSCOC** | Singapore (common law) | Singapore public sector |
| **SIA** | Singapore (common law) | Singapore private sector |
| **AIA / ConsensusDocs** | US (common law) | United States |
| **JCT** | English (common law) | UK, former Commonwealth |
| **CCAG** | French (civil law) | France, Francophone countries |
| **VOB** | German (civil law) | Germany, German-influenced markets |

---

## Impact on Claims & Disputes {#impact-on-claims}

### Claims Assessment

| Aspect | Common Law | Civil Law |
|--------|-----------|-----------|
| **Precedent** | Prior court decisions are binding/persuasive — cite relevant cases | Precedent is persuasive but not formally binding |
| **Time-bars** | Strictly enforced (see *Multiplex v Honeywell*) | May be moderated by good faith principles |
| **Causation** | Detailed causation analysis required; concurrent delay case law | Code provisions on causation; less granular case law |
| **Quantum** | Extensive methods developed through case law (Eichleay, Hudson, Emden) | Quantum often assessed by court-appointed experts |
| **Expert evidence** | Party-appointed experts; hot-tubbing in some jurisdictions | Court-appointed experts more common |
| **Discovery/disclosure** | Broad disclosure obligations | More limited document production |

### Dispute Resolution

| Aspect | Common Law | Civil Law |
|--------|-----------|-----------|
| **Adjudication** | Statutory in many jurisdictions (UK, SG, AU, MY) | Less common; not typically statutory |
| **Arbitration** | Well-established; party autonomy; institutional rules (ICC, SIAC, LCIA) | Well-established; often ICC; court involvement varies |
| **Mediation** | Growing; voluntary or court-ordered | Growing; mandatory in some jurisdictions (Italy, France) |
| **Enforcement** | New York Convention (arbitral awards); direct court enforcement | New York Convention; enforcement procedures vary |
| **Appeals** | Limited grounds (arbitration); broader in litigation | Broader appeal rights in some civil law courts |

---

## FIDIC Across Legal Systems {#fidic-across-systems}

FIDIC contracts originated in Switzerland (civil law) but are widely used across both legal traditions. Key considerations:

### In Common Law Jurisdictions
- Clause interpretation guided by case law (e.g. *Obrascon Huarte Lain v AG* [2015] EWHC 1918 — interpretation of FIDIC Sub-Clause 20.1 notice requirements)
- Time-bar provisions strictly enforced
- Engineer/Employer's Representative decisions subject to judicial review on reasonableness
- Implied terms may supplement express FIDIC provisions

### In Civil Law Jurisdictions
- Code provisions may override or supplement FIDIC terms
- Good faith obligations apply even where FIDIC is silent
- Mandatory local law provisions cannot be contracted out of
- Court-appointed experts may re-assess Engineer's determinations
- Some civil law jurisdictions require FIDIC to be adapted to local codes (e.g. UAE, China)

### Practical Tip
When using FIDIC internationally, always check:
1. **Governing law** — which legal system applies?
2. **Mandatory local provisions** — what can't be contracted out of?
3. **Particular Conditions** — how has the standard form been modified for local law?
4. **Dispute forum** — where will disputes be heard, and under what rules?
5. **Enforcement** — can awards/judgments be enforced in the relevant jurisdictions?

---

## Practical Implications {#practical-implications}

### For Claims Practitioners

**Working in common law jurisdictions:**
- Research case law thoroughly — precedent strengthens arguments
- Strict compliance with notice provisions (time-bars are real)
- Prepare detailed expert reports with methodology transparency
- Expect broad document disclosure obligations
- Use established quantum methods (cite the cases that support them)

**Working in civil law jurisdictions:**
- Study the applicable code provisions carefully — they fill gaps
- Good faith arguments carry weight (both ways)
- Court-appointed experts may override party experts
- Document production may be more limited
- Code interpretation principles differ from common law rules

**Working across both systems (international projects):**
- Identify the governing law FIRST — it determines everything
- Don't assume common law interpretation principles apply to civil law contracts (or vice versa)
- Check for mandatory local law provisions that cannot be overridden by contract
- Consider the enforcement jurisdiction for disputes
- FIDIC's Sub-Clause 1.4 (governing law) is critical — never leave it blank

### For the Companion Skills

| Skill | Legal System Context |
|-------|---------------------|
| **open-construction-estimate** | Russian civil law — government-codified pricing norms (ГЭСН/ФЕР/ТЕР); useful for methodology and international projects in CIS markets |
| **afrexai-construction-estimator** | US common law — RSMeans-based; bid preparation, change orders, value engineering methodology applicable internationally |

---

*This reference is a general guide to legal system differences. Construction law varies significantly within each tradition. Always verify the specific governing law, local statutes, and applicable case law for the jurisdiction in question.*

> This is a workflow and analysis aid only. It does not constitute legal advice.


path: references/procurement.md
content: # Procurement & Tendering — Reference

## Table of Contents
1. [Procurement Strategy Framework](#strategy)
2. [MDB Procurement Principles](#mdb)
3. [Tendering Methods](#tendering)
4. [Bid Evaluation Methods](#evaluation)
5. [Prequalification](#prequalification)
6. [Collaborative Contracting](#collaborative)
7. [Compliance in Tenders](#compliance)

---

## Procurement Strategy Framework {#strategy}

### Three Phases

| Phase | Focus | Activities |
|-------|-------|-----------|
| 1. Analysis | Understand context | Pre-investment studies, stakeholder ID, SWOT, market analysis |
| 2. Choices | Strategic decisions | Contract type, delivery method, packaging, risk allocation |
| 3. Planning | Implementation prep | Procurement plan, timeline, bidding documents, evaluation criteria |

### Procurement Strategy Decisions

**Project characteristics** → assess complexity, size, duration, risk profile
**Packaging decisions** → single contract vs multiple packages vs lots
**Pricing strategy** → lump sum, remeasurement, cost-plus, target cost
**Risk allocation** → who bears design, ground, weather, price risks
**Competition level** → open, limited, direct, framework

### Fitness-for-Purpose Procurement
Procurement must reflect:
- Project complexity (simple works ≠ mega infrastructure)
- Institutional capacity (can employer manage multiple contracts?)
- Risk profile (who is best placed to manage which risks?)
- Market conditions (are qualified contractors available?)
- Implementation timeline (fast-track vs traditional sequencing)

> Standardised approaches may be unsuitable. Strategy must be fit for purpose, not one-size-fits-all.

---

## MDB Procurement Principles {#mdb}

### Core Principles (ADB / IFI Framework)

| Principle | Meaning |
|-----------|---------|
| Economy | Optimal price without harming project viability |
| Efficiency | Procurement proportionate to complexity and risk |
| Fairness | Equal treatment of bidders; credible complaint mechanisms |
| Transparency | Public access to procurement information |
| Quality | Outputs suitable for project objectives |
| Value for Money | Lifecycle cost and socio-environmental benefits considered |

### Value for Money vs Lowest Price
MDB procurement does NOT require award to lowest bidder. Award based on:
- Lifecycle cost (total cost of ownership)
- Technical quality
- Risk allocation
- Sustainability impact
- Delivery capability

### Risk Allocation Principle
Allocate risk to the party best able to:
1. Identify that risk
2. Control that risk
3. Mitigate that risk
4. Absorb that risk

Incorrect allocation → pricing inflation, claims escalation, programme delay, disputes.

---

## Tendering Methods {#tendering}

### Main Methods

| Method | Description | When Used |
|--------|-------------|-----------|
| Open competitive (with PQ) | Prequalification → shortlist → bid | Large/complex projects |
| Open competitive (without PQ) | Direct bidding, qualification with bid | Simple projects |
| Limited/Restricted | Invite specific firms | Specialist work, limited market |
| Competitive dialogue | Discussion with bidders before final tender | Very complex, unclear specs |
| Negotiated/Direct | Direct negotiation with selected vendor | Emergency, sole source, proprietary |
| E-Reverse auction | Online reverse bidding | Routine procurement |
| Framework agreement | Pre-qualified pool at predefined rates | Repetitive works |

### Negotiated Procedure — Justification
- Emergency/urgency
- Small quantity — competitive tendering not feasible
- Proprietary equipment — only original supplier compatible
- Remote locations — limited contractor access
- Usually requires minimum 3 quotations

---

## Bid Evaluation Methods {#evaluation}

| Method | Description | When Used |
|--------|-------------|----------|
| Lowest Evaluated Cost | Award to lowest compliant bid | Clearly defined specifications |
| QCBS (Quality & Cost Based) | Weighted technical + financial score | Complex projects needing quality |
| Fixed Budget Selection | Best technical score within fixed budget | Budget-constrained projects |
| Least Cost Selection | Cheapest technically compliant bid | Routine/standardised assignments |
| Quality-Based Selection | Best technical score wins | Highly specialised/critical work |

> MDB projects typically apply weighted evaluation criteria rather than price-only selection.

### Evaluation Process
1. Preliminary examination (completeness, eligibility, signatures)
2. Technical evaluation (scored against published criteria)
3. Financial evaluation (arithmetic check, currency conversion, price adjustment)
4. Combined evaluation (weighted score or pass/fail technical + lowest price)
5. Post-qualification (verify winner's capacity)

### Abnormally Low Bids
- May indicate: misunderstanding of scope, unsustainable pricing, error
- Evaluator should: request clarification, verify cost breakdown
- Risk: contractor wins → fails → project hostage → termination + re-tender
- Some MDB rules allow rejection of abnormally low bids

---

## Prequalification {#prequalification}

### PQ Document Contents
1. Employer identity & representative
2. Project description & scope
3. Qualification criteria (technical, financial, experience)
4. Required documents (financial statements, project references, personnel CVs)
5. Evaluation methodology
6. Timeline

### Qualification Criteria

| Category | Examples |
|----------|---------|
| Financial | Annual turnover, liquid assets, credit facilities, audited accounts |
| Technical | Similar project experience, equipment, methodology |
| Personnel | Key staff qualifications and experience |
| Legal | Registration, licensing, litigation history, debarment status |
| Safety | Safety record, certifications (ISO 45001) |
| Quality | Quality management system (ISO 9001), CONQUAS history |

---

## Collaborative Contracting {#collaborative}

### Spectrum of Collaboration

| Level | Type | Risk Culture |
|-------|------|-------------|
| Low | Traditional/Binary | Claims culture — adversarial |
| Medium | Intermediate (NEC partnering, VE incentives) | Mixed |
| High | Full Alliancing | Collaborative — "project first" |

### Alliance Governance Structure

| Level | Body | Function |
|-------|------|----------|
| Strategic | Alliance Leadership Team (ALT) | Strategic decisions and oversight |
| Operational | Alliance Management Team (AMT) | Operational coordination and issue resolution |
| Execution | Integrated Delivery Teams | Daily execution responsibility |

These structures support collective decision-making and replace traditional adversarial contract hierarchies.

### Target Cost & Pain/Gain
1. Parties agree target cost
2. Contractor reimbursed for all actual costs + fixed profit
3. At completion: actual < target → gain shared; actual > target → pain shared
4. Creates incentive to optimise without incentive to inflate

### Key Features of Alliancing
- Shared project objectives (not individual scope targets)
- Joint management team
- Risk register — risks discussed and mitigated together
- Early engagement — contractor involved before final design
- No-claim/no-blame culture
- Open book — full cost transparency
- Conflict avoidance (CAB/dispute board)

### Heathrow T5 — Landmark Example
- £4.2 billion project
- BAA absorbed ALL risks
- Target cost with pre-agreed profit margins
- Pain/gain incentive mechanism
- Only 6 major disputes over 5 years; only 1 went to arbitration
- Remarkable for project of this size and complexity

### NEC — Only Standard Form with Alliancing
- Option C = target cost
- Clause 10.1 = mutual trust and cooperation (express obligation)
- Only mainstream form with built-in alliancing/partnering option
- FIDIC has NO alliancing form (reportedly working on one)

---

## Compliance in Tenders {#compliance}

### Key Compliance Areas

| Area | Key Legislation/Framework |
|------|--------------------------|
| Anti-bribery | FCPA (US), UK Bribery Act, French Sapin II |
| Sanctions | US OFAC, EU Sanctions, UN Security Council |
| Modern slavery | UK Modern Slavery Act, US TVPA, ILO conventions |
| ESG | EU CS3D, MDB environmental/social safeguards |
| Integrity | ADB Integrity Policy, World Bank sanctions framework |

### MDB Prohibited Practices (ADB)
- Corrupt, Fraudulent, Coercive, Collusive, Abuse, Conflict of Interest
- Plus: Obstructive practices, violation of sanctions
- Sanctions: debarment (fixed/indefinite), conditional non-debarment, reprimand
- Cross-debarment across all major MDBs

### Sanctions Screening
- Must check: beneficial ownership, ultimate controlling parties
- Indirect participation risks (JV partners, subcontractors, suppliers)
- Supply chain exposure
- Continuous screening, not one-time
- Debarment consequences: cross-default in bank financing, reputational exclusion

### Compliance-by-Design
- Beneficial ownership disclosure
- Sanctions screening (continuous)
- Supply chain traceability and audit rights
- Internal compliance programme (demonstrate effectiveness, not just existence)
- Whistleblowing mechanisms
- Training and disciplinary regime


path: references/singapore.md
content: # Singapore Construction Contracts — Reference

> 📂 **Live BCA updates:** BCA publishes circulars at https://www1.bca.gov.sg/resources/circulars/. Recommend mirroring locally (e.g. `bca-circulars/` workspace folder, refreshed weekly via heartbeat/cron) and **consulting the latest circulars first** for current requirements on SOP Act timelines, plan fees, CORENET-X, BC1/structural codes, cost-sharing schemes, productivity grants, and buildability — BCA updates can change procedural requirements without warning.

## Table of Contents
1. [PSSCOC (Public Sector Standard Conditions of Contract)](#psscoc)
2. [SIA Conditions (Singapore Institute of Architects)](#sia)
3. [Building and Construction Industry Security of Payment Act (SOP Act)](#sop-act)
4. [BCA Regulatory Framework](#bca)
5. [SIArb (Singapore Institute of Arbitrators)](#siarb)

---

## PSSCOC {#psscoc}

### Overview
- Standard form for **Singapore government projects**
- Administered by BCA (Building and Construction Authority)
- Two editions: **Construction Works** and **Design & Build**
- Employer: typically a government agency (LTA, PUB, JTC, HDB, NParks, etc.)

### Key Features
| Feature | Detail |
|---------|--------|
| Contract type | Re-measurement (Construction Works) or Lump Sum (D&B) |
| Superintending Officer (SO) | Engineer-equivalent; appointed by Employer |
| SO's authority | Acts as Employer's agent (NOT neutral like FIDIC 2017 Engineer) |
| Variations | SO may issue variation orders; valuation per contract rates or fair rates |
| EOT | Contractor must apply within 28 days of delay event |
| Liquidated damages | Specified in Contract Data; deducted from payments |
| Defects Liability Period | Typically 12 months (maintenance period) |
| Retention | 5% capped at specified limit; half released at completion, half after DLP |
| Dispute resolution | Mediation → Arbitration (SIA Arbitration Rules or SIAC) |

### Key Clauses — Construction Works Edition
| Clause | Subject | Key Points |
|--------|---------|------------|
| 2 | SO's duties | Authority from Employer; acts as agent |
| 7 | Assignment & subcontracting | Written consent required for assignment |
| 14 | Variations | SO instructs; Contractor must comply |
| 14(4) | Valuation of variations | Contract rates → fair rates → daywork |
| 20 | Possession of site | Employer grants possession per programme |
| 23 | EOT | 28-day notice requirement; SO assesses entitlement |
| 24 | Liquidated damages | Deducted per day/week of delay |
| 25 | Completion certificate | SO certifies when works substantially complete |
| 27 | Defects | Contractor must rectify during maintenance period |
| 32 | Interim payments | Monthly valuations by SO |
| 33 | Final account | Submit within period stated; SO certifies |
| 34 | Set-off | Employer may set off amounts owed |
| 37 | Determination by Employer | Listed defaults; notice required |
| 38 | Determination by Contractor | Non-payment, suspension, employer default |
| 40 | Settlement of disputes | Mediation → Arbitration |

### EOT Under PSSCOC
- **28-day notice** from commencement of delay event
- Must include: cause, expected duration, mitigation measures
- SO assesses and grants/refuses within reasonable time
- Grounds: variations, exceptionally adverse weather, employer's default, force majeure, unforeseen ground conditions (if applicable)
- **Concurrent delay**: SO may apportion — Singapore approach allows partial EOT

### Variations Under PSSCOC
- SO may instruct additions, omissions, changes
- Valuation hierarchy: contract rates → analogous rates → fair valuation → daywork
- Contractor must comply first, dispute valuation later
- No automatic entitlement to profit on variations (depends on contract)

---

## SIA Conditions {#sia}

### Overview
- Standard form for **Singapore private sector** building works
- Published by Singapore Institute of Architects
- Current edition: **SIA Conditions 9th Edition (2010)** with amendments
- Tripartite structure: Employer, Contractor, Architect (and QS)

### Key Features
| Feature | Detail |
|---------|--------|
| Contract type | Lump sum (with provisional/prime cost sums) |
| Architect | Contract administrator; certifies payments, variations, completion |
| QS role | Valuation of variations; interim and final accounts |
| Clerk of Works | Employer's site representative |
| Nominated subcontractors | Architect may nominate; Contractor must employ (with right to object) |
| Payment | Architect certifies interim payments; 30 days to pay |
| Retention | Typically 5% capped; released progressively |
| DLP | Typically 12 months |
| Dispute resolution | Mediation → Arbitration (SIA Arbitration Rules) |

### Key Clauses
| Clause | Subject | Key Points |
|--------|---------|------------|
| 1 | Definitions | Key defined terms |
| 2 | Architect's duties | Certification, instruction, supervision |
| 11 | Variations | Architect instructs; valuation by QS |
| 14 | Contract sum adjustment | Provisional sums, PC sums, prime cost |
| 23 | EOT | Written notice required; Architect certifies |
| 24 | Delay certificate & LDs | Architect issues delay certificate; LDs apply |
| 25 | Completion certificate | Architect certifies substantial completion |
| 27 | Maintenance & defects | Contractor rectifies during DLP |
| 30 | Certificates & payment | Architect certifies; Employer pays within 30 days |
| 31 | Payment terms | Interim, progress, final payments |
| 32 | Set-off and counterclaim | Employer's right to set off |
| 33 | Determination by Employer | Default, insolvency, abandonment |
| 34 | Determination by Contractor | Non-payment, employer interference |
| 37 | Arbitration | Disputes referred to arbitration |

### SIA vs PSSCOC Key Differences
| Feature | SIA | PSSCOC |
|---------|-----|--------|
| Sector | Private | Public (government) |
| Administrator | Architect | Superintending Officer |
| Payment cert | Architect certifies | SO certifies |
| Nominated subcon | Yes (extensive provisions) | Less common |
| Payment period | 30 days from certificate | Per contract terms |
| Dispute resolution | Mediation → Arbitration | Mediation → Arbitration |
| Standard of independence | Architect has dual role (employer's agent + certifier) | SO is Employer's agent |

---

## SOP Act {#sop-act}

### Building and Construction Industry Security of Payment Act (Cap. 30B)

### Purpose
- Ensures **timely payment** in the construction industry
- Creates a **right to progress payments** regardless of contract terms
- Provides **statutory adjudication** as fast-track dispute resolution for payment disputes

### Key Provisions

| Section | Subject | Key Points |
|---------|---------|------------|
| 5 | Right to progress payments | Every person who carries out construction work has a right to payment |
| 6 | Amount of progress payment | Based on contract terms; if silent, based on value of work done |
| 10 | Payment claims | Served by claimant on respondent; must state claimed amount |
| 11 | Payment responses | Respondent must serve response within 21 days (or contract period) |
| 12 | Entitlement to make adjudication application | If payment response not served, or dispute on amount |
| 13 | Adjudication application | Must be made within 7 days after entitlement arises |
| 15 | Adjudication response | Within 7 days of receiving the application |
| 17 | Determination | Adjudicator determines within 7-14 days |
| 21 | Direct payment from principal | If respondent fails to pay, claimant may seek payment from higher-tier party |
| 22 | Lien on unpaid goods | Right to lien on unfixed goods |
| 36 | No contracting out | Provisions cannot be contracted out of |

### Critical Timelines
| Action | Timeline |
|--------|----------|
| Payment claim | Per contract or monthly (last day of month) |
| Payment response | 21 days from payment claim (or contract period, whichever shorter) |
| Adjudication application | Within 7 days after entitlement arises |
| Adjudication response | 7 days from receiving application |
| Adjudicator's determination | 7 days (extendable to 14 days with consent) |
| Payment of adjudicated amount | 7 days from determination |

### Key Principles
1. **Pay first, argue later** — adjudication decisions must be complied with; challenge in court/arbitration later
2. **Cannot contract out** — any clause purporting to exclude SOP Act rights is void
3. **Repeat claims** — claimant can serve fresh payment claim for same work in next payment cycle
4. **"Smash and grab"** — if no payment response served, respondent cannot raise reasons for withholding in adjudication

### 2018 Amendments (Key Changes)
- Expanded definition of "construction work"
- Clarified cross-contract set-off limitations
- Strengthened adjudication enforcement provisions

---

## BCA Regulatory Framework {#bca}

### Building and Construction Authority
- Statutory board under Ministry of National Development
- Regulates construction industry in Singapore
- Website: https://www1.bca.gov.sg/

### Key Functions
- Building plan approval and permits
- Contractor registration (financial grading: CW01-CW02, L1-L6, A1-A2, C1-C3)
- Construction quality management (CONQUAS)
- Safety regulations (WSH Act coordination)
- Green building requirements (Green Mark scheme)
- Buildability and constructability requirements
- Procurement frameworks and standard contract forms

### BCA Official Resources & Downloads

#### Standard Contract Forms
- **PSSCOC landing page**: https://www1.bca.gov.sg/growth-and-transformation/procurement/standard-contract-forms/public-sector-standard-conditions-of-contract-psscoc/
- **PSSCOC for Construction Works 2020 (8th Ed, Jul 2020)** [PDF]: https://www1.bca.gov.sg/docs/default-source/docs-corp-procurement/psscoc-for-construction-works-2020.pdf
- **PSSCOC for Design & Build 2020 (7th Ed, Jul 2020) — List of Amendments** [PDF]: https://www1.bca.gov.sg/docs/default-source/docs-corp-procurement/list-of-amendments-psscoc-design-build-2020.pdf
- **Standard Contract Forms overview**: https://www1.bca.gov.sg/growth-and-transformation/procurement/standard-contract-forms/
- Note: PSSCOC Construction Works Cl 4.5(2) was amended on 21 June 2024 — always check the latest List of Amendments

#### Procurement Frameworks
- **Procurement main page**: https://www1.bca.gov.sg/growth-and-transformation/procurement/
- **Collaborative Contracting**: https://www1.bca.gov.sg/growth-and-transformation/procurement/progressive-procurement-approaches/collaborative-contracting/
- **Early Contractor Involvement (ECI)**: https://www1.bca.gov.sg/growth-and-transformation/procurement/progressive-procurement-approaches/early-contractor-involvement-eci/
- **NEC4 Contract launch in Singapore**: https://www1.bca.gov.sg/resources/newsroom/launch-of-nec4-contract-for-construction-and-engineering-projects-in-singapore/

#### Circulars
- **BCA Circulars page**: https://www1.bca.gov.sg/resources/circulars/
- Check for circulars on: cost-sharing schemes, material cost adjustments, ex-gratia frameworks, COVID/geopolitical disruption relief

#### Worked example: Ex-gratia cost-sharing pattern (BCA → implementing agency → contractor)

When BCA issues an ex-gratia cost-sharing circular, the rollout typically follows a three-tier pattern:

1. **BCA framework circular** — sets policy: co-share rate, coverage period, eligible contract criteria, computation method, heads of cost
2. **Implementing agency circular** (HDB, LTA, PUB, JTC, NParks) — operationalises the BCA framework: lists eligible contracts, fixes monthly reference rates per BCA advisory, sets submission deadlines, prescribes claim format
3. **Contractor claim** — standalone submission (separate from monthly progress payment) with cover letter + claim summary + substantiation

**Reference case study — Diesel & Bitumen Ex-Gratia (Mar–May 2026):**
- BCA Circular: 7 Apr 2026 (post Middle East price spike)
- Co-share: 50% of Direct Additional Cost
- Coverage: 1 Mar 2026 – 31 May 2026
- Eligibility: ongoing critical public sector contracts; tender closing date before coverage start; last phase not certified complete
- HDB implementation: 30 Apr 2026 (Annexes A & B listing eligible BTO contracts)

**Computation formula:**

```
Direct Additional Cost = Quantity used in month × (Month rate − Base rate)
Ex-gratia payment      = Direct Additional Cost × Co-share %
```

**Heads of cost — diesel typically covers:**
- Plant & equipment (cranes, piling rigs, excavators, bulldozers, rollers)
- Haulage / disposal vehicles (tipper trucks)
- Site overhead equipment (generators)
- **Excluded:** supplier transport surcharges (diesel attribution unquantifiable)

**Substantiation expected:**
- Fuel Pump Meter Records
- Delivery Orders
- Supplier Invoices
- Subcontractor & supplier consolidated usage figures

**Compliance traps:**
- Claims must be **standalone**, not bundled with progress payment
- Submission deadlines are **strict** (typically ~2 weeks post-month) — implementing agencies generally do not entertain late or augmenting appeals
- Incomplete substantiation may be **excluded entirely** from co-sharing computation
- **Pass-through obligation:** main contractor must forward the relevant share to subcontractors and suppliers; wrongful withholding can trigger debt recovery, poor performance rating, and tendering restriction
- **Ex-gratia, not contractual** — no entitlement basis; agency assessment is final, no adjudication route

#### Safety & Standards
- **Building Control Act**: https://www1.bca.gov.sg/safety-and-standards/building-control-act/
- **Construction Quality (CONQUAS)**: https://www1.bca.gov.sg/safety-and-standards/construction-quality/
- **Applications & Licences**: https://www1.bca.gov.sg/safety-and-standards/applications-and-licenses/

#### Growth & Transformation
- **Industry Transformation Map (ITM)**: https://www1.bca.gov.sg/growth-and-transformation/built-environment-industry-transformation-map-itm/
- **Manpower**: https://www1.bca.gov.sg/growth-and-transformation/manpower/
- **Grants & funded programmes**: https://www1.bca.gov.sg/growth-and-transformation/grants-and-funded-programmes/
- **e-Services / Key Construction Info**: https://www1.bca.gov.sg/e-services/key-construction-information/

### Contractor Registration
| Grade | Tendering Limit |
|-------|----------------|
| CW01 | Up to $325,000 |
| CW02 | Up to $650,000 |
| L1 | Up to $1.3M |
| L2 | Up to $3.25M |
| L3 | Up to $6.5M |
| L4 | Up to $13M |
| L5 | Up to $40M |
| L6 | Up to $85M |
| A1 | Up to $200M |
| A2 | Unlimited |
| C1-C3 | Civil engineering (separate grading) |

---

## SIArb {#siarb}

### Singapore Institute of Arbitrators

### Membership Pathway
| Level | Requirements |
|-------|-------------|
| Associate | Entry-level; relevant qualifications |
| Member | Entry Course + experience |
| Fellow | Fellowship Assessment Course + substantial experience |

### Entry Course
- Covers: arbitration law, procedure, evidence, drafting awards
- Assessment: written examination
- Prepares for appointment as arbitrator in construction disputes

### Fellowship Assessment Course
- Advanced: complex arbitrations, multi-party disputes, expert evidence
- Mock arbitration exercises
- Assessment: written + oral components

### SIArb Arbitration Rules
- Commonly used in Singapore construction arbitrations
- Referenced in both SIA and PSSCOC as dispute resolution mechanism
- Administered by SIArb secretariat
- Compatible with SIAC (Singapore International Arbitration Centre) for international disputes

### SMC Conflict Avoidance Board (CAB)
- Standalone rules by Singapore Mediation Centre
- Can be plugged into any contract
- 4 functions: dispute avoidance, informal assistance, mediation, determination
- Primary emphasis on **dispute avoidance** (proactive) vs FIDIC DAAB (reactive)
- Cheapest ADR mechanism available
- Combines avoidance + mediation + determination in one framework


path: scripts/claims_template.py
content: #!/usr/bin/env python3
"""
Claims Letter / Notice Template Generator
Generates structured claim notices, EOT applications, and response letters
based on contract form and claim type.

Usage:
    python3 claims_template.py --form fidic-red --type notice-of-claim --output notice.md
    python3 claims_template.py --form psscoc --type eot-application --output eot.md
    python3 claims_template.py --form sia --type variation-claim --output vo_claim.md
    python3 claims_template.py --form fidic-red --type interim-claim --output interim.md
    python3 claims_template.py --form fidic-red --type disruption-claim --output disruption.md
    python3 claims_template.py --list
"""

import argparse
import sys
from datetime import datetime

VISIBLE_DISCLAIMER = "> ⚠️ **Disclaimer:** This template is a workflow aid, not legal advice. Verify edition, amendments, and governing law before use."
HTML_DISCLAIMER = "<!-- DISCLAIMER: This template is generated by Construction Law Skill. It is a workflow and analysis aid only. It does not constitute legal advice. Always verify the applicable contract edition, amendments, and governing law. -->"

TEMPLATES = {
    "notice-of-claim": {
        "title": "Notice of Claim",
        "description": "Initial notice to preserve entitlement (time-bar compliance)",
        "forms": {
            "fidic-red": {
                "clause": "20.2.1",
                "period": "28 days from awareness",
                "template": """# NOTICE OF CLAIM
## Under Clause 20.2.1 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Engineer/Engineer's Representative],**

**RE: NOTICE OF CLAIM UNDER CLAUSE 20.2.1 — [Brief Description of Claim]**

We refer to the above-captioned Contract and hereby give notice pursuant to **Sub-Clause 20.2.1** of the Conditions of Contract (FIDIC Red Book 2017 Edition).

### 1. EVENT OR CIRCUMSTANCE GIVING RISE TO THE CLAIM

[Describe the event or circumstance. Be specific about what happened, when it happened, and where.]

The Contractor became aware of this event/circumstance on **[date of awareness]**.

This Notice is given within **28 days** of the date on which the Contractor became aware of the event or circumstance, in compliance with Sub-Clause 20.2.1.

### 2. CONTRACTUAL BASIS

The Contractor considers that it is entitled to:

- [ ] Extension of Time under Sub-Clause [8.4 / 8.5 / other]
- [ ] Additional Payment (Cost) under Sub-Clause [___]
- [ ] Additional Payment (Cost + Profit) under Sub-Clause [___]

The relevant Sub-Clauses giving rise to this entitlement are:
- **Sub-Clause [___]**: [Brief description of entitlement basis]

### 3. PRELIMINARY ESTIMATE OF IMPACT

**Time impact:** [Estimated delay in days/weeks — if known at this stage]
**Cost impact:** [Preliminary estimate — if quantifiable at this stage]

*Note: These are preliminary estimates only. A fully detailed claim will be submitted in accordance with Sub-Clause 20.2.4 within 84 days of this Notice.*

### 4. SUPPORTING RECORDS

The Contractor is maintaining contemporary records in accordance with Sub-Clause 20.2.3, including:
- Daily site records
- Progress photographs
- Correspondence
- Programme updates
- Resource records
- [Other relevant records]

### 5. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law, including but not limited to the right to submit further claims and to update the particulars and quantum of this claim.

This Notice is given **without prejudice** to any other rights or remedies available to the Contractor.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
[Name and Title]

---
*cc: [Employer] / [Other parties as required]*
"""
            },
            "psscoc": {
                "clause": "23(1)",
                "period": "28 days from commencement of delay event",
                "template": """# APPLICATION FOR EXTENSION OF TIME
## Under Clause 23(1) of PSSCOC

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Government Agency]
**Contractor:** [Contractor Name]
**Superintending Officer:** [SO Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Superintending Officer],**

**RE: APPLICATION FOR EXTENSION OF TIME UNDER CLAUSE 23(1) — [Brief Description]**

We refer to the above Contract and hereby apply for an Extension of Time pursuant to **Clause 23(1)** of the Public Sector Standard Conditions of Contract.

### 1. CAUSE OF DELAY

[Describe the delay event in detail — what happened, when, how it affects the works]

The delay event commenced on **[date]**.

This application is made within **28 days** from the commencement of the delay event, in compliance with Clause 23(1).

### 2. GROUNDS FOR EOT

The Contractor applies for EOT on the following grounds under Clause 23:
- [ ] Variation Orders
- [ ] Exceptionally adverse weather conditions
- [ ] Delay caused by the Employer or SO
- [ ] Civil commotion, strikes, lockouts
- [ ] Force majeure
- [ ] Other: [specify]

### 3. IMPACT ON PROGRAMME

**Current Completion Date:** [date]
**Estimated delay:** [number] days
**Requested Revised Completion Date:** [date]

**Critical path impact:** [Describe how the delay event affects the critical path]

### 4. MITIGATION MEASURES

The Contractor has taken / is taking the following steps to mitigate delay:
- [Measure 1]
- [Measure 2]
- [Measure 3]

### 5. SUPPORTING DOCUMENTS

Enclosed:
- [ ] Updated programme showing delay impact
- [ ] Site diary / daily records for affected period
- [ ] Relevant correspondence
- [ ] Photographs
- [ ] Weather records (if applicable)
- [ ] Resource records

### 6. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract including any entitlement to costs arising from the delay.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "23",
                "period": "Written notice required",
                "template": """# APPLICATION FOR EXTENSION OF TIME
## Under Clause 23 of the SIA Conditions

**Contract:** [Contract Title]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Architect:** [Architect Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Architect],**

**RE: APPLICATION FOR EXTENSION OF TIME — [Brief Description]**

We refer to the above Contract and hereby apply for an Extension of Time pursuant to **Clause 23** of the SIA Conditions of Building Contract (9th Edition).

### 1. DELAY EVENT
[Description of event causing delay]

### 2. CONTRACTUAL BASIS
[Relevant sub-clause of Clause 23]

### 3. IMPACT
**Current Completion Date:** [date]
**Delay period:** [number] days
**Requested Revised Completion Date:** [date]

### 4. MITIGATION
[Steps taken to minimise delay]

### 5. SUPPORTING DOCUMENTS
[List of enclosed documents]

### 6. RESERVATION OF RIGHTS
The Contractor reserves all rights under the Contract.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "20.2.1",
                "period": "28 days from awareness",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# NOTICE OF CLAIM
## Under Sub-Clause 20.2.1 — FIDIC Yellow Book 2017 (Plant & Design-Build)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Engineer / Engineer's Representative],**

**RE: NOTICE OF CLAIM UNDER SUB-CLAUSE 20.2.1 — [Brief Description of Claim]**

We refer to the above-captioned Contract and hereby give notice pursuant to **Sub-Clause 20.2.1** of the Conditions of Contract (FIDIC Yellow Book 2017, Plant and Design-Build).

### 1. EVENT OR CIRCUMSTANCE GIVING RISE TO THE CLAIM

[Describe the event or circumstance. Be specific about what happened, when it happened, and where. Where the event relates to design (Employer's Requirements / Contractor's design / interfacing with the Employer's other contractors), state this expressly.]

The Contractor became aware of this event/circumstance on **[date of awareness]**.

This Notice is given within **28 days** of the date on which the Contractor became aware of the event or circumstance, in compliance with Sub-Clause 20.2.1.

### 2. CONTRACTUAL BASIS

The Contractor considers that it is entitled to:

- [ ] Extension of Time for Completion under Sub-Clause 8.5
- [ ] Additional Payment (Cost / Cost Plus Profit) under Sub-Clause [___]
- [ ] Relief in respect of Tests after Completion under Sub-Clause 12.4
- [ ] Relief in respect of an error in the Employer's Requirements under Sub-Clause 1.9
- [ ] Other entitlement under the Contract: [identify]

### 3. DESIGN-RELATED CONSIDERATIONS (where applicable)

Where the claim concerns the Contractor's design or the Employer's Requirements, identify:
- The relevant clause of the Employer's Requirements
- Whether an error in the Employer's Requirements is alleged (Sub-Clause 1.9)
- Any impact on the Contractor's design review periods under Sub-Clause 5.2

### 4. RESERVATION OF RIGHTS

A fully detailed claim under Sub-Clause 20.2.4 will follow within 84 days of the date on which the Contractor became aware (or such other period as the Engineer may agree). The Contractor reserves the right to update or supplement this Notice and the detailed claim in accordance with the Contract.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "20.2.1",
                "period": "28 days from awareness",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# NOTICE OF CLAIM
## Under Sub-Clause 20.2.1 — FIDIC Silver Book 2017 (EPC/Turnkey)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Employer's Representative:** [Employer's Representative Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Employer / Employer's Representative],**

**RE: NOTICE OF CLAIM UNDER SUB-CLAUSE 20.2.1 — [Brief Description of Claim]**

We refer to the above-captioned Contract and hereby give notice pursuant to **Sub-Clause 20.2.1** of the Conditions of Contract (FIDIC Silver Book 2017, EPC/Turnkey).

### 1. EVENT OR CIRCUMSTANCE GIVING RISE TO THE CLAIM

[Describe the event or circumstance. Note: Under the Silver Book, the Contractor bears significantly wider risk than under the Red or Yellow Books. Ensure the event falls within the limited grounds for Contractor relief under the EPC/Turnkey allocation.]

The Contractor became aware of this event/circumstance on **[date of awareness]**.

This Notice is given within **28 days** of the date on which the Contractor became aware of the event or circumstance, in compliance with Sub-Clause 20.2.1.

### 2. CONTRACTUAL BASIS

The Contractor considers that it is entitled to:

- [ ] Extension of Time for Completion under Sub-Clause 8.5
- [ ] Additional Payment (Cost) under Sub-Clause [___]
- [ ] Additional Payment (Cost Plus Profit) under Sub-Clause [___]

The relevant Sub-Clauses giving rise to this entitlement are:
- **Sub-Clause [___]**: [Brief description]

**Note on Silver Book risk allocation:** This claim is limited to entitlement expressly provided under the Conditions of Contract and does not extend to matters within the Contractor's assumed EPC risk.

### 3. PRELIMINARY ESTIMATE OF IMPACT

**Time impact:** [Estimated delay in days/weeks — if known at this stage]
**Cost impact:** [Preliminary estimate — if quantifiable at this stage]

*A fully detailed claim under Sub-Clause 20.2.4 will follow within 84 days.*

### 4. SUPPORTING RECORDS

The Contractor is maintaining contemporary records in accordance with Sub-Clause 20.2.3.

### 5. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law. This Notice is given **without prejudice** to any other rights or remedies available to the Contractor.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    },
    "eot-application": {
        "title": "EOT Application (Detailed)",
        "description": "Detailed extension of time application with delay analysis",
        "forms": {
            "fidic-red": {
                "clause": "20.2.4",
                "period": "84 days from Notice of Claim",
                "template": """# FULLY DETAILED CLAIM — EXTENSION OF TIME
## Under Sub-Clause 20.2.4 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

**Notice of Claim Ref:** [Reference to original 20.2.1 notice]
**Notice of Claim Date:** [Date of original notice]

---

### 1. EXECUTIVE SUMMARY

This fully detailed claim is submitted pursuant to Sub-Clause 20.2.4, within 84 days of the Notice of Claim dated [date].

**Summary of claim:**
- Extension of Time: [number] days
- Additional Cost: $[amount]
- Profit (if applicable): $[amount]

### 2. FACTUAL BACKGROUND

#### 2.1 Contract Overview
- Contract Sum: $[amount]
- Original Completion Date: [date]
- Current Completion Date: [date] (as extended)
- Commencement Date: [date]

#### 2.2 Chronology of Events
| Date | Event | Reference |
|------|-------|-----------|
| [date] | [Event description] | [Letter/drawing/instruction ref] |
| [date] | [Event description] | [Reference] |

### 3. CONTRACTUAL ENTITLEMENT

#### 3.1 Relevant Contract Provisions
[Quote relevant clauses verbatim]

#### 3.2 Analysis of Entitlement
[Demonstrate how the facts satisfy each element of the clause]

#### 3.3 Notice Compliance
- Date of awareness: [date]
- Notice given: [date]
- Period: [X] days (within 28-day requirement)

### 4. CAUSATION — DELAY ANALYSIS

#### 4.1 Methodology
[State the delay analysis method used: TIA / Impacted As-Planned / Collapsed As-Built / Windows]

#### 4.2 Baseline Programme
[Reference the approved programme used as baseline]

#### 4.3 Delay Events
| Event | Start | End | Duration | Critical? |
|-------|-------|-----|----------|-----------|
| [Description] | [date] | [date] | [X] days | Yes/No |

#### 4.4 Critical Path Impact
[Demonstrate how delay events affected the critical path]

#### 4.5 Conclusion on Time
**Total delay to critical path: [X] days**
**EOT requested: [X] days**
**Revised Completion Date: [date]**

### 5. QUANTIFICATION — COSTS

#### 5.1 Prolongation Costs
| Item | Monthly Rate | Period | Amount |
|------|-------------|--------|--------|
| Site staff | $[amount] | [X] months | $[amount] |
| Site facilities | $[amount] | [X] months | $[amount] |
| Plant & equipment | $[amount] | [X] months | $[amount] |
| Insurance | $[amount] | [X] months | $[amount] |
| Bonds | $[amount] | [X] months | $[amount] |
| **Subtotal** | | | **$[amount]** |

#### 5.2 Head Office Overhead (Emden Formula)
```
HO Overhead = (Contract Sum / Contract Period) × (HO% / 100) × Delay Period
            = ($[amount] / [X] months) × ([X]% / 100) × [X] months
            = $[amount]
```

#### 5.3 Additional Direct Costs
[Itemise any additional costs directly caused by the delay event]

#### 5.4 Finance Charges
[Interest on delayed payments, if applicable]

#### 5.5 Profit (if entitled)
[Calculate profit element if Sub-Clause provides for Cost + Profit]

#### 5.6 Summary of Costs
| Head | Amount |
|------|--------|
| Prolongation costs | $[amount] |
| HO overhead | $[amount] |
| Additional direct costs | $[amount] |
| Finance charges | $[amount] |
| Profit | $[amount] |
| **TOTAL CLAIM** | **$[amount]** |

### 6. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Approved baseline programme | [ref] |
| Updated/as-built programme | [ref] |
| Daily site records | [ref] |
| Correspondence | [ref] |
| Photographs | [ref] |
| Cost records / invoices | [ref] |
| Weather records | [ref] |
| Resource records | [ref] |

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law. This claim may be updated as further information becomes available.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "psscoc": {
                "clause": "14.2 / 14.3",
                "period": "Within 28 days of the delay event becoming apparent (Cl. 14.2 condition precedent)",
                "template": """<!-- Edition: PSSCOC for Construction Works (7th Edition, 2014, reprinted with amendments 2020). Verify clause numbering if a different edition applies. -->
# EXTENSION OF TIME APPLICATION
## Under Clause 14.2 (Notice) and Clause 14.3 (Particulars) — PSSCOC for Construction Works (7th Ed., 2014)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Superintending Officer (SO):** [SO Name]
**Date:** {date}
**Ref:** [Reference Number]

**Notice of Delay Ref (Cl. 14.2):** [Reference to original 28-day notice]
**Notice of Delay Date:** [Date of original notice]

> **Important — condition precedent.** Under Clause 14.2, written notice within **28 days** of the delay event becoming apparent is a **condition precedent** to entitlement. Confirm notice compliance before relying on this submission.

---

### 1. EXECUTIVE SUMMARY

This particulars submission is made pursuant to Clause 14.3, supplementing the Contractor's Clause 14.2 Notice of Delay dated [date].

**Summary:**
- Extension of Time sought: [X] days
- Revised Date for Completion: [date]
- (Costs, if any, claimed separately under Cl. 22 / Cl. 23 — see related submission ref [_])

### 2. FACTUAL BACKGROUND

#### 2.1 Contract Overview
- Contract Sum: S$[amount]
- Date for Possession: [date]
- Original Date for Completion: [date]
- Current Date for Completion (as previously extended): [date]

#### 2.2 Chronology of the Delay Event
| Date | Event | Reference |
|------|-------|-----------|
| [date] | [Event description] | [SO instruction / letter / drawing] |
| [date] | [Event description] | [Reference] |
| [date] | Notice of Delay served (Cl. 14.2) | [Reference] |

### 3. CONTRACTUAL ENTITLEMENT — RELEVANT EVENT

#### 3.1 Relevant Event Relied On
Clause 14.2 lists the qualifying delay events. The event(s) relied on:
- [ ] (a) Force majeure
- [ ] (b) Exceptionally adverse weather
- [ ] (c) Loss or damage from Excepted Risks
- [ ] (d) Civil commotion / strike / lockout
- [ ] (e) Compliance with SO's instructions (other than for Contractor's default)
- [ ] (f) Late receipt of further drawings or instructions where requested in good time
- [ ] (g) Delay by Employer / nominated subcontractor / supplier
- [ ] (h) Delay caused by other contractors employed by Employer
- [ ] (i) Failure to give possession of the Site or part thereof
- [ ] (j) Suspension under Clause 16
- [ ] (k) Any other ground for which the Contract entitles EOT

#### 3.2 Notice Compliance (Cl. 14.2)
- Date the delay became reasonably apparent: [date]
- Notice of Delay served: [date]
- Period elapsed: [X] days (must be within 28 days)
- **Condition precedent satisfied:** [Yes / No — explain]

#### 3.3 Particulars Submission (Cl. 14.3)
- Notice date + 28 days: [date]
- This particulars submission served: [date]
- Within 28 days of Notice: [Yes / No]

### 4. DELAY ANALYSIS

#### 4.1 Methodology
[State method: Time Impact Analysis / Impacted As-Planned / Collapsed As-Built / Windows. Explain choice having regard to programme quality and records available.]

#### 4.2 Baseline Programme
[Identify the approved programme under Clause 13 used as baseline; revision number; SO acceptance ref/date]

#### 4.3 Delay Event Impact
| Event | Start | End | Activity Affected | Float Available | Critical? |
|-------|-------|-----|-------------------|-----------------|-----------|
| [Description] | [date] | [date] | [Activity ID] | [X] days | Yes/No |

#### 4.4 Critical Path Impact
[Demonstrate how the relevant event affected the critical path; identify shifted longest path]

#### 4.5 Conclusion on Time
**Net delay to critical path: [X] days**
**EOT applied for: [X] days**
**Revised Date for Completion: [date]**

### 5. CONCURRENT DELAY (if applicable)

[Address any concurrent contractor-culpable delay. Note: PSSCOC does not codify a concurrency rule; common-law principles (Henry Boot / Walter Lilly approach) generally apply for time, with apportionment for cost.]

### 6. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Cl. 14.2 Notice of Delay | [ref] |
| Approved baseline programme | [ref] |
| Updated / as-built programme | [ref] |
| SO instructions relied on | [ref] |
| Daily site records | [ref] |
| Correspondence | [ref] |
| Weather records (if Cl. 14.2(b)) | [ref] |
| Photographs | [ref] |

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract, the Building and Construction Industry Security of Payment Act 2004, and at common law. This submission may be updated as further information becomes available, including any continuing effect of the delay event under Cl. 14.3.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "23(1) and 23(2)",
                "period": "As soon as practicable after the cause of delay arises (Cl. 23(2))",
                "template": """<!-- Edition: SIA Conditions of Building Contract (Lump Sum Contract), 9th Edition (2010, reprinted September 2016). Verify clause numbering if a different edition applies. -->
# EXTENSION OF TIME APPLICATION
## Under Clause 23 — SIA Conditions of Building Contract (Lump Sum), 9th Ed. (2010, reprinted 2016)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Architect:** [Architect Name]
**Date:** {date}
**Ref:** [Reference Number]

> **Important — notice and timing.** Under Cl. 23(2), written notice of delay must be given to the Architect **as soon as practicable** after the cause of delay arises (and in any event before the Date for Completion). Unlike PSSCOC Cl. 14.2, SIA does not impose a strict 28-day condition precedent, but late notice may prejudice causation evidence and the Architect's discretion.

---

### 1. EXECUTIVE SUMMARY

This application for extension of time is made under Clause 23.

**Summary:**
- Extension of Time sought: [X] weeks / days
- Revised Date for Completion: [date]
- (Loss & Expense, if any, claimed separately under Cl. 23(1)(q) read with Cl. 24 — see related submission ref [_])

### 2. FACTUAL BACKGROUND

#### 2.1 Contract Overview
- Contract Sum: S$[amount]
- Date for Possession: [date]
- Original Date for Completion: [date]
- Current Date for Completion (as previously extended): [date]

#### 2.2 Chronology of the Delay Event
| Date | Event | Reference |
|------|-------|-----------|
| [date] | [Event description] | [Architect's instruction / letter] |
| [date] | Notice of Delay served (Cl. 23(2)) | [Reference] |

### 3. RELEVANT EVENT — CL. 23(1)

The Contractor relies on the following ground(s) listed in Clause 23(1):

- [ ] (a) Force majeure
- [ ] (b) Inclement weather
- [ ] (c) Loss or damage by Excepted Risks
- [ ] (d) Civil commotion / strike / lockout
- [ ] (e) Architect's instructions other than for Contractor's default
- [ ] (f) Late receipt of necessary drawings, instructions or levels (where requested in good time)
- [ ] (g) Delay by Nominated Subcontractor / Nominated Supplier
- [ ] (h) Work by Employer's other contractors
- [ ] (i) Employer's failure to give possession of Site
- [ ] (j) Suspension of the Works
- [ ] (k) Variations under Clause 12
- [ ] (q) Any other matter giving rise to loss and expense entitling the Contractor to time
- [ ] Any other ground entitling EOT under the Contract

### 4. NOTICE OF DELAY — CL. 23(2)

- Date the cause of delay arose: [date]
- Date the Contractor became aware: [date]
- Notice of Delay served: [date]
- Particulars of expected effect provided: [date]

### 5. DELAY ANALYSIS

#### 5.1 Methodology
[State method used and reasons for choice.]

#### 5.2 Baseline Programme
[Identify accepted programme used as baseline.]

#### 5.3 Delay Event Impact
| Event | Start | End | Activity Affected | Float | Critical? |
|-------|-------|-----|-------------------|-------|-----------|
| [Description] | [date] | [date] | [Activity ID] | [X] days | Yes/No |

#### 5.4 Critical Path Impact
[Demonstrate impact on the critical path; identify the longest path post-impact.]

#### 5.5 Conclusion on Time
**Net delay to critical path: [X] days**
**EOT applied for: [X] weeks / days**
**Revised Date for Completion: [date]**

### 6. CONCURRENT DELAY (if applicable)

[Address any concurrent contractor-culpable delay. Singapore courts have generally followed common-law principles; SIA does not codify concurrency. Consider Malmaison-style approach for time and apportionment for any associated loss and expense.]

### 7. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Cl. 23(2) Notice of Delay | [ref] |
| Accepted programme | [ref] |
| Updated / as-built programme | [ref] |
| Architect's instructions relied on | [ref] |
| Daily site records | [ref] |
| Correspondence | [ref] |
| Weather records (if Cl. 23(1)(b)) | [ref] |
| Photographs | [ref] |

### 8. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract, the Building and Construction Industry Security of Payment Act 2004, and at common law. This application may be updated as further information becomes available.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "20.2.4 read with 8.5",
                "period": "84 days from Notice of Claim",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# FULLY DETAILED CLAIM — EXTENSION OF TIME
## Under Sub-Clause 20.2.4 read with Sub-Clause 8.5 — FIDIC Yellow Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

**Notice of Claim Ref:** [Reference to original 20.2.1 notice]
**Notice of Claim Date:** [Date of original notice]

---

### 1. EXECUTIVE SUMMARY

This fully detailed claim is submitted pursuant to Sub-Clause 20.2.4, within 84 days of the Notice of Claim dated [date], and engages Sub-Clause 8.5 (Extension of Time for Completion).

**Summary of claim:**
- Extension of Time: [number] days
- Additional Cost (Cost / Cost Plus Profit per Sub-Clause invoked): $[amount]

### 2. RELEVANT GROUND UNDER SUB-CLAUSE 8.5

The Contractor relies on the following ground(s) under Sub-Clause 8.5:

- [ ] (a) A Variation
- [ ] (b) A cause of delay giving an entitlement to EOT under a Sub-Clause of these Conditions
- [ ] (c) Exceptionally adverse climatic conditions
- [ ] (d) Unforeseeable shortages in personnel or Goods caused by epidemic or governmental action
- [ ] (e) Any delay, impediment or prevention caused by or attributable to the Employer, Employer's Personnel, or Employer's other contractors
- [ ] (f) Any other matter listed in the Contract or in the Contract Data

### 3. DESIGN-RELATED CONSIDERATIONS

Where the delay engages the Contractor's design or interfaces with the Employer's Requirements, address:
- The clause(s) in Employer's Requirements relied on
- Any error in the Employer's Requirements (Sub-Clause 1.9) and the Engineer's response
- Whether design review periods (Sub-Clause 5.2) contributed to the critical-path impact
- Any redesign required and its sequencing impact

### 4. CAUSATION — DELAY ANALYSIS

#### 4.1 Methodology
[State delay analysis method used: TIA / Impacted As-Planned / Collapsed As-Built / Windows. Justify choice.]

#### 4.2 Baseline Programme
[Reference the accepted programme used as baseline; revision and Engineer's review status.]

#### 4.3 Delay Events
| Event | Start | End | Duration | Critical? |
|-------|-------|-----|----------|-----------|
| [Description] | [date] | [date] | [X] days | Yes/No |

#### 4.4 Critical Path Impact
[Demonstrate how delay events affected the critical path, including any shift in the longest path.]

#### 4.5 Conclusion on Time
**Total delay to critical path: [X] days**
**EOT requested: [X] days**
**Revised Time for Completion: [date]**

### 5. QUANTIFICATION

| Head | Sub-Clause / Basis | Amount |
|------|---------------------|--------|
| Prolongation costs (site staff, plant, facilities, insurance, bonds) | Cl. 8.5 + applicable Sub-Clause | $[amount] |
| Head office overhead (Emden / Hudson / Eichleay) | Established formula | $[amount] |
| Design / redesign cost (Yellow Book specific) | Cl. 5 + applicable Sub-Clause | $[amount] |
| Additional direct costs | Cost records | $[amount] |
| Finance charges | Cl. 14 | $[amount] |
| Profit (where Cost Plus Profit applies) | Sub-Clause invoked | $[amount] |
| **TOTAL** | | **$[amount]** |

### 6. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Notice of Claim (Sub-Clause 20.2.1) | [ref] |
| Approved baseline programme | [ref] |
| Updated / as-built programme | [ref] |
| Engineer's instructions and review responses (Sub-Clause 5.2) | [ref] |
| Daily site records | [ref] |
| Weather records (if Cl. 8.5(c)) | [ref] |
| Contemporaneous correspondence | [ref] |
| Cost records / payroll / invoices | [ref] |

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law. This claim may be updated as further information becomes available, including any continuing or further effects of the relevant event.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "20.2.4 read with 8.5",
                "period": "84 days from Notice of Claim",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# FULLY DETAILED CLAIM — EXTENSION OF TIME
## Under Sub-Clause 20.2.4 read with Sub-Clause 8.5 — FIDIC Silver Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Employer's Representative:** [Employer's Representative Name]
**Date:** {date}
**Ref:** [Reference Number]

**Notice of Claim Ref:** [Reference to original 20.2.1 notice]
**Notice of Claim Date:** [Date of original notice]

---

### 1. EXECUTIVE SUMMARY

This fully detailed claim is submitted pursuant to Sub-Clause 20.2.4, within 84 days of the Notice of Claim dated [date], and engages Sub-Clause 8.5 (Extension of Time for Completion).

**Summary of claim:**
- Extension of Time: [number] days
- Additional Cost: $[amount]

### 2. RELEVANT GROUND UNDER SUB-CLAUSE 8.5

**Important — Silver Book EOT grounds are narrower than Red/Yellow Book.** The Contractor relies on:

- [ ] (a) A Variation (except where arising from the Contractor's design)
- [ ] (b) A cause of delay giving an entitlement to EOT under a Sub-Clause of these Conditions
- [ ] (c) Exceptionally adverse climatic conditions
- [ ] (d) Unforeseeable shortages caused by epidemic or governmental action
- [ ] (e) Any delay, impediment or prevention caused by or attributable to the Employer

### 3. EPC/TURNKEY RISK CONSIDERATIONS

- [ ] Confirmed: the claimed event falls outside the Contractor's assumed EPC risk
- [ ] If design-related: issue arises from Employer's Requirements, not Contractor's design
- [ ] If ground conditions: qualifies as Unforeseeable under Sub-Clause 4.12 (higher threshold)

### 4. CAUSATION — DELAY ANALYSIS

#### 4.1 Methodology
[State method: TIA / Impacted As-Planned / Collapsed As-Built / Windows]

#### 4.2 Baseline Programme
[Reference the accepted programme]

#### 4.3 Delay Events
| Event | Start | End | Duration | Critical? |
|-------|-------|-----|----------|-----------|
| [Description] | [date] | [date] | [X] days | Yes/No |

#### 4.4 Critical Path Impact
[Demonstrate impact on critical path including design, procurement, and construction interfaces]

#### 4.5 Conclusion on Time
**Total delay: [X] days | EOT requested: [X] days | Revised Completion: [date]**

### 5. QUANTIFICATION

| Head | Basis | Amount |
|------|-------|--------|
| Prolongation costs | Actual cost | $[amount] |
| Head office overhead | Emden / Eichleay | $[amount] |
| Design prolongation | Actual cost | $[amount] |
| Additional direct costs | Cost records | $[amount] |
| Finance charges | Cl. 14 | $[amount] |
| Profit (if applicable) | Per Sub-Clause | $[amount] |
| **TOTAL** | | **$[amount]** |

### 6. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Notice of Claim (20.2.1) | [ref] |
| Baseline programme | [ref] |
| Updated programme | [ref] |
| Employer's Requirements | [ref] |
| Daily site records | [ref] |
| Cost records | [ref] |

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    },
    "variation-claim": {
        "title": "Variation Valuation Claim",
        "description": "Claim for valuation of instructed variation",
        "forms": {
            "fidic-red": {
                "clause": "13.3",
                "period": "Per Engineer's instruction",
                "template": """# VARIATION VALUATION
## Under Sub-Clause 13.3 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Variation Instruction Ref:** [Reference]
**Variation Instruction Date:** [Date]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. VARIATION INSTRUCTION

On [date], the Engineer issued [Instruction/Direction] Ref: [reference] instructing the following variation:

[Describe the variation — what work is added/omitted/changed]

### 2. VALUATION BASIS

The Contractor proposes the following valuation in accordance with Sub-Clause 13.3:

#### 2.1 Applicable Rates
- [ ] Contract rates (applicable to similar work)
- [ ] New rates (no similar work in BOQ)
- [ ] Daywork rates

#### 2.2 Breakdown

| Item | Description | Qty | Unit | Rate | Amount |
|------|-------------|-----|------|------|--------|
| 1 | [Description] | [qty] | [unit] | $[rate] | $[amount] |
| 2 | [Description] | [qty] | [unit] | $[rate] | $[amount] |
| | **Subtotal** | | | | **$[amount]** |
| | Profit & Overhead [X]% | | | | $[amount] |
| | **TOTAL** | | | | **$[amount]** |

### 3. TIME IMPACT

**Does this variation affect the programme?**
- [ ] Yes — EOT claim to follow under Clause 20.2
- [ ] No — variation can be absorbed within current programme

### 4. SUPPORTING DOCUMENTS

- [ ] Engineer's variation instruction
- [ ] Drawings / specifications
- [ ] Quotations from suppliers/subcontractors
- [ ] Rate build-up / cost breakdown
- [ ] Programme showing impact (if applicable)

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "psscoc": {
                "clause": "19.1 (Variations) and 20 (Valuation)",
                "period": "Per SO's directions and Cl. 20 valuation rules",
                "template": """<!-- Edition: PSSCOC for Construction Works (7th Edition, 2014, reprinted with amendments 2020). Verify clause numbering if a different edition applies. -->
# VARIATION VALUATION
## Under Clause 19 (Variations) and Clause 20 (Valuation of Variations) — PSSCOC for Construction Works (7th Ed., 2014)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**SO Direction Ref (Cl. 19):** [Reference]
**SO Direction Date:** [Date]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. SUMMARY OF VARIATION

| Item | Detail |
|------|--------|
| SO Direction Ref | [ref] |
| Description | [Brief description of varied work] |
| Type | [ ] Addition  [ ] Omission  [ ] Substitution  [ ] Change in sequence/timing |
| Date directed | [date] |
| Date executed | [date / range] |
| Net value | S$[amount] |

### 2. CONTRACTUAL BASIS

#### 2.1 SO's Power to Direct Variations (Cl. 19.1)
The SO directed the variation by [SO Direction / Letter / Site Instruction] dated [date].

#### 2.2 Confirmation of Oral Direction (if applicable)
Where the direction was given orally, it was confirmed in writing within 7 days under Clause 19.4 by [reference].

### 3. VALUATION RULES — CLAUSE 20

Cl. 20 sets the order of priority for valuation:

- [ ] **Cl. 20.1(a) — Bill of Quantities / Schedule of Rates apply** (work of similar character, executed under similar conditions)
- [ ] **Cl. 20.1(b) — BQ rates as basis** (similar character but different conditions; rates adjusted)
- [ ] **Cl. 20.1(c) — Fair valuation** (work not of similar character; new rates/prices)
- [ ] **Cl. 20.2 — Daywork** (where SO so directs and work cannot otherwise be valued)

### 4. VALUATION DETAIL

#### 4.1 Quantities
| Item | Description | Unit | Qty | Source |
|------|-------------|------|-----|--------|
| [No.] | [Description] | [unit] | [qty] | [Drawing/measurement ref] |

#### 4.2 Rate Build-Up
| Item | Description | Unit | Rate (S$) | Source / Justification |
|------|-------------|------|-----------|------------------------|
| [No.] | [Description] | [unit] | [rate] | [BQ ref / Quotation / First-principles build-up] |

#### 4.3 Total Variation Value
| Item | Description | Qty | Rate (S$) | Amount (S$) |
|------|-------------|-----|-----------|-------------|
| [No.] | [Description] | [qty] | [rate] | [amount] |
| | | | **Subtotal** | **[amount]** |
| | | | Adjustments (preliminaries, OH&P) | [amount] |
| | | | **TOTAL** | **[amount]** |

### 5. PROGRAMME / TIME IMPACT

- [ ] No impact on Date for Completion
- [ ] EOT required — separate Cl. 14.2 Notice of Delay served, ref [_]

### 6. SUPPORTING DOCUMENTS

- SO Direction (Cl. 19) — ref [_]
- Confirmation of oral direction (if applicable, Cl. 19.4) — ref [_]
- Drawings / specifications — ref [_]
- Quotations from sub-contractors / suppliers — ref [_]
- Rate build-up working papers — ref [_]
- Daywork sheets (if Cl. 20.2 valuation) — ref [_]
- Programme impact analysis (if applicable) — ref [_]

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract, including any further valuation adjustments under Clause 20 and time-related entitlements under Clause 14.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "12 (Variations) and 12(3) (Valuation)",
                "period": "Per Architect's instructions and Cl. 12(3) valuation rules",
                "template": """<!-- Edition: SIA Conditions of Building Contract (Lump Sum Contract), 9th Edition (2010, reprinted September 2016). Verify clause numbering if a different edition applies. -->
# VARIATION VALUATION
## Under Clause 12 — SIA Conditions of Building Contract (Lump Sum), 9th Ed. (2010, reprinted 2016)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Architect's Instruction (AI) Ref:** [Reference]
**AI Date:** [Date]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. SUMMARY OF VARIATION

| Item | Detail |
|------|--------|
| Architect's Instruction Ref | [ref] |
| Description | [Brief description of varied work] |
| Type | [ ] Addition  [ ] Omission  [ ] Substitution  [ ] Change in sequence/timing |
| Date instructed | [date] |
| Date executed | [date / range] |
| Net value | S$[amount] |

### 2. CONTRACTUAL BASIS

#### 2.1 Architect's Authority to Order Variations (Cl. 1 and Cl. 12)
The Architect issued AI ref [_] dated [date] requiring the variation.

#### 2.2 Confirmation of Oral Instruction (if applicable)
Where the instruction was given orally, it has been confirmed in writing in accordance with Clause 1.

### 3. VALUATION RULES — CLAUSE 12(3)

Cl. 12(3) sets the priority for valuation:

- [ ] **Cl. 12(3)(a) — Contract rates apply** (work of similar character executed under similar conditions)
- [ ] **Cl. 12(3)(b) — Contract rates as basis** (similar character but different conditions; fair adjustment)
- [ ] **Cl. 12(3)(c) — Fair valuation / fair rates and prices** (work not of similar character)
- [ ] **Cl. 12(4) — Daywork** (where the Architect so directs)

### 4. VALUATION DETAIL

#### 4.1 Quantities
| Item | Description | Unit | Qty | Source |
|------|-------------|------|-----|--------|
| [No.] | [Description] | [unit] | [qty] | [Drawing / measurement] |

#### 4.2 Rate Build-Up
| Item | Description | Unit | Rate (S$) | Source / Justification |
|------|-------------|------|-----------|------------------------|
| [No.] | [Description] | [unit] | [rate] | [Contract Sum analysis / Quotation / First principles] |

#### 4.3 Total Variation Value
| Item | Description | Qty | Rate (S$) | Amount (S$) |
|------|-------------|-----|-----------|-------------|
| [No.] | [Description] | [qty] | [rate] | [amount] |
| | | | **Subtotal** | **[amount]** |
| | | | Adjustments (preliminaries, OH&P) | [amount] |
| | | | **TOTAL** | **[amount]** |

### 5. PROGRAMME / TIME IMPACT

- [ ] No impact on Date for Completion
- [ ] EOT required — separate Cl. 23(2) Notice of Delay served, ref [_]
- [ ] Loss & Expense follows under Cl. 23(1)(q) and Cl. 24, ref [_]

### 6. SUPPORTING DOCUMENTS

- Architect's Instruction — ref [_]
- Drawings / specifications — ref [_]
- Quotations from sub-contractors / suppliers — ref [_]
- Rate build-up working papers — ref [_]
- Daywork sheets (if Cl. 12(4) valuation) — ref [_]
- Programme impact analysis (if applicable) — ref [_]

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law, including further adjustments under Cl. 12(3) and any associated time / loss and expense entitlements under Cl. 23 / Cl. 24.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "13.3",
                "period": "Per Engineer's instruction / RFP",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# VARIATION VALUATION
## Under Sub-Clause 13.3 — FIDIC Yellow Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Variation Instruction Ref:** [Reference]
**Variation Instruction Date:** [Date]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. SUMMARY OF VARIATION

| Item | Detail |
|------|--------|
| Variation Ref | [ref] |
| Description | [Brief description of varied work] |
| Type | [ ] Addition  [ ] Omission  [ ] Substitution  [ ] Change to Employer's Requirements  [ ] Change in sequence/timing |
| Date instructed | [date] |
| Date executed | [date / range] |
| Net value | $[amount] |

### 2. CONTRACTUAL BASIS

#### 2.1 Initiation Route (Sub-Clause 13.1 / 13.3)
The Variation was initiated by:
- [ ] Engineer's Variation Instruction under Sub-Clause 13.1
- [ ] Engineer's Request for Proposal under Sub-Clause 13.3.2
- [ ] Value Engineering proposal by Contractor under Sub-Clause 13.2

#### 2.2 Design Impact (Yellow Book specific)
Where the Variation alters the Employer's Requirements or the Contractor's design, set out:
- The change to Employer's Requirements (clause / drawing / spec)
- Redesign required and design effort cost
- Fitness-for-purpose implications under Sub-Clause 4.1
- Any additional review period required under Sub-Clause 5.2

### 3. VALUATION RULES — SUB-CLAUSE 13.3.1

Valuation follows the priority:
- [ ] (a) Sums and rates quoted in the Schedules apply
- [ ] (b) Sums and rates in the Schedules used as basis with reasonable adjustment
- [ ] (c) Fair valuation by the Engineer
- [ ] Daywork under the Daywork Schedule (where applicable)

### 4. VALUATION DETAIL

#### 4.1 Quantities
| Item | Description | Unit | Qty | Source |
|------|-------------|------|-----|--------|
| [No.] | [Description] | [unit] | [qty] | [Drawing / measurement / Employer's Requirements ref] |

#### 4.2 Rate Build-Up
| Item | Description | Unit | Rate | Source / Justification |
|------|-------------|------|------|------------------------|
| [No.] | [Description] | [unit] | $[rate] | [Schedule rate / Quotation / First-principles build-up] |

#### 4.3 Total Variation Value
| Item | Description | Qty | Rate | Amount |
|------|-------------|-----|------|--------|
| [No.] | [Description] | [qty] | $[rate] | $[amount] |
| | | | **Subtotal** | **$[amount]** |
| | | | Adjustments (preliminaries, OH&P, design effort) | $[amount] |
| | | | **TOTAL** | **$[amount]** |

### 5. PROGRAMME / TIME IMPACT

- [ ] No impact on Time for Completion
- [ ] EOT required — Notice of Claim under Sub-Clause 20.2.1 served, ref [_]

### 6. SUPPORTING DOCUMENTS

- Variation Instruction / Request for Proposal
- Drawings / revised Employer's Requirements
- Quotations from sub-contractors / suppliers
- Rate build-up working papers
- Daywork sheets (if applicable)
- Programme impact analysis (if applicable)
- Design effort records (where redesign engaged)

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "13.3",
                "period": "Per Employer's instruction or deemed Variation",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# VARIATION VALUATION
## Under Sub-Clause 13.3 — FIDIC Silver Book 2017 (EPC/Turnkey)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Variation Instruction Ref:** [Reference]
**Variation Instruction Date:** [Date]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. VARIATION INSTRUCTION

On [date], the Employer / Employer's Representative issued Instruction Ref: [reference] instructing the following variation:

[Describe the variation]

**Silver Book note:** Variations are instructed by the Employer (not an Engineer). Where the Contractor considers an instruction constitutes a Variation not covered by the Contract, notice should be given under Sub-Clause 13.2.

### 2. VALUATION BASIS

#### 2.1 Applicable Rates
- [ ] Contract rates (if applicable — Silver Book is generally lump sum)
- [ ] New rates (agreed or to be agreed)
- [ ] Cost-based valuation

#### 2.2 Breakdown

| Item | Description | Qty | Unit | Rate | Amount |
|------|-------------|-----|------|------|--------|
| 1 | [Description] | [qty] | [unit] | $[rate] | $[amount] |
| | **Subtotal** | | | | **$[amount]** |
| | Overhead & Profit [X]% | | | | $[amount] |
| | **TOTAL** | | | | **$[amount]** |

### 3. DESIGN IMPACT

- [ ] Additional design/engineering cost included
- [ ] Impact on fitness for purpose obligations: [describe if applicable]

### 4. TIME IMPACT

- [ ] Yes — EOT claim to follow under Sub-Clause 20.2
- [ ] No — can be absorbed within current programme

### 5. SUPPORTING DOCUMENTS

- [ ] Employer's variation instruction
- [ ] Revised drawings / specifications
- [ ] Rate build-up / cost breakdown
- [ ] Design impact assessment
- [ ] Programme (if time impact)

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    },
    "interim-claim": {
        "title": "Interim Claim Statement",
        "description": "Progress claim / interim payment application",
        "forms": {
            "fidic-red": {
                "clause": "14.3",
                "period": "Monthly",
                "template": """# INTERIM PAYMENT APPLICATION No. [X]
## Under Sub-Clause 14.3 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Period:** [Start Date] to [End Date]
**Date:** {date}
**Ref:** [Reference Number]

---

### SUMMARY

| Item | Amount |
|------|--------|
| A. Work done to date | $[amount] |
| B. Materials on site | $[amount] |
| C. Approved variations | $[amount] |
| D. Claims (assessed) | $[amount] |
| E. Price adjustments | $[amount] |
| **F. Gross valuation (A+B+C+D+E)** | **$[amount]** |
| G. Less retention [X]% | ($[amount]) |
| **H. Net valuation** | **$[amount]** |
| I. Less previous certifications | ($[amount]) |
| **J. Amount due this certificate** | **$[amount]** |

### BREAKDOWN OF WORK DONE

| BOQ Ref | Description | Contract Qty | Completed Qty | Rate | Amount |
|---------|-------------|-------------|---------------|------|--------|
| [ref] | [description] | [qty] | [qty] | $[rate] | $[amount] |

### VARIATIONS INCLUDED

| VO No. | Description | Amount |
|--------|-------------|--------|
| VO-[X] | [Description] | $[amount] |

### CLAIMS INCLUDED

| Claim No. | Description | Amount |
|-----------|-------------|--------|
| CLM-[X] | [Description] | $[amount] |

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "psscoc": {
                "clause": "32 (Interim Payments)",
                "period": "Monthly, on the date stipulated in the Contract; SOP Act parallel right under s.10",
                "template": """<!-- Edition: PSSCOC for Construction Works (7th Edition, 2014, reprinted with amendments 2020). Verify clause numbering if a different edition applies. -->
# INTERIM PAYMENT CLAIM
## Under Clause 32 — PSSCOC for Construction Works (7th Ed., 2014)
## (and also constituting a Payment Claim under s.10 of the Building and Construction Industry Security of Payment Act 2004)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Superintending Officer (SO):** [SO Name]
**Payment Claim No.:** [No.]
**Period to which claim relates:** [start] to [end]
**Date of submission:** {date}
**Ref:** [Reference Number]

> This document is intended to operate concurrently as (a) a monthly interim payment application under Cl. 32 PSSCOC, and (b) a payment claim under s.10 of the Building and Construction Industry Security of Payment Act 2004 ("SOP Act"). The reference period and amounts are stated to satisfy s.10(3).

---

### 1. CONTRACT SUM RECONCILIATION

| Item | Amount (S$) |
|------|-------------|
| Original Contract Sum | [amount] |
| Add: Variations approved to date | [amount] |
| Add: Claims admitted to date | [amount] |
| Less: Omissions to date | [amount] |
| **Adjusted Contract Sum** | **[amount]** |

### 2. VALUATION OF WORK DONE

#### 2.1 Bill of Quantities Items
| BQ Ref | Description | Unit | BQ Qty | Rate (S$) | Cumulative Qty Done | Cumulative Value (S$) |
|--------|-------------|------|--------|-----------|----------------------|------------------------|
| [ref] | [description] | [unit] | [qty] | [rate] | [qty] | [amount] |

#### 2.2 Variations Included
| VO No. | Description | Cumulative Value (S$) |
|--------|-------------|------------------------|
| VO-[X] | [Description] | [amount] |

#### 2.3 Materials On-Site (Cl. 32 / contract conditions)
| Item | Quantity | Value (S$) | Vesting / Insurance Status |
|------|----------|-------------|----------------------------|
| [Description] | [qty] | [amount] | [Vested / Insured / Off-site approved] |

#### 2.4 Claims Included
| Claim No. | Description | Cumulative Value (S$) |
|-----------|-------------|------------------------|
| CLM-[X] | [Description] | [amount] |

### 3. SUMMARY — AMOUNT CLAIMED

| Heading | Amount (S$) |
|---------|-------------|
| Cumulative gross value of permanent work done | [amount] |
| Cumulative value of variations | [amount] |
| Cumulative value of materials on-site | [amount] |
| Cumulative value of claims | [amount] |
| **Cumulative Gross Valuation** | **[amount]** |
| Less: Retention (per Contract) | ([amount]) |
| Less: Previous Payments certified | ([amount]) |
| Less: Adjustments / set-offs notified by SO | ([amount]) |
| **Amount Now Claimed (excl. GST)** | **[amount]** |
| Add: GST @ [rate]% | [amount] |
| **TOTAL AMOUNT CLAIMED (incl. GST)** | **[amount]** |

### 4. SOP ACT REQUIREMENTS — SECTION 10

- [x] Identifies the Contract: [Contract title and reference]
- [x] Identifies the work to which it relates: [reference period]
- [x] States the claimed amount: S$[amount]
- [x] Served on the Respondent: [Employer name]
- [x] Reference period: [start] to [end]

### 5. SUPPORTING DOCUMENTS

- Measurement sheets / quantity build-ups
- Approved VOs
- Materials on-site schedule with vesting / insurance evidence
- Claim submissions (cross-references)
- Previous Payment Certificates

### 6. STATUTORY RIGHTS

The Contractor expressly reserves and intends to rely on its rights under the Building and Construction Industry Security of Payment Act 2004, including the right to seek adjudication if a Payment Response is not served within the statutory period, or if the Response disputes the claim.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "31 (Progress Payments) read with Cl. 32 (Interim Certificates)",
                "period": "Monthly intervals as stated in the Contract; SOP Act parallel right under s.10",
                "template": """<!-- Edition: SIA Conditions of Building Contract (Lump Sum Contract), 9th Edition (2010, reprinted September 2016). Verify clause numbering if a different edition applies. -->
# INTERIM PAYMENT CLAIM
## Under Clause 31 (Progress Payments) and Clause 32 (Interim Certificates) — SIA 9th Ed. (2010, reprinted 2016)
## (and also constituting a Payment Claim under s.10 of the Building and Construction Industry Security of Payment Act 2004)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Architect:** [Architect Name]
**Payment Claim No.:** [No.]
**Period to which claim relates:** [start] to [end]
**Date of submission:** {date}
**Ref:** [Reference Number]

> This document is intended to operate concurrently as (a) an interim payment application under Cl. 31 / 32 SIA, and (b) a payment claim under s.10 of the Building and Construction Industry Security of Payment Act 2004 ("SOP Act"). The reference period and amounts are stated to satisfy s.10(3).

---

### 1. CONTRACT SUM RECONCILIATION

| Item | Amount (S$) |
|------|-------------|
| Original Contract Sum | [amount] |
| Add: Variations approved (AIs to date) | [amount] |
| Add: Loss & expense admitted to date | [amount] |
| Less: Omissions to date | [amount] |
| **Adjusted Contract Sum** | **[amount]** |

### 2. VALUATION OF WORK DONE

#### 2.1 Trade / Section Breakdown (Lump Sum)
| Trade / Section | Lump Sum (S$) | % Complete | Cumulative Value (S$) |
|------------------|----------------|------------|------------------------|
| [Trade] | [amount] | [%] | [amount] |

#### 2.2 Variations (Architect's Instructions)
| AI Ref | Description | Cumulative Value (S$) |
|--------|-------------|------------------------|
| AI-[X] | [Description] | [amount] |

#### 2.3 Materials On-Site
| Item | Quantity | Value (S$) | Vesting / Insurance Status |
|------|----------|-------------|----------------------------|
| [Description] | [qty] | [amount] | [Vested / Insured / Off-site approved] |

#### 2.4 Loss & Expense Included
| Claim Ref | Description | Cumulative Value (S$) |
|-----------|-------------|------------------------|
| L&E-[X] | [Description] | [amount] |

### 3. SUMMARY — AMOUNT CLAIMED

| Heading | Amount (S$) |
|---------|-------------|
| Cumulative value of permanent work done | [amount] |
| Cumulative value of variations | [amount] |
| Cumulative value of materials on-site | [amount] |
| Cumulative value of loss & expense | [amount] |
| **Cumulative Gross Valuation** | **[amount]** |
| Less: Retention per Contract | ([amount]) |
| Less: Previous Interim Certificates | ([amount]) |
| Less: Architect's adjustments / set-offs | ([amount]) |
| **Amount Now Claimed (excl. GST)** | **[amount]** |
| Add: GST @ [rate]% | [amount] |
| **TOTAL AMOUNT CLAIMED (incl. GST)** | **[amount]** |

### 4. SOP ACT REQUIREMENTS — SECTION 10

- [x] Identifies the Contract: [Contract title and reference]
- [x] Identifies the work to which it relates: [reference period]
- [x] States the claimed amount: S$[amount]
- [x] Served on the Respondent: [Employer name]
- [x] Reference period: [start] to [end]

### 5. SUPPORTING DOCUMENTS

- Trade-by-trade valuation working papers
- Architect's Instructions to date (variations log)
- Materials on-site schedule with vesting / insurance evidence
- Loss & expense submissions (cross-references)
- Previous Interim Certificates

### 6. STATUTORY RIGHTS

The Contractor expressly reserves and intends to rely on its rights under the Building and Construction Industry Security of Payment Act 2004, including the right to seek adjudication if a Payment Response is not served within the statutory period, or if the Response disputes the claim.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "14.3",
                "period": "Monthly per Schedule of Payments",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# INTERIM PAYMENT STATEMENT
## Under Sub-Clause 14.3 — FIDIC Yellow Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Statement No.:** [No.]
**Period to which Statement relates:** [start] to [end]
**Date of submission:** {date}
**Ref:** [Reference Number]

> Yellow Book payment is typically lump-sum / milestone-based per the Schedule of Payments. Adapt the breakdown below to the Contract's Schedule of Payments or Schedule of Prices.

---

### 1. CONTRACT PRICE RECONCILIATION

| Item | Amount |
|------|--------|
| Accepted Contract Amount | $[amount] |
| Add: Variations approved (Sub-Clause 13.3) | $[amount] |
| Add: Claims admitted | $[amount] |
| Less: Omissions | $[amount] |
| **Adjusted Contract Price** | **$[amount]** |

### 2. VALUATION OF WORKS DONE — SCHEDULE OF PAYMENTS

| Section / Milestone | Lump Sum | % Achieved | Cumulative Value |
|---------------------|----------|-----------|-------------------|
| [Milestone description] | $[amount] | [%] | $[amount] |

### 3. VARIATIONS INCLUDED

| Var. Ref | Description | Cumulative Value |
|----------|-------------|-------------------|
| VAR-[X] | [Description] | $[amount] |

### 4. PLANT, MATERIALS AND CONTRACTOR'S DOCUMENTS

| Item | Status | Value |
|------|--------|-------|
| Plant for the Works (on Site) | [On Site / Vested] | $[amount] |
| Plant for the Works (off Site, where Contract permits) | [Off-Site approved / Vested] | $[amount] |
| Materials | [On Site / Off Site approved] | $[amount] |
| Contractor's Documents (where Contract permits payment for design effort) | [Submitted / Reviewed] | $[amount] |

### 5. CLAIMS INCLUDED

| Claim Ref | Description | Cumulative Value |
|-----------|-------------|-------------------|
| CLM-[X] | [Description] | $[amount] |

### 6. SUMMARY — AMOUNT CLAIMED

| Heading | Amount |
|---------|--------|
| Cumulative gross valuation | $[amount] |
| Less: Retention per Contract | ($[amount]) |
| Less: Previous IPCs paid | ($[amount]) |
| Less: Adjustments / set-offs (Engineer's notice) | ($[amount]) |
| **Amount due in this Statement (excl. taxes)** | **$[amount]** |
| Add: Applicable taxes | $[amount] |
| **TOTAL AMOUNT CLAIMED** | **$[amount]** |

### 7. SUPPORTING DOCUMENTS

- Schedule of Payments / Schedule of Prices breakdown
- Milestone evidence (sign-offs / Engineer acceptance)
- Variations log with Engineer's determinations
- Plant & Materials schedule with vesting / insurance evidence
- Contractor's Documents review status (Sub-Clause 5.2)
- Claims log with cross-references

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "14.3",
                "period": "Per payment schedule in Contract Data",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# INTERIM PAYMENT APPLICATION
## Under Sub-Clause 14.3 — FIDIC Silver Book 2017 (EPC/Turnkey)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Application No.:** [Number]
**Period:** [From date] to [To date]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. APPLICATION SUMMARY

This application is submitted under Sub-Clause 14.3 (FIDIC Silver Book 2017, EPC/Turnkey).

**Note:** Payment is typically milestone-based or per Schedule of Payments, not monthly measurement.

| Item | Amount |
|------|--------|
| Works completed (per milestones / Schedule of Payments) | $[amount] |
| Materials on site (if permitted) | $[amount] |
| Plant delivered to site | $[amount] |
| Variations (approved / pending) | $[amount] |
| Claims (determined / pending) | $[amount] |
| **Gross amount** | **$[amount]** |
| Less: Previous certifications | ($[amount]) |
| Less: Retention ([X]%) | ($[amount]) |
| Less: Advance payment recovery | ($[amount]) |
| **Net amount this application** | **$[amount]** |

### 2. MILESTONE ACHIEVEMENT

| Milestone | Description | Value | Status |
|-----------|-------------|-------|--------|
| [M1] | [Description] | $[amount] | Complete / In Progress |

### 3. VARIATIONS INCLUDED

| VO Ref | Description | Status | Amount |
|--------|-------------|--------|--------|
| [ref] | [description] | Approved / Pending | $[amount] |

### 4. CLAIMS INCLUDED

| Claim Ref | Description | Status | Amount |
|-----------|-------------|--------|--------|
| [ref] | [description] | Determined / Pending | $[amount] |

### 5. SUPPORTING DOCUMENTS

- [ ] Detailed breakdown / milestone evidence
- [ ] Progress report
- [ ] Variation valuations
- [ ] Test certificates (if applicable)

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    },
    "disruption-claim": {
        "title": "Disruption Claim",
        "description": "Loss of productivity / disruption claim (separate from delay)",
        "forms": {
            "fidic-red": {
                "clause": "20.2",
                "period": "28 days from awareness",
                "template": """# DISRUPTION CLAIM
## Under Sub-Clause 20.2 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Engineer/Engineer's Representative],**

## 1. Notice and Reservation of Rights

Pursuant to Sub-Clause 20.2.1, the Contractor hereby gives notice of a claim for additional Cost (and reasonable profit where applicable) arising from disruption to the Works — i.e. loss of productivity rather than (or in addition to) delay to the time for completion.

## 2. Disruption Event(s)

[Describe the events giving rise to disruption. Examples:]
- Out-of-sequence working caused by […]
- Trade stacking / over-resourcing in confined area […]
- Late information / RFI response delays […]
- Concurrent operations imposed by Employer / other contractors […]
- Acceleration / re-sequencing instruction

## 3. Causation & Productivity Loss

**Methodology used:** [Measured Mile / Earned Value / Project Comparison / Industry Studies (e.g. MCAA, Leonard) — specify]

| Period | Planned Output | Actual Output | Loss of Productivity |
|--------|----------------|---------------|---------------------|
| Unimpacted period | [units/manhour] | [units/manhour] | Baseline |
| Impacted period | [units/manhour] | [units/manhour] | [%] |

## 4. Quantum (Heads of Loss)

- Additional labour hours: [hrs] x [rate] = $[…]
- Additional plant: […]
- Site supervision overhead: […]
- Sub-contractor disruption pass-through: […]
- Reasonable profit: […]
- **Total claimed:** $[…]

## 5. Records Relied Upon

- Daily site records / allocation sheets
- Approved baseline programme & updates
- Productivity studies / industry benchmarks
- RFI / instruction logs
- Meeting minutes

## 6. Reservation

This claim is separate from any concurrent claim for extension of time. The Contractor reserves the right to amend, supplement, or expand this claim as further records and analysis become available.

Fully detailed claim to follow within 84 days pursuant to Sub-Clause 20.2.4.

Yours faithfully,

[Authorised Signatory]
"""
            },
            "psscoc": {
                "clause": "22.1",
                "period": "30 days from awareness",
                "template": """# DISRUPTION CLAIM
## Under Clause 22 (Loss & Expense) PSSCOC

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**SO:** [Superintending Officer]
**Date:** {date}

---

**Dear [SO],**

The Contractor hereby gives notice under Clause 22.1 of a claim for loss and expense arising from disruption to the regular progress of the Works (i.e. loss of productivity), not amounting solely to delay to the Date for Completion.

## 1. Disrupting Events

[List events under Clause 22.1 — e.g. late drawings, instructions, postponement, opening up, AI/SI imposing out-of-sequence work, employer's other contractors.]

## 2. Productivity Impact

Methodology: [Measured Mile / earned value / industry benchmark]

## 3. Heads of Loss & Expense

- Additional preliminaries
- Additional labour & plant unproductive time
- Sub-contractor disruption costs
- Site overheads & finance costs
- **Total:** $[…]

## 4. Substantiation

Further particulars and computations to be submitted within a reasonable time pursuant to Clause 22.1(2).

Yours faithfully,

[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "23(1)(q)",
                "period": "As soon as it has become reasonably apparent",
                "template": """# DISRUPTION CLAIM
## Under Clause 23(1)(q) and Clause 24 SIA Conditions (9th Ed.)

**Date:** {date}

Please treat this as the Contractor's notice of intention to claim Loss & Expense for disruption to the regular progress of the Works.

## 1. Events
[…]

## 2. Productivity Methodology
[…]

## 3. Heads of Loss
[…]

Fully detailed submission to follow.

Yours faithfully,

[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "20.2 read with 8.5",
                "period": "28 days from awareness",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# DISRUPTION CLAIM
## Under Sub-Clause 20.2 — FIDIC Yellow Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. NATURE OF DISRUPTION

[Describe the loss of productivity / disruption event(s). Disruption is loss of efficiency on the affected works; it is distinct from delay (which is critical-path impact). Disruption can occur without overall delay.]

### 2. CONTRACTUAL BASIS

Notice of Claim under Sub-Clause 20.2.1 served on [date]. This claim is for additional Cost (and Profit, where the underlying Sub-Clause entitles).

For Yellow Book contracts, identify the cause:
- [ ] Variations to the Employer's Requirements (Cl. 13)
- [ ] Engineer's review comments under Sub-Clause 5.2 forcing rework
- [ ] Late Engineer's instructions / late access
- [ ] Interfacing with Employer's other contractors (Cl. 4.6)
- [ ] Unforeseeable physical conditions (Cl. 4.12)
- [ ] Suspension under Cl. 8.9 / 16.1
- [ ] Other: [identify Sub-Clause]

### 3. METHODOLOGY

[State the disruption analysis method: Measured Mile / Earned Value / Industry Studies / Project Specific. Justify choice having regard to records available.]

### 4. QUANTIFICATION

| Resource | Planned Productivity | Actual Productivity | Loss | Value |
|----------|----------------------|---------------------|------|-------|
| [Trade / labour gang] | [units/hr] | [units/hr] | [%] | $[amount] |
| [Equipment] | [units/hr] | [units/hr] | [%] | $[amount] |

**Total disruption cost: $[amount]**
**Profit (where Cost Plus Profit applies): $[amount]**

### 5. SUPPORTING DOCUMENTS

- Daily allocation sheets
- Resource histograms (planned vs actual)
- Site diaries
- Photographs / time-lapse records
- Productivity baselines from undisrupted periods (Measured Mile)
- Engineer's review comments / instructions giving rise to disruption (where applicable)

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "20.2.4",
                "period": "84 days from Notice of Claim",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# DISRUPTION / LOSS OF PRODUCTIVITY CLAIM
## Under Sub-Clause 20.2.4 — FIDIC Silver Book 2017 (EPC/Turnkey)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Employer's Representative:** [Employer's Representative Name]
**Date:** {date}
**Ref:** [Reference Number]

**Notice of Claim Ref:** [Reference to 20.2.1 notice]
**Notice of Claim Date:** [Date]

---

### 1. EXECUTIVE SUMMARY

This claim is for **disruption / loss of productivity** caused by [brief description]. It is distinct from any delay (EOT) claim.

**Silver Book context:** This disruption relates to events that are the Employer's responsibility, not risks assumed by the Contractor under the EPC model.

**Total disruption cost claimed:** $[amount]

### 2. CONTRACTUAL BASIS

Entitlement arises under Sub-Clause [___]: [Description]

**Confirmed:** The claimed events fall within the Employer's contractual responsibility and outside the Contractor's assumed EPC risk.

### 3. DISRUPTING EVENTS

| # | Event | Date(s) | Clause | Impact |
|---|-------|---------|--------|--------|
| 1 | [Description] | [dates] | [clause] | [impact] |

### 4. DISRUPTION ≠ DELAY

This claim is for loss of productivity, not delay to completion. The affected works [were / were not] on the critical path.

### 5. PRODUCTIVITY ANALYSIS

#### 5.1 Methodology
- [ ] Measured Mile
- [ ] Project-Specific Study
- [ ] Earned Value Analysis

#### 5.2 Productivity Comparison
| Activity | Baseline Rate | Actual Rate | Loss | Additional Resources |
|----------|--------------|-------------|------|---------------------|
| [Activity] | [X units/hr] | [Y units/hr] | [Z]% | [hours/cost] |

### 6. QUANTIFICATION

| Head | Basis | Amount |
|------|-------|--------|
| Additional labour | [X] man-hours x $[rate] | $[amount] |
| Additional plant | [Details] | $[amount] |
| Materials wastage | [Details] | $[amount] |
| Supervision | [Details] | $[amount] |
| **TOTAL** | | **$[amount]** |

### 7. CAUSATION

Per *Costain v Charles Haswell* [2009]: specific events linked to identifiable productivity loss.

### 8. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Notice of Claim (20.2.1) | [ref] |
| Productivity analysis | [ref] |
| Labour records | [ref] |
| Daily site records | [ref] |
| Cost records | [ref] |

### 9. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    },
    "loss-and-expense": {
        "title": "Loss & Expense Claim",
        "description": "Comprehensive loss and expense claim with quantum breakdown",
        "forms": {
            "fidic-red": {
                "clause": "20.2 / 8.5",
                "period": "28 days from awareness",
                "template": """# LOSS & EXPENSE CLAIM
## Under Sub-Clauses 20.2 and 8.5 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Engineer/Engineer's Representative],**

## 1. Notice and Reservation of Rights

Pursuant to Sub-Clause 20.2.1, the Contractor hereby submits this comprehensive Loss & Expense claim arising from [Event(s)] which has caused / will cause the Contractor to incur additional Cost (and reasonable profit where applicable) over and above that which would otherwise have been incurred.

## 2. Compensable Event(s)

| # | Date | Event | Clause Relied Upon |
|---|------|-------|-------------------|
| 1 | [date] | [event description] | [Cl. ref] |
| 2 | [date] | [event description] | [Cl. ref] |

## 3. Causation Chain

[Demonstrate the chain: Event → Effect on Works → Resource Impact → Cost. Use:]
- Programme impact analysis (TIA / windows / collapsed as-built)
- Resource records (allocation sheets, daywork)
- Productivity comparison (planned vs actual)
- Method statements affected

## 4. Quantum — Heads of Loss & Expense

### 4.1 Prolongation Costs
| Item | Period | Rate | Amount |
|------|--------|------|--------|
| Site staff | [days] | $/day | $[…] |
| Site establishment | [days] | $/day | $[…] |
| Plant on standby | [days] | $/day | $[…] |
| Insurance & bonds extension | [days] | $/day | $[…] |
| Head office overhead (Hudson/Emden/Eichleay) | [%] | — | $[…] |

### 4.2 Disruption Costs (loss of productivity)
| Trade/Activity | Planned hrs | Actual hrs | Loss | Rate | Amount |
|----------------|-------------|------------|------|------|--------|
| [trade] | [hrs] | [hrs] | [hrs] | $/hr | $[…] |

### 4.3 Direct Cost Impact
- Additional materials / wastage: $[…]
- Additional plant hire: $[…]
- Acceleration costs (if instructed): $[…]
- Sub-contractor pass-through: $[…]

### 4.4 Finance & Profit
- Financing charges on outstanding sums: $[…]
- Reasonable profit: [%] of Cost = $[…]

### 4.5 Total Claimed
**Total Loss & Expense: $[…]**

## 5. Substantiation & Records

- Daily site records / labour allocation sheets
- Approved baseline + monthly progress updates
- Plant returns and hire invoices
- Sub-contractor variations and back-to-back claims
- Method statements and impact assessments
- Photographs / video records
- Correspondence (RFIs, instructions, meeting minutes)

## 6. Concurrent Delay Position

[State position on concurrent delay if relevant. Cite Henry Boot v Malmaison apportionment principle, or City Inn v Shepherd Construction (Scottish approach), as applicable.]

## 7. Reservation

The Contractor reserves the right to amend, supplement, or expand this claim. Without prejudice to any other rights or remedies under the Contract or at law.

Fully detailed claim with full supporting evidence is attached / will follow within the timeframes set by Sub-Clause 20.2.4.

Yours faithfully,

[Authorised Signatory]

---

**Attachments:**
- Programme impact analysis
- Quantum build-up (Excel)
- Supporting evidence bundle
"""
            },
            "psscoc": {
                "clause": "22.1",
                "period": "30 days from awareness",
                "template": """# LOSS & EXPENSE CLAIM
## Under Clause 22 PSSCOC

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**SO:** [Superintending Officer]
**Date:** {date}

---

**Dear [SO],**

The Contractor submits this Loss & Expense claim under Clause 22.1 PSSCOC arising from matters listed at Clause 22.1(a)–(g) which have materially affected the regular progress of the Works.

## 1. Compensable Matters

| # | Clause 22.1 head | Date | Event |
|---|------------------|------|-------|
| 1 | [(a)–(g)] | [date] | [event] |

## 2. Heads of Loss & Expense

### Prolongation
- Time-related preliminaries
- Extended site staff & supervision
- Plant standby / extended hire
- Insurance / bond extension
- Head office overhead recovery (Hudson / Emden / Eichleay formula — specify)

### Disruption
- Loss of productivity (measured-mile basis)
- Out-of-sequence working
- Trade stacking / acceleration

### Direct Costs
- Additional materials / wastage
- Sub-contractor disruption costs

### Finance
- Interest on capital tied up (Wadsworth v Lydall)

## 3. Quantum Summary

| Head | Amount (S$) |
|------|------------|
| Prolongation | […] |
| Disruption | […] |
| Direct costs | […] |
| Finance | […] |
| **Total** | **[…]** |

## 4. Substantiation

Full supporting documentation per Clause 22.1(2) attached / to follow.

## 5. Reservation

The Contractor reserves the right to add further heads / amend quantum as evidence develops. Without prejudice to claims for EOT under Clause 14 / 23.

Yours faithfully,

[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "24",
                "period": "As soon as reasonably apparent",
                "template": """# LOSS & EXPENSE CLAIM
## Under Clauses 23(1)(q) and 24 SIA Conditions (9th Ed.)

**Date:** {date}

---

This is the Contractor's claim for direct loss and/or expense pursuant to Clause 24 SIA Conditions arising from matters notified under Clause 23(1)(q).

## 1. Compensable Events
[List events with dates and Clause references]

## 2. Heads of Loss & Expense
- Prolongation: $[…]
- Disruption / loss of productivity: $[…]
- Direct costs: $[…]
- Finance charges: $[…]
- **Total:** $[…]

## 3. Substantiation
Full computations and supporting evidence attached.

Yours faithfully,

[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "20.2 read with relevant Sub-Clause",
                "period": "28 days from awareness",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# LOSS & EXPENSE CLAIM
## Under Sub-Clause 20.2 — FIDIC Yellow Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Date:** {date}
**Ref:** [Reference Number]

---

### 1. EVENT GIVING RISE TO LOSS & EXPENSE

[Describe the event(s). Identify the underlying Sub-Clause that entitles the Contractor to Cost (or Cost Plus Profit). Common Yellow Book grounds:
- 1.9 (errors in the Employer's Requirements)
- 4.6 (co-operation with Employer's other contractors)
- 4.12 (Unforeseeable physical conditions)
- 7.4 (Testing on Completion at Contractor's request)
- 8.5 + applicable Sub-Clause (EOT-related Cost)
- 8.9 (Suspension)
- 13 (Variations)
- 16.1 (Suspension by Contractor for non-payment)
- 17.x (Excepted Risks)]

### 2. NOTICE COMPLIANCE — SUB-CLAUSE 20.2.1

Notice of Claim served: [date]
Within 28 days of awareness: [Yes / No]

### 3. QUANTIFICATION

| Head | Sub-Clause / Basis | Amount |
|------|---------------------|--------|
| Prolongation costs | 8.5 + applicable Sub-Clause | $[amount] |
| Head office overhead (Emden / Hudson / Eichleay) | Established formula | $[amount] |
| Disruption / loss of productivity | (separate disruption analysis) | $[amount] |
| Design / redesign cost (Yellow Book specific) | Cl. 5 + applicable Sub-Clause | $[amount] |
| Additional resources | Cost records | $[amount] |
| Finance charges | Cl. 14.8 (delayed payment) | $[amount] |
| Profit (where Cost Plus Profit applies) | Sub-Clause invoked | $[amount] |
| **TOTAL** | | **$[amount]** |

### 4. CAUSATION

[Demonstrate the factual and contractual link between the event and each head of cost. For design-related events, show the impact on design effort, redesign cycles, and review periods.]

### 5. SUPPORTING DOCUMENTS

- Cost records / payroll / invoices
- Programme analysis (for prolongation period)
- Disruption analysis (for productivity loss)
- Design effort records (where design impact alleged)
- Subcontractor pass-through claims
- Finance / interest calculations

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "20.2.4",
                "period": "84 days from Notice of Claim",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# LOSS AND EXPENSE CLAIM
## Under Sub-Clause 20.2.4 — FIDIC Silver Book 2017 (EPC/Turnkey)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Employer's Representative:** [Employer's Representative Name]
**Date:** {date}
**Ref:** [Reference Number]

**Notice of Claim Ref:** [Reference to 20.2.1 notice]
**Notice of Claim Date:** [Date]

---

### 1. EXECUTIVE SUMMARY

This Loss and Expense claim is submitted pursuant to Sub-Clause 20.2.4.

**Silver Book context:** Under the EPC/Turnkey model, the Contractor assumes broader risk. This claim is limited to losses from events expressly the Employer's responsibility.

**Total amount claimed:** $[amount]

### 2. CONTRACTUAL BASIS

| Sub-Clause | Event | Entitlement |
|------------|-------|-------------|
| [Sub-Clause] | [Description] | Cost / Cost Plus Profit |

**EPC risk check:**
- [ ] Event is NOT within Contractor's assumed EPC risk
- [ ] Entitlement clause expressly provides for Cost / Cost Plus Profit
- [ ] Event caused by Employer or falls under express relief provision

### 3. CHRONOLOGY

| Date | Event | Reference |
|------|-------|-----------|
| [date] | [Event] | [ref] |

### 4. QUANTIFICATION

| Head | Basis | Amount |
|------|-------|--------|
| Prolongation — site overheads | Actual cost [X] months | $[amount] |
| Prolongation — HO overhead | Emden / Eichleay | $[amount] |
| Additional labour | Actual cost | $[amount] |
| Additional plant | Actual cost | $[amount] |
| Design / engineering | Actual cost | $[amount] |
| Subcontractor costs | Pass-through | $[amount] |
| Finance charges | Cl. 14 | $[amount] |
| Profit (if applicable) | Per Sub-Clause | $[amount] |
| **TOTAL** | | **$[amount]** |

#### Prolongation Detail

| Item | Monthly Cost | Duration | Amount |
|------|-------------|----------|--------|
| Site management | $[amount] | [X] months | $[amount] |
| Site facilities | $[amount] | [X] months | $[amount] |
| Insurance & bonds | $[amount] | [X] months | $[amount] |
| Plant on standby | $[amount] | [X] months | $[amount] |
| Design team | $[amount] | [X] months | $[amount] |
| **Subtotal** | | | **$[amount]** |

### 5. MITIGATION

- [Mitigation measure 1]
- [Mitigation measure 2]

### 6. SUPPORTING DOCUMENTS

| Document | Reference |
|----------|-----------|
| Notice of Claim (20.2.1) | [ref] |
| Chronology and correspondence | [ref] |
| Programme records | [ref] |
| Cost records | [ref] |
| HO overhead calculation | [ref] |

### 7. RESERVATION OF RIGHTS

The Contractor reserves all rights under the Contract and at law.

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    },
    "final-account": {
        "title": "Final Account Submission",
        "description": "Final account / final payment submission with full reconciliation",
        "forms": {
            "fidic-red": {
                "clause": "14.11 / 14.13",
                "period": "56 days after Performance Certificate",
                "template": """# FINAL ACCOUNT — STATEMENT AT COMPLETION / FINAL STATEMENT
## Under Sub-Clauses 14.10–14.13 of the Conditions of Contract

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Engineer:** [Engineer Name]
**Date:** {date}
**Ref:** [Reference Number]

---

**Dear [Engineer/Engineer's Representative],**

In accordance with Sub-Clause 14.11 (Statement at Completion) / 14.13 (Final Statement), the Contractor submits this Final Account in respect of the Works.

## 1. Reconciliation Summary

| Item | Amount (S$) |
|------|-------------|
| **Original Contract Sum** | […] |
| Add: Approved Variations (net) | […] |
| Add: Provisional Sums adjusted (actual vs allowance) | […] |
| Add: Loss & Expense determined | […] |
| Add: Fluctuations / price adjustment | […] |
| Less: Omissions / contra-charges | ([…]) |
| Less: Liquidated Damages (if any) | ([…]) |
| **Adjusted Contract Sum (Final)** | **[…]** |
| Less: Total payments certified to date | ([…]) |
| **Final Amount Due** | **[…]** |

## 2. Variations Schedule

| VO# | Date | Description | Amount (S$) | Status |
|-----|------|-------------|------------|--------|
| VO-001 | [date] | [scope] | […] | Approved/Pending |

[Attach full VO register]

## 3. Provisional Sums Adjustment

| PS Ref | Description | Allowed | Actual | Net Adjustment |
|--------|-------------|---------|--------|----------------|

## 4. Outstanding Claims

| Claim Ref | Description | Amount Claimed | Amount Certified | Difference |
|-----------|-------------|----------------|------------------|------------|

## 5. Defects Liability Period

- DLP commenced: [date]
- Performance Certificate expected: [date]
- Outstanding defects: [list / none]
- Retention release: [scheduled date]

## 6. Discharge

Upon agreement and payment of the Final Amount Due, the Contractor shall provide the discharge required by Sub-Clause 14.12, **subject to** the express reservations set out below.

## 7. Reservations

The Contractor expressly reserves rights in respect of:
- [Outstanding claim 1 — ref]
- [Outstanding dispute — ref]
- [Pending VO determinations]

Without prejudice to any rights under the Contract or at law.

Yours faithfully,

[Authorised Signatory]

---

**Attachments:**
- Final Variations Register (Excel)
- Provisional Sums Adjustment Schedule
- Outstanding Claims Schedule
- Sub-contractor final accounts
- Discharge wording (subject to reservations)
"""
            },
            "psscoc": {
                "clause": "31",
                "period": "Within 3 months of Maintenance Certificate",
                "template": """# FINAL ACCOUNT (FINAL PAYMENT CERTIFICATE)
## Under Clause 31 PSSCOC

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**SO:** [Superintending Officer]
**Date:** {date}

---

**Dear [SO],**

Pursuant to Clause 31 PSSCOC, the Contractor submits this Final Account for issue of the Final Payment Certificate.

## 1. Final Account Reconciliation

| Item | S$ |
|------|-----|
| Original Contract Sum | […] |
| Approved VOs (net) | […] |
| Provisional Sums adjusted | […] |
| Daywork | […] |
| Loss & Expense (Cl.22) | […] |
| Fluctuations (if applicable) | […] |
| Less: Omissions | ([…]) |
| Less: LD (Cl.32) | ([…]) |
| **Final Contract Sum** | **[…]** |
| Less: Interim payments | ([…]) |
| **Final Amount Due** | **[…]** |

## 2. Supporting Schedules

- VO Register (full list with SO instructions)
- Provisional Sum reconciliation
- Daywork records
- Outstanding claims reservation

## 3. Maintenance Period & Defects

- Maintenance Period commenced: [date]
- Maintenance Certificate expected: [date]
- Outstanding defects: [list / nil]

## 4. Reservations

The Contractor expressly reserves the right to pursue [outstanding claims / disputes] notwithstanding submission of this Final Account.

## 5. Release of Retention

Final release of retention sum requested upon issue of Maintenance Certificate per Clause 31.

Yours faithfully,

[Authorised Signatory]
"""
            },
            "sia": {
                "clause": "31(11)",
                "period": "Within 3 months of Maintenance Certificate",
                "template": """# FINAL ACCOUNT
## Under Clause 31(11) SIA Conditions (9th Ed.)

**Date:** {date}

---

Pursuant to Clause 31(11) SIA Conditions, the Contractor submits this Final Account.

## 1. Reconciliation

| Item | S$ |
|------|-----|
| Original Contract Sum | […] |
| Approved VOs (net) | […] |
| PC/Provisional Sums adjusted | […] |
| L&E (Cl.24) | […] |
| Less: Omissions / LD | ([…]) |
| **Final Sum** | **[…]** |
| Less: Interim Certificates | ([…]) |
| **Balance Due** | **[…]** |

## 2. Reservations
[Outstanding claims and disputes expressly reserved]

## 3. Maintenance Period
[Status of defects and Maintenance Certificate]

Yours faithfully,

[Authorised Signatory]
"""
            },
            "fidic-yellow": {
                "clause": "14.11 / 14.13",
                "period": "56 days after Performance Certificate",
                "template": """<!-- Edition: FIDIC Conditions of Contract for Plant and Design-Build, Second Edition 2017 (Yellow Book). Verify clause numbering if a different edition applies. -->
# FINAL STATEMENT
## Under Sub-Clause 14.11 — FIDIC Yellow Book 2017

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Performance Certificate Date:** [date]
**Date of submission:** {date}
**Ref:** [Reference Number]

> Submitted within 56 days of receiving the Performance Certificate per Sub-Clause 14.11 (Final Statement). The Final Payment Certificate is issued by the Engineer under Sub-Clause 14.13.

---

### 1. CONTRACT PRICE RECONCILIATION

| Item | Amount |
|------|--------|
| Accepted Contract Amount | $[amount] |
| Add: Variations approved (Cl. 13.3) | $[amount] |
| Add: Claims admitted | $[amount] |
| Add: Adjustments for changes in Laws (Cl. 13.6) | $[amount] |
| Less: Omissions | $[amount] |
| Less: Liquidated Damages (if any, Cl. 8.8) | ($[amount]) |
| **Final Contract Price** | **$[amount]** |

### 2. PAYMENTS RECEIVED

| IPC No. | Date | Amount |
|---------|------|--------|
| [X] | [date] | $[amount] |
| **Total Paid to Date** | | **$[amount]** |

### 3. AMOUNT DUE IN FINAL STATEMENT

| Heading | Amount |
|---------|--------|
| Final Contract Price | $[amount] |
| Less: Total previously paid | ($[amount]) |
| Less: Retention released to date | ($[amount]) |
| Add: Outstanding retention release (Cl. 14.9) | $[amount] |
| **Amount due in Final Statement** | **$[amount]** |

### 4. UNRESOLVED CLAIMS

[List any claims that are not agreed and remain in dispute. The Contractor expressly reserves rights in respect of these per Sub-Clause 14.12 (Discharge) and Sub-Clause 21 (Disputes and Arbitration).]

### 5. SUPPORTING DOCUMENTS

- Final Variation log
- Final Claims log (agreed and disputed)
- IPC summary (chronological)
- Retention reconciliation
- Performance Certificate (Sub-Clause 11.9)
- As-built records and operation/maintenance manuals (Sub-Clause 5.6)

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            },
            "fidic-silver": {
                "clause": "14.11",
                "period": "Per Sub-Clause 14.11 and Contract Data",
                "template": """<!-- Edition: FIDIC Conditions of Contract for EPC/Turnkey Projects, Second Edition 2017 (Silver Book). Verify clause numbering if a different edition applies. -->
# FINAL ACCOUNT SUBMISSION
## Under Sub-Clause 14.11 — FIDIC Silver Book 2017 (EPC/Turnkey)

**Contract:** [Contract Title]
**Contract No.:** [Contract Number]
**Employer:** [Employer Name]
**Contractor:** [Contractor Name]
**Employer's Representative:** [Employer's Representative Name]
**Date:** {date}
**Ref:** [Reference Number]

**Taking-Over Certificate Date:** [Date]
**Performance Certificate Date:** [Date, if issued]

---

### 1. SUBMISSION BASIS

This Final Statement is submitted under Sub-Clause 14.11 (FIDIC Silver Book 2017, EPC/Turnkey).

**Note:** The Contract Price is a lump sum. This reconciles the Accepted Contract Amount with approved Variations, determined claims, and permitted adjustments.

### 2. FINAL ACCOUNT SUMMARY

| Item | Reference | Amount |
|------|-----------|--------|
| **Accepted Contract Amount** | Contract Data | $[amount] |
| Variations (approved) | Schedule | $[amount] |
| Claims (determined) | Schedule | $[amount] |
| Provisional Sum adjustments | [ref] | $[amount] |
| Other adjustments | [ref] | $[amount] |
| **Revised Contract Price** | | **$[amount]** |
| Less: Previous payments | | ($[amount]) |
| Less: Deductions | | ($[amount]) |
| Add: Release of retention | | $[amount] |
| **Final balance due** | | **$[amount]** |

### 3. VARIATIONS SCHEDULE

| VO Ref | Description | Date | Amount |
|--------|-------------|------|--------|
| [ref] | [description] | [date] | $[amount] |
| | **Total** | | **$[amount]** |

### 4. CLAIMS SCHEDULE

| Claim Ref | Description | Status | Amount |
|-----------|-------------|--------|--------|
| [ref] | [description] | Determined / Pending | $[amount] |
| | **Total** | | **$[amount]** |

### 5. TESTS AND PERFORMANCE (Silver Book-specific)

- [ ] Tests on Completion (Sub-Clause 9) — passed
- [ ] Tests after Completion (Sub-Clause 12) — completed / pending
- [ ] Performance Guarantees — met / not met
- [ ] Defects liability — status

### 6. OUTSTANDING MATTERS

| Item | Description | Value | Status |
|------|-------------|-------|--------|
| [item] | [description] | $[amount] | Pending |

### 7. DISCHARGE

Upon receipt of the final balance, the Contractor shall provide written discharge confirming full and final settlement.

*Or: The Contractor reserves its position on: [list outstanding items]*

### 8. SUPPORTING DOCUMENTS

- [ ] Final Statement with breakdown
- [ ] Variations schedule
- [ ] Claims schedule
- [ ] As-built records
- [ ] Test certificates and performance records
- [ ] O&M manuals
- [ ] As-built drawings

Yours faithfully,

**[Contractor Name]**
[Authorised Signatory]
"""
            }
        }
    }
}

def list_templates():
    print("Available templates:\n")
    for key, tmpl in TEMPLATES.items():
        forms = ", ".join(tmpl["forms"].keys())
        print(f"  --type {key}")
        print(f"    {tmpl['title']}: {tmpl['description']}")
        print(f"    Available for: {forms}")
        print()

def generate_template(form, claim_type, output=None):
    if claim_type not in TEMPLATES:
        print(f"Error: Unknown type '{claim_type}'. Use --list to see available templates.")
        sys.exit(1)

    tmpl = TEMPLATES[claim_type]
    if form not in tmpl["forms"]:
        available = ", ".join(tmpl["forms"].keys())
        print(f"Error: Template '{claim_type}' not available for '{form}'. Available forms: {available}")
        sys.exit(1)

    form_tmpl = tmpl["forms"][form]
    content = form_tmpl["template"].format(date=datetime.now().strftime("%d %B %Y"))

    header = f"<!-- Template: {tmpl['title']} | Form: {form} | Clause: {form_tmpl['clause']} | Period: {form_tmpl['period']} -->\n"
    result = f"{VISIBLE_DISCLAIMER}\n{HTML_DISCLAIMER}\n{header}{content}"

    if output:
        with open(output, 'w') as f:
            f.write(result)
        print(f"Template written to {output}")
    else:
        print(result)

def _supported_forms():
    """Forms that actually have at least one template registered."""
    forms = set()
    for tmpl in TEMPLATES.values():
        forms.update(tmpl.get("forms", {}).keys())
    # Stable order
    order = ["fidic-red", "fidic-yellow", "fidic-silver", "psscoc", "sia", "nec4", "jct"]
    return [f for f in order if f in forms] + sorted(f for f in forms if f not in order)


def main():
    supported_forms = _supported_forms()
    parser = argparse.ArgumentParser(description="Generate construction claims/notice templates")
    parser.add_argument("--form", choices=supported_forms,
                       help="Contract form (only forms with registered templates are accepted)")
    parser.add_argument("--type", dest="claim_type",
                       choices=list(TEMPLATES.keys()),
                       help="Template type")
    parser.add_argument("--output", "-o", help="Output file path")
    parser.add_argument("--list", action="store_true", help="List available templates")
    args = parser.parse_args()

    if args.list:
        list_templates()
        return

    if not args.form or not args.claim_type:
        parser.error("--form and --type are required (or use --list)")

    # Friendly error if combo unsupported
    tmpl = TEMPLATES.get(args.claim_type, {})
    if args.form not in tmpl.get("forms", {}):
        available = sorted(tmpl.get("forms", {}).keys())
        parser.error(
            f"No '{args.claim_type}' template registered for form '{args.form}'. "
            f"Available forms for this type: {available or 'none'}. "
            f"Use --list to see the full support matrix."
        )

    generate_template(args.form, args.claim_type, args.output)

if __name__ == "__main__":
    main()


path: scripts/construction_law.py
content: #!/usr/bin/env python3
"""
Construction Law Skill — Unified CLI

A top-level dispatcher providing a single entry point for all skill scripts.
Run without arguments or with --help to see the full list of sub-commands.

Usage:
    python3 construction_law.py                     # show help
    python3 construction_law.py --list              # list all sub-commands
    python3 construction_law.py notices --form fidic-red
    python3 construction_law.py claims --form fidic-red --type disruption-claim
    python3 construction_law.py sop --claim-date 2026-05-15
    python3 construction_law.py compare --forms red,yellow --topic claims
    python3 construction_law.py obligations --form fidic-red
    python3 construction_law.py register --form fidic-red --type both --output reg.xlsx
    python3 construction_law.py delay --baseline-start 2026-05-01 --baseline-end 2026-12-31
"""
import os
import sys

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# Ensure sibling scripts are importable as plain modules (no dynamic loaders).
if SCRIPT_DIR not in sys.path:
    sys.path.insert(0, SCRIPT_DIR)

SUB_COMMANDS = {
    "intake":      ("intake",               "🏗️ Matter intake — guided issue triage (recommended starting point)"),
    "wizard":      ("wizard",               "🧙 Interactive guided prompts for tools"),
    "notices":     ("notice_calendar",      "Generate notice/obligations calendar for a contract form"),
    "claims":      ("claims_template",      "Generate claim notice/EOT/VO/disruption letters"),
    "sop":         ("sop_calculator",       "Singapore SOP Act payment timeline calculator"),
    "compare":     ("fidic_comparator",     "Compare FIDIC contract forms side-by-side"),
    "obligations": ("obligations_register", "Generate party-by-party obligations register"),
    "register":    ("excel_register",       "Generate Excel workbook of obligations + notices"),
    "delay":       ("delay_calculator",     "Delay analysis & EOT entitlement calculator"),
    "deadline":    ("fidic_deadline",       "FIDIC deadline calculator — Singapore bundled; bring-your-own-holidays for other seats"),
}

def print_help():
    print("Construction Law Skill — Unified CLI\n")
    print("Usage: construction_law.py <command> [options]\n")
    print("Available commands:\n")
    for cmd, (script, desc) in SUB_COMMANDS.items():
        print(f"  {cmd:12s} {desc}")
    print("\nRun any command with --help for its specific options, e.g.:")
    print("  python3 construction_law.py notices --help")
    print("  python3 construction_law.py claims --help\n")
    print("Or call the underlying script directly:")
    for cmd, (mod_name, _) in SUB_COMMANDS.items():
        print(f"  python3 {mod_name}.py ...")

def run_script(module_name, argv):
    """Import a sibling module by name and call its main() with the given argv."""
    saved_argv = sys.argv
    sys.argv = [f"{module_name}.py"] + argv
    try:
        mod = __import__(module_name)
        if hasattr(mod, "main"):
            mod.main()
        else:
            print(f"Error: module '{module_name}' has no main()", file=sys.stderr)
            sys.exit(2)
    finally:
        sys.argv = saved_argv

def main():
    if len(sys.argv) < 2 or sys.argv[1] in ("-h", "--help", "help"):
        print_help()
        sys.exit(0)
    if sys.argv[1] in ("--list", "-l", "list"):
        for cmd, (script, desc) in SUB_COMMANDS.items():
            print(f"{cmd:12s} -> {script:28s} {desc}")
        sys.exit(0)

    cmd = sys.argv[1]
    if cmd not in SUB_COMMANDS:
        print(f"Error: unknown command '{cmd}'\n", file=sys.stderr)
        print_help()
        sys.exit(1)

    module_name, _ = SUB_COMMANDS[cmd]
    run_script(module_name, sys.argv[2:])

if __name__ == "__main__":
    main()


path: scripts/delay_analysis.py
content: #!/usr/bin/env python3
"""Compatibility wrapper for delay_calculator.py."""

from delay_calculator import main

if __name__ == "__main__":
    main()


path: scripts/delay_calculator.py
content: #!/usr/bin/env python3
"""
Delay Analysis Calculator
Input delay events with dates and get critical path impact analysis.

Usage:
    python3 delay_calculator.py --baseline-start 2026-05-11 --baseline-end 2030-05-10 --events events.json
    python3 delay_calculator.py --baseline-start 2026-05-11 --baseline-end 2030-05-10 --interactive
    python3 delay_calculator.py --baseline-start 2026-05-11 --baseline-end 2030-05-10 --add "Late access|2026-06-01|2026-06-30|employer|critical" --add "Weather|2026-07-15|2026-07-25|neutral|critical"
"""

import argparse
import csv as csv_module
import json
import sys
import warnings
from datetime import datetime, timedelta

def parse_date(s):
    return datetime.strptime(s.strip(), "%Y-%m-%d")

def days_between(d1, d2):
    return (d2 - d1).days

def analyse_delays(baseline_start, baseline_end, events, fmt="md", output=None):
    baseline_duration = days_between(baseline_start, baseline_end)
    
    # Sort events by start date
    events.sort(key=lambda e: e["start"])
    
    # Calculate total delays by responsibility
    employer_delay = 0
    contractor_delay = 0
    neutral_delay = 0
    concurrent_days = 0
    
    # Track occupied delay periods for concurrency detection
    employer_periods = []
    contractor_periods = []
    
    for e in events:
        duration = days_between(e["start"], e["end"])
        e["duration"] = duration
        
        if e["responsibility"] == "employer":
            employer_delay += duration
            employer_periods.append((e["start"], e["end"]))
        elif e["responsibility"] == "contractor":
            contractor_delay += duration
            contractor_periods.append((e["start"], e["end"]))
        elif e["responsibility"] == "neutral":
            neutral_delay += duration
    
    # Detect concurrent delay (overlapping employer + contractor periods)
    for ep_start, ep_end in employer_periods:
        for cp_start, cp_end in contractor_periods:
            overlap_start = max(ep_start, cp_start)
            overlap_end = min(ep_end, cp_end)
            if overlap_start < overlap_end:
                concurrent_days += days_between(overlap_start, overlap_end)
    
    # Calculate net delay (simple impacted method)
    total_critical_delay = sum(e["duration"] for e in events if e.get("critical", True))
    total_non_critical = sum(e["duration"] for e in events if not e.get("critical", True))
    
    # EOT entitlement (employer + neutral delays on critical path, minus concurrency)
    eot_entitlement = sum(e["duration"] for e in events 
                         if e["responsibility"] in ("employer", "neutral") and e.get("critical", True))
    
    # Projected completion
    projected_end = baseline_end + timedelta(days=total_critical_delay)
    eot_completion = baseline_end + timedelta(days=eot_entitlement)
    
    # Exposure analysis
    ld_exposure_days = max(0, total_critical_delay - eot_entitlement)
    
    if fmt == "md":
        lines = [
            "# Delay Analysis Report",
            "",
            f"**Generated:** {datetime.now().strftime('%Y-%m-%d %H:%M')}",
            "",
            "---",
            "",
            "## Contract Dates",
            "",
            f"| Item | Date | Days |",
            f"|------|------|------|",
            f"| Baseline Start | {baseline_start.strftime('%d %b %Y')} | — |",
            f"| Baseline Completion | {baseline_end.strftime('%d %b %Y')} | {baseline_duration} days |",
            f"| Projected Completion | {projected_end.strftime('%d %b %Y')} | {baseline_duration + total_critical_delay} days |",
            f"| Completion with EOT | {eot_completion.strftime('%d %b %Y')} | {baseline_duration + eot_entitlement} days |",
            "",
            "## Delay Events",
            "",
            "| # | Event | Start | End | Duration | Responsibility | Critical? |",
            "|---|-------|-------|-----|----------|---------------|-----------|",
        ]
        
        for i, e in enumerate(events, 1):
            critical = "✅ Yes" if e.get("critical", True) else "❌ No"
            lines.append(f"| {i} | {e['description']} | {e['start'].strftime('%d %b %Y')} | {e['end'].strftime('%d %b %Y')} | {e['duration']} days | {e['responsibility'].title()} | {critical} |")
        
        lines.extend([
            "",
            "## Delay Summary",
            "",
            "| Category | Days |",
            "|----------|------|",
            f"| Employer-caused delay (critical) | {sum(e['duration'] for e in events if e['responsibility']=='employer' and e.get('critical',True))} days |",
            f"| Contractor-caused delay (critical) | {sum(e['duration'] for e in events if e['responsibility']=='contractor' and e.get('critical',True))} days |",
            f"| Neutral delay (critical) | {sum(e['duration'] for e in events if e['responsibility']=='neutral' and e.get('critical',True))} days |",
            f"| Non-critical delay (all) | {total_non_critical} days |",
            f"| Concurrent delay detected | {concurrent_days} days |",
            f"| **Total critical delay** | **{total_critical_delay} days** |",
            "",
            "## EOT & LD Analysis",
            "",
            "| Item | Value |",
            "|------|-------|",
            f"| EOT Entitlement (employer + neutral, critical) | **{eot_entitlement} days** |",
            f"| Contractor's own delay (critical) | {sum(e['duration'] for e in events if e['responsibility']=='contractor' and e.get('critical',True))} days |",
            f"| LD Exposure (delay beyond EOT) | **{ld_exposure_days} days** |",
            f"| Concurrent delay | {concurrent_days} days |",
            "",
            "## Concurrency Note",
            "",
        ])
        
        if concurrent_days > 0:
            lines.extend([
                f"⚠️ **{concurrent_days} days of concurrent delay detected** — employer and contractor delays overlap.",
                "",
                "**Treatment depends on jurisdiction:**",
                "- **Malmaison (England)**: Contractor gets EOT but no prolongation costs for concurrent period",
                "- **Singapore**: Apportionment approach — SO/Architect may grant partial EOT",
                "- **SCL Protocol**: If true concurrency, EOT granted but costs not recoverable",
                "",
            ])
        else:
            lines.append("No concurrent delay detected.")
            lines.append("")
        
        lines.extend([
            "## Recommendations",
            "",
            "1. **Preserve notices** — ensure all delay events have been properly notified under the contract",
            "2. **Update programme** — submit revised programme showing delay impact",
            "3. **Maintain records** — daily site diaries, progress photos, resource records",
            "4. **Quantify costs** — prepare prolongation cost calculation for EOT period",
            "5. **Mitigate** — document all mitigation measures taken",
            "",
            "---",
            "",
            "⚠️ **Disclaimer**: This is a simplified impacted as-planned analysis. For complex disputes, a Time Impact Analysis (TIA) or Windows Analysis by a delay expert is recommended.",
            "",
            f"*Generated by Construction Law Skill v2.8.1*",
        ])
        
        result = "\n".join(lines)
        if output:
            with open(output, 'w') as f:
                f.write(result)
            print(f"Report written to {output}")
        else:
            print(result)

    elif fmt == "csv":
        import csv
        out = open(output, 'w', newline='') if output else sys.stdout
        writer = csv.writer(out)
        writer.writerow(["Delay Analysis Report"])
        writer.writerow(["Baseline Start", baseline_start.strftime('%Y-%m-%d')])
        writer.writerow(["Baseline Completion", baseline_end.strftime('%Y-%m-%d')])
        writer.writerow(["Baseline Duration", f"{baseline_duration} days"])
        writer.writerow(["Projected Completion", projected_end.strftime('%Y-%m-%d')])
        writer.writerow(["EOT Entitlement", f"{eot_entitlement} days"])
        writer.writerow(["LD Exposure", f"{ld_exposure_days} days"])
        writer.writerow([])
        writer.writerow(["#", "Event", "Start", "End", "Duration", "Responsibility", "Critical"])
        for i, e in enumerate(events, 1):
            writer.writerow([i, e['description'], e['start'].strftime('%Y-%m-%d'),
                           e['end'].strftime('%Y-%m-%d'), e['duration'],
                           e['responsibility'], "Yes" if e.get('critical', True) else "No"])
        if output:
            out.close()
            print(f"CSV written to {output}")

    elif fmt == "json":
        result = {
            "baseline": {"start": baseline_start.strftime('%Y-%m-%d'), "end": baseline_end.strftime('%Y-%m-%d'), "duration": baseline_duration},
            "projected_completion": projected_end.strftime('%Y-%m-%d'),
            "eot_completion": eot_completion.strftime('%Y-%m-%d'),
            "eot_entitlement_days": eot_entitlement,
            "ld_exposure_days": ld_exposure_days,
            "concurrent_delay_days": concurrent_days,
            "total_critical_delay": total_critical_delay,
            "events": [{"description": e["description"], "start": e["start"].strftime('%Y-%m-%d'),
                        "end": e["end"].strftime('%Y-%m-%d'), "duration": e["duration"],
                        "responsibility": e["responsibility"], "critical": e.get("critical", True)}
                       for e in events]
        }
        output_str = json.dumps(result, indent=2)
        if output:
            with open(output, 'w') as f:
                f.write(output_str)
            print(f"JSON written to {output}")
        else:
            print(output_str)

def _parse_criticality(value):
    """Parse criticality string to boolean. Accepts 'critical', 'non-critical', 'yes', 'no', 'true', 'false'."""
    return value.strip().lower() not in ("non-critical", "no", "false", "0")


def main():
    parser = argparse.ArgumentParser(
        description="Delay Analysis Calculator",
        epilog="""Examples:
  # Structured event (recommended):
  %(prog)s --baseline-start 2026-05-11 --baseline-end 2030-05-10 \\
    --add-event "Late access" 2026-06-01 2026-06-30 employer critical

  # Events from CSV file:
  %(prog)s --baseline-start 2026-05-11 --baseline-end 2030-05-10 \\
    --events-csv events.csv

  # Legacy pipe-delimited (deprecated):
  %(prog)s --baseline-start 2026-05-11 --baseline-end 2030-05-10 \\
    --add "Late access|2026-06-01|2026-06-30|employer|critical"
""",
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument("--baseline-start", required=True, help="Baseline start date (YYYY-MM-DD)")
    parser.add_argument("--baseline-end", required=True, help="Baseline completion date (YYYY-MM-DD)")
    parser.add_argument("--events", help="JSON file with delay events")
    parser.add_argument(
        "--add", action="append", metavar="'desc|start|end|cause|criticality'",
        help="(DEPRECATED — use --add-event or --events-csv) Add event as pipe-delimited string: "
             "'description|start_date|end_date|responsibility|critical/non-critical'. "
             "Field values must NOT contain pipe characters."
    )
    parser.add_argument(
        "--add-event", action="append", nargs=5,
        metavar=("DESCRIPTION", "START", "END", "CAUSE", "CRITICALITY"),
        help="Add a structured delay event (repeatable). "
             "CAUSE: employer|contractor|neutral. "
             "CRITICALITY: critical|non-critical."
    )
    parser.add_argument(
        "--events-csv",
        help="CSV file with columns: description, start_date, end_date, cause, criticality"
    )
    parser.add_argument("--format", default="md", choices=["md", "csv", "json"])
    parser.add_argument("--output", "-o")
    args = parser.parse_args()

    bs = parse_date(args.baseline_start)
    be = parse_date(args.baseline_end)
    events = []

    if args.events:
        with open(args.events) as f:
            raw = json.load(f)
        for e in raw:
            events.append({
                "description": e["description"],
                "start": parse_date(e["start"]),
                "end": parse_date(e["end"]),
                "responsibility": e.get("responsibility", "employer"),
                "critical": e.get("critical", True)
            })

    # --add (legacy pipe-delimited, deprecated)
    if args.add:
        warnings.warn(
            "--add is deprecated and will be removed in v3.0. "
            "Use --add-event or --events-csv instead.",
            DeprecationWarning,
            stacklevel=2,
        )
        for a in args.add:
            parts = a.split("|")
            if len(parts) > 5:
                print(
                    f"Error: --add value has {len(parts)} pipe-separated fields (expected 4-5).\n"
                    f"  If a field contains a pipe character, use --add-event or --events-csv instead.\n"
                    f"  Example: --add-event \"Late access\" 2026-06-01 2026-06-30 employer critical",
                    file=sys.stderr,
                )
                sys.exit(1)
            if len(parts) < 4:
                print(f"Error: --add format is 'description|start|end|responsibility[|critical]'")
                sys.exit(1)
            events.append({
                "description": parts[0].strip(),
                "start": parse_date(parts[1]),
                "end": parse_date(parts[2]),
                "responsibility": parts[3].strip().lower(),
                "critical": _parse_criticality(parts[4]) if len(parts) > 4 else True
            })

    # --add-event (structured, recommended)
    if args.add_event:
        for ev in args.add_event:
            desc, start, end, cause, crit = ev
            events.append({
                "description": desc,
                "start": parse_date(start),
                "end": parse_date(end),
                "responsibility": cause.strip().lower(),
                "critical": _parse_criticality(crit)
            })

    # --events-csv
    if args.events_csv:
        with open(args.events_csv, newline='') as csvfile:
            reader = csv_module.DictReader(csvfile)
            for row in reader:
                events.append({
                    "description": row["description"].strip(),
                    "start": parse_date(row["start_date"]),
                    "end": parse_date(row["end_date"]),
                    "responsibility": row["cause"].strip().lower(),
                    "critical": _parse_criticality(row["criticality"])
                })

    if not events:
        print("Error: No events provided. Use --events, --add-event, or --events-csv")
        sys.exit(1)

    analyse_delays(bs, be, events, args.format, args.output)

if __name__ == "__main__":
    main()


path: scripts/excel_register.py
content: #!/usr/bin/env python3
"""
Excel Obligations Register & Notice Calendar Generator
Exports obligations registers and notice calendars to .xlsx format with formatting.

Usage:
    python3 excel_register.py --form fidic-red --type obligations --output obligations.xlsx
    python3 excel_register.py --form psscoc --type notices --output notices.xlsx
    python3 excel_register.py --form fidic-red --type both --output contract_admin.xlsx
    python3 excel_register.py --form fidic-red --type obligations --commencement 2026-05-11
"""

import argparse
import sys
from datetime import datetime

try:
    import openpyxl
    from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
    from openpyxl.utils import get_column_letter
except ImportError:
    print("Error: openpyxl is required for Excel output.")
    print("Install with: pip3 install openpyxl")
    print("  or: pip3 install construction-law[excel]")
    sys.exit(1)

# Import data from sibling scripts
import os

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
if SCRIPT_DIR not in sys.path:
    sys.path.insert(0, SCRIPT_DIR)

def get_obligations(form):
    import obligations_register as mod
    if form not in mod.OBLIGATIONS:
        return None, None
    db = mod.OBLIGATIONS[form]
    return db["name"], db

def get_notices(form):
    import notice_calendar as mod
    if form not in mod.NOTICE_DATABASES:
        return None, None
    db = mod.NOTICE_DATABASES[form]
    return db["name"], db

# Styles
HEADER_FONT = Font(bold=True, color="FFFFFF", size=11)
HEADER_FILL = PatternFill(start_color="2F5496", end_color="2F5496", fill_type="solid")
CRITICAL_FILL = PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid")
HIGH_FILL = PatternFill(start_color="FFEB9C", end_color="FFEB9C", fill_type="solid")
TITLE_FONT = Font(bold=True, size=14, color="2F5496")
SUBTITLE_FONT = Font(bold=True, size=11, color="2F5496")
THIN_BORDER = Border(
    left=Side(style='thin'), right=Side(style='thin'),
    top=Side(style='thin'), bottom=Side(style='thin')
)

def style_header(ws, row, col_count):
    for col in range(1, col_count + 1):
        cell = ws.cell(row=row, column=col)
        cell.font = HEADER_FONT
        cell.fill = HEADER_FILL
        cell.alignment = Alignment(horizontal='center', wrap_text=True)
        cell.border = THIN_BORDER

def style_data_cell(cell, priority=None):
    cell.border = THIN_BORDER
    cell.alignment = Alignment(wrap_text=True, vertical='top')
    if priority == "Critical":
        cell.fill = CRITICAL_FILL
    elif priority == "High":
        cell.fill = HIGH_FILL

def auto_width(ws, min_width=10, max_width=50):
    for col in ws.columns:
        max_len = 0
        col_letter = get_column_letter(col[0].column)
        for cell in col:
            if cell.value:
                max_len = max(max_len, len(str(cell.value)))
        width = min(max(max_len + 2, min_width), max_width)
        ws.column_dimensions[col_letter].width = width

def create_obligations_sheet(wb, form, commencement=None):
    name, db = get_obligations(form)
    if not db:
        print(f"No obligations data for form '{form}'")
        return

    for party in ["contractor", "employer"]:
        items = db.get(party, [])
        if not items:
            continue
        
        ws = wb.create_sheet(title=f"{party.title()} Obligations")
        
        # Title
        ws.cell(row=1, column=1, value=f"{party.title()} Obligations Register — {name}")
        ws.cell(row=1, column=1).font = TITLE_FONT
        ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=8)
        
        ws.cell(row=2, column=1, value=f"Generated: {datetime.now().strftime('%d %B %Y')}")
        ws.cell(row=2, column=1).font = SUBTITLE_FONT
        if commencement:
            ws.cell(row=2, column=4, value=f"Commencement: {commencement}")
            ws.cell(row=2, column=4).font = SUBTITLE_FONT
        
        # Headers
        headers = ["#", "Clause", "Obligation", "Timing", "Priority", "Category", "Status", "Notes / Action Required"]
        row = 4
        for col, h in enumerate(headers, 1):
            ws.cell(row=row, column=col, value=h)
        style_header(ws, row, len(headers))
        
        # Data
        for i, ob in enumerate(items, 1):
            row += 1
            values = [i, ob["clause"], ob["obligation"], ob["timing"], 
                     ob["priority"], ob["category"], "Pending", ""]
            for col, v in enumerate(values, 1):
                cell = ws.cell(row=row, column=col, value=v)
                style_data_cell(cell, ob["priority"])
        
        # Conditional formatting note
        row += 2
        ws.cell(row=row, column=1, value="Legend:")
        ws.cell(row=row, column=1).font = Font(bold=True)
        row += 1
        ws.cell(row=row, column=1, value="Red = Critical priority")
        ws.cell(row=row, column=1).fill = CRITICAL_FILL
        row += 1
        ws.cell(row=row, column=1, value="Yellow = High priority")
        ws.cell(row=row, column=1).fill = HIGH_FILL
        
        auto_width(ws)
        
        # Freeze panes
        ws.freeze_panes = "A5"

def create_notices_sheet(wb, form, commencement=None):
    name, db = get_notices(form)
    if not db:
        print(f"No notice data for form '{form}'")
        return
    
    ws = wb.create_sheet(title="Notice Calendar")
    
    # Title
    ws.cell(row=1, column=1, value=f"Notice Calendar — {name}")
    ws.cell(row=1, column=1).font = TITLE_FONT
    ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=7)
    
    ws.cell(row=2, column=1, value=f"Generated: {datetime.now().strftime('%d %B %Y')}")
    ws.cell(row=2, column=1).font = SUBTITLE_FONT
    if commencement:
        ws.cell(row=2, column=4, value=f"Commencement: {commencement}")
        ws.cell(row=2, column=4).font = SUBTITLE_FONT
    
    # Headers
    headers = ["#", "Clause", "Event / Obligation", "Notice Period", "Recipient", "Consequence of Non-Compliance", "Category"]
    row = 4
    for col, h in enumerate(headers, 1):
        ws.cell(row=row, column=col, value=h)
    style_header(ws, row, len(headers))
    
    notices = sorted(db["notices"], key=lambda x: (x["category"], x["clause"]))
    
    current_category = None
    i = 0
    for n in notices:
        row += 1
        i += 1
        
        # Category separator
        if n["category"] != current_category:
            current_category = n["category"]
        
        is_timebar = "TIME-BAR" in n["consequence"].upper() or "FINAL" in n["consequence"].upper()
        
        values = [i, n["clause"], n["event"], n["period"], n["recipient"], n["consequence"], n["category"]]
        for col, v in enumerate(values, 1):
            cell = ws.cell(row=row, column=col, value=v)
            cell.border = THIN_BORDER
            cell.alignment = Alignment(wrap_text=True, vertical='top')
            if is_timebar:
                cell.fill = CRITICAL_FILL
    
    auto_width(ws)
    ws.freeze_panes = "A5"

def main():
    parser = argparse.ArgumentParser(description="Excel Register Generator")
    parser.add_argument("--form", required=True, choices=["fidic-red", "fidic-yellow", "fidic-silver", "psscoc", "sia", "nec4"])
    parser.add_argument("--type", required=True, choices=["obligations", "notices", "both"])
    parser.add_argument("--output", "-o", required=True, help="Output .xlsx file path")
    parser.add_argument("--commencement", help="Commencement date (YYYY-MM-DD)")
    args = parser.parse_args()

    # Pre-flight: refuse to write half-empty workbooks.
    # Real coverage as of v2.6.0:
    #   obligations: fidic-red, psscoc, sia
    #   notices:     fidic-red, fidic-yellow, psscoc, sia, nec4
    OBLIGATIONS_FORMS = {"fidic-red", "fidic-yellow", "fidic-silver", "psscoc", "sia"}
    NOTICES_FORMS = {"fidic-red", "fidic-yellow", "fidic-silver", "psscoc", "sia", "nec4"}

    want_obl = args.type in ("obligations", "both")
    want_not = args.type in ("notices", "both")

    missing = []
    if want_obl and args.form not in OBLIGATIONS_FORMS:
        missing.append(f"obligations data not available for '{args.form}' (supported: {sorted(OBLIGATIONS_FORMS)})")
    if want_not and args.form not in NOTICES_FORMS:
        missing.append(f"notices data not available for '{args.form}' (supported: {sorted(NOTICES_FORMS)})")

    if missing:
        for m in missing:
            print(f"Error: {m}", file=sys.stderr)
        if args.type == "both":
            print("Hint: try --type notices (broader coverage) or pick a different --form.", file=sys.stderr)
        sys.exit(2)

    wb = openpyxl.Workbook()
    # Remove default sheet
    wb.remove(wb.active)
    
    if want_obl:
        create_obligations_sheet(wb, args.form, args.commencement)
    
    if want_not:
        create_notices_sheet(wb, args.form, args.commencement)
    
    wb.save(args.output)
    print(f"Excel workbook saved to {args.output}")

if __name__ == "__main__":
    main()


path: scripts/fidic_comparator.py
content: #!/usr/bin/env python3
"""
FIDIC Contract Form Comparator
Side-by-side comparison of FIDIC Red, Yellow, Silver, and Emerald Books.

Usage:
    python3 fidic_comparator.py --forms red,yellow,silver
    python3 fidic_comparator.py --forms red,yellow --topic risk
    python3 fidic_comparator.py --forms red,silver --topic all --format csv --output comparison.csv
"""

import argparse
import sys

COMPARISONS = {
    "overview": {
        "title": "Contract Overview",
        "items": [
            {"aspect": "Full Name", "red": "Conditions of Contract for Construction", "yellow": "Conditions of Contract for Plant & Design-Build", "silver": "Conditions of Contract for EPC/Turnkey Projects", "emerald": "Conditions of Contract for Underground Works"},
            {"aspect": "Typical Use", "red": "Employer-designed traditional works", "yellow": "Design & Build projects", "silver": "Large industrial, power, PPP/BOT", "emerald": "Tunnelling, underground construction"},
            {"aspect": "Design Responsibility", "red": "Employer", "yellow": "Contractor", "silver": "Contractor", "emerald": "Shared (GBR-based)"},
            {"aspect": "Payment Basis", "red": "Re-measurement (item rates)", "yellow": "Lump sum", "silver": "Lump sum (fixed price)", "emerald": "Re-measurement with GBR adjustment"},
            {"aspect": "Engineer Role", "red": "Yes — administers contract", "yellow": "Yes — administers contract", "silver": "No Engineer — Employer's Representative", "emerald": "Yes — with geotechnical expertise"},
            {"aspect": "Price Level", "red": "Lowest bid price", "yellow": "Medium bid price", "silver": "Highest bid price", "emerald": "Medium-High"},
            {"aspect": "Employer Involvement", "red": "High (designs + supervises)", "yellow": "Medium (sets requirements)", "silver": "Low (turnkey delivery)", "emerald": "Medium (GBR preparation)"},
        ]
    },
    "risk": {
        "title": "Risk Allocation",
        "items": [
            {"aspect": "Design Risk", "red": "Employer", "yellow": "Contractor", "silver": "Contractor", "emerald": "Shared per GBR"},
            {"aspect": "Quantity Risk", "red": "Employer (re-measurement)", "yellow": "Contractor (lump sum)", "silver": "Contractor (lump sum)", "emerald": "Employer (re-measurement)"},
            {"aspect": "Ground Conditions", "red": "Employer (unforeseeable — Cl.4.12)", "yellow": "Shared (Cl.4.12 applies)", "silver": "Contractor (deemed included)", "emerald": "Shared per GBR baseline"},
            {"aspect": "Exceptional Climate", "red": "Employer (EOT)", "yellow": "Employer (EOT)", "silver": "Contractor (no relief)", "emerald": "Employer (EOT)"},
            {"aspect": "Force Majeure", "red": "Shared (Cl.18)", "yellow": "Shared (Cl.18)", "silver": "Limited Contractor relief", "emerald": "Shared (Cl.18)"},
            {"aspect": "Changes in Law", "red": "Employer (Cl.13.6)", "yellow": "Employer (Cl.13.6)", "silver": "Contractor (limited relief)", "emerald": "Employer (Cl.13.6)"},
            {"aspect": "Errors in Requirements", "red": "Employer (own design)", "yellow": "Shared (Contractor must check)", "silver": "Contractor (deemed verified)", "emerald": "Per GBR allocation"},
            {"aspect": "Design Standard of Care", "red": "N/A (Employer designs)", "yellow": "Fitness for purpose", "silver": "Fitness for purpose", "emerald": "Fitness for purpose (within GBR)"},
            {"aspect": "Overall Risk to Contractor", "red": "LOW", "yellow": "MEDIUM", "silver": "HIGH", "emerald": "MEDIUM"},
        ]
    },
    "claims": {
        "title": "Claims & Time-Bars",
        "items": [
            {"aspect": "Notice of Claim", "red": "28 days (Cl.20.2.1)", "yellow": "28 days (Cl.20.2.1)", "silver": "28 days (Cl.20.2.1)", "emerald": "28 days (Cl.20.2.1)"},
            {"aspect": "Time-Bar Effect", "red": "Claim deemed time-barred", "yellow": "Claim deemed time-barred", "silver": "Claim deemed time-barred", "emerald": "Claim deemed time-barred"},
            {"aspect": "Detailed Claim", "red": "84 days from Notice", "yellow": "84 days from Notice", "silver": "84 days from Notice", "emerald": "84 days from Notice"},
            {"aspect": "Late Notice Safeguard (Cl.20.2.7)", "red": "Engineer must notify if late", "yellow": "Engineer must notify if late", "silver": "ER must notify if late", "emerald": "Engineer must notify if late"},
            {"aspect": "EOT Entitlement", "red": "Broad (Cl.8.4/8.5)", "yellow": "Broad (Cl.8.4/8.5)", "silver": "Very limited", "emerald": "Broad + GBR-based"},
            {"aspect": "Unforeseeable Conditions", "red": "Entitled (Cl.4.12)", "yellow": "Entitled (Cl.4.12)", "silver": "NOT entitled (deemed included)", "emerald": "Per GBR — better than baseline = Employer benefit"},
            {"aspect": "Variation Procedure", "red": "Engineer instructs (Cl.13)", "yellow": "Engineer instructs (Cl.13)", "silver": "ER instructs (limited)", "emerald": "Engineer instructs (Cl.13)"},
            {"aspect": "Cost Definition", "red": "Expenditure + overhead, NOT profit", "yellow": "Expenditure + overhead, NOT profit", "silver": "Expenditure + overhead, NOT profit", "emerald": "Expenditure + overhead, NOT profit"},
            {"aspect": "Cost + Profit Events", "red": "Cl.4.12, some Cl.13 events", "yellow": "Cl.4.12, some Cl.13 events", "silver": "Very few", "emerald": "GBR-related events"},
        ]
    },
    "disputes": {
        "title": "Dispute Resolution",
        "items": [
            {"aspect": "Dispute Board", "red": "Standing DAAB (mandatory)", "yellow": "Standing DAAB (mandatory)", "silver": "Ad hoc DAAB (optional)", "emerald": "Standing DAAB (mandatory)"},
            {"aspect": "DAAB Decision Period", "red": "84 days", "yellow": "84 days", "silver": "84 days", "emerald": "84 days"},
            {"aspect": "DAAB Decision Binding?", "red": "Binding (subject to NOD)", "yellow": "Binding (subject to NOD)", "silver": "Binding (subject to NOD)", "emerald": "Binding (subject to NOD)"},
            {"aspect": "NOD Period", "red": "28 days after DAAB decision", "yellow": "28 days after DAAB decision", "silver": "28 days after DAAB decision", "emerald": "28 days after DAAB decision"},
            {"aspect": "Arbitration", "red": "After NOD + 28 days", "yellow": "After NOD + 28 days", "silver": "After NOD + 28 days", "emerald": "After NOD + 28 days"},
            {"aspect": "Non-compliance Enforcement", "red": "Direct to arbitration (Persero)", "yellow": "Direct to arbitration (Persero)", "silver": "Direct to arbitration", "emerald": "Direct to arbitration"},
            {"aspect": "Engineer Neutrality", "red": "Must act neutrally (Cl.3.7)", "yellow": "Must act neutrally (Cl.3.7)", "silver": "No Engineer role", "emerald": "Must act neutrally (Cl.3.7)"},
        ]
    },
    "payment": {
        "title": "Payment Mechanisms",
        "items": [
            {"aspect": "Interim Payments", "red": "Monthly (Cl.14.3)", "yellow": "Monthly (Cl.14.3)", "silver": "Per milestones or monthly", "emerald": "Monthly (Cl.14.3)"},
            {"aspect": "IPC by Engineer", "red": "28 days from Statement", "yellow": "28 days from Statement", "silver": "N/A (no Engineer)", "emerald": "28 days from Statement"},
            {"aspect": "Employer Payment", "red": "56 days from Statement", "yellow": "56 days from Statement", "silver": "56 days from Statement", "emerald": "56 days from Statement"},
            {"aspect": "Late Payment Remedy", "red": "Financing charges (Cl.14.8)", "yellow": "Financing charges (Cl.14.8)", "silver": "Financing charges (Cl.14.8)", "emerald": "Financing charges (Cl.14.8)"},
            {"aspect": "Right to Suspend", "red": "42 days unpaid (Cl.16.1)", "yellow": "42 days unpaid (Cl.16.1)", "silver": "42 days unpaid (Cl.16.1)", "emerald": "42 days unpaid (Cl.16.1)"},
            {"aspect": "Retention", "red": "Per Contract Data", "yellow": "Per Contract Data", "silver": "Per Contract Data", "emerald": "Per Contract Data"},
            {"aspect": "Advance Payment", "red": "Per Contract Data (Cl.14.2)", "yellow": "Per Contract Data (Cl.14.2)", "silver": "Per Contract Data (Cl.14.2)", "emerald": "Per Contract Data (Cl.14.2)"},
            {"aspect": "Price Adjustment", "red": "Cl.13.7 (if applicable)", "yellow": "Cl.13.7 (if applicable)", "silver": "Usually excluded", "emerald": "Cl.13.7 (if applicable)"},
        ]
    },
    "termination": {
        "title": "Termination Provisions",
        "items": [
            {"aspect": "Employer Termination", "red": "Cl.15.2 (14 days notice after Notice to Correct)", "yellow": "Cl.15.2 (same)", "silver": "Cl.15.2 (same)", "emerald": "Cl.15.2 (same)"},
            {"aspect": "Employer Convenience", "red": "Cl.15.5 (at any time)", "yellow": "Cl.15.5 (at any time)", "silver": "Cl.15.5 (at any time)", "emerald": "Cl.15.5 (at any time)"},
            {"aspect": "Contractor Termination", "red": "Cl.16.2 (14 days notice)", "yellow": "Cl.16.2 (same)", "silver": "Cl.16.2 (same)", "emerald": "Cl.16.2 (same)"},
            {"aspect": "Exceptional Event Termination", "red": "Cl.18.5 (>84 days, 7 days notice)", "yellow": "Cl.18.5 (same)", "silver": "Limited", "emerald": "Cl.18.5 (same)"},
            {"aspect": "Payment on Termination", "red": "Cl.15.3/16.3 (valuation)", "yellow": "Cl.15.3/16.3 (same)", "silver": "Cl.15.3/16.3 (same)", "emerald": "Cl.15.3/16.3 (same)"},
        ]
    }
}

FORM_NAMES = {
    "red": "Red Book",
    "yellow": "Yellow Book",
    "silver": "Silver Book",
    "emerald": "Emerald Book"
}

# Aliases for cross-script consistency (e.g. fidic-red → red)
FORM_ALIASES = {
    "fidic-red": "red",
    "fidic-yellow": "yellow",
    "fidic-silver": "silver",
    "fidic-emerald": "emerald"
}

def compare(forms, topic, fmt, output):
    form_list = [FORM_ALIASES.get(f.strip().lower(), f.strip().lower()) for f in forms.split(",")]
    for f in form_list:
        if f not in FORM_NAMES:
            print(f"Error: Unknown form '{f}'. Available: {', '.join(FORM_NAMES.keys())} (aliases: {', '.join(FORM_ALIASES.keys())})")
            sys.exit(1)

    topics = list(COMPARISONS.keys()) if topic == "all" else [topic]
    for t in topics:
        if t not in COMPARISONS:
            print(f"Error: Unknown topic '{t}'. Available: {', '.join(COMPARISONS.keys())}, all")
            sys.exit(1)

    if fmt == "md":
        lines = ["# FIDIC Contract Comparison", "",
                 f"**Forms:** {', '.join(FORM_NAMES[f] for f in form_list)}",
                 f"**Generated:** {__import__('datetime').datetime.now().strftime('%Y-%m-%d %H:%M')}",
                 ""]

        for t in topics:
            comp = COMPARISONS[t]
            lines.append(f"## {comp['title']}")
            lines.append("")
            header = "| Aspect | " + " | ".join(FORM_NAMES[f] for f in form_list) + " |"
            sep = "|--------|" + "|".join("------" for _ in form_list) + "|"
            lines.append(header)
            lines.append(sep)
            for item in comp["items"]:
                row = f"| **{item['aspect']}** | " + " | ".join(item.get(f, "N/A") for f in form_list) + " |"
                lines.append(row)
            lines.append("")

        result = "\n".join(lines)
        if output:
            with open(output, 'w') as f:
                f.write(result)
            print(f"Comparison written to {output}")
        else:
            print(result)

    elif fmt == "csv":
        import csv
        out = open(output, 'w', newline='') if output else sys.stdout
        writer = csv.writer(out)
        for t in topics:
            comp = COMPARISONS[t]
            writer.writerow([comp["title"]])
            writer.writerow(["Aspect"] + [FORM_NAMES[f] for f in form_list])
            for item in comp["items"]:
                writer.writerow([item["aspect"]] + [item.get(f, "N/A") for f in form_list])
            writer.writerow([])
        if output:
            out.close()
            print(f"CSV written to {output}")

def main():
    parser = argparse.ArgumentParser(description="FIDIC Contract Form Comparator")
    parser.add_argument("--forms", help="Comma-separated forms: red,yellow,silver,emerald (or fidic-red etc)")
    parser.add_argument("--topic", default="all",
                       choices=list(COMPARISONS.keys()) + ["all"],
                       help="Comparison topic (default: all)")
    parser.add_argument("--format", default="md", choices=["md", "csv"])
    parser.add_argument("--output", "-o")
    parser.add_argument("--list-forms", action="store_true", help="List available FIDIC forms and exit")
    parser.add_argument("--list-topics", action="store_true", help="List available comparison topics and exit")
    args = parser.parse_args()

    if args.list_forms:
        print("Available FIDIC forms:")
        for k, v in FORM_NAMES.items():
            print(f"  {k:10s} — {v}")
        print("\nAliases (for consistency with other scripts):")
        for k, v in FORM_ALIASES.items():
            print(f"  {k:14s} → {v}")
        sys.exit(0)
    if args.list_topics:
        print("Available topics:")
        for k, v in COMPARISONS.items():
            print(f"  {k:12s} — {v.get('title', k)}")
        sys.exit(0)
    if not args.forms:
        parser.error("--forms is required (use --list-forms to see options)")
    compare(args.forms, args.topic, args.format, args.output)

if __name__ == "__main__":
    main()


path: scripts/fidic_deadline.py
content: #!/usr/bin/env python3
"""
FIDIC Deadline Calculator — Seat-Aware

Computes contractual deadlines based on the seat country's public holidays.
Supports multiple day-counting modes:
  - calendar: Pure calendar days (FIDIC 2017 default — Sub-Clause 1.1.19)
  - exclude_ph: Calendar days excluding public holidays of the seat country
  - working: Excludes weekends AND public holidays (for contracts that define "working day")

Singapore is supported out of the box with gazette-verified holiday data.
For any other jurisdiction, supply your own holiday file with --holidays-file.

Usage:
    python3 fidic_deadline.py --seat SG --trigger 2026-05-15 --period 28
    python3 fidic_deadline.py --seat SG --trigger 2026-05-15 --period 28 --mode exclude_ph
    python3 fidic_deadline.py --seat AE --trigger 2026-03-18 --period 28 --mode exclude_ph --holidays-file my_ae_holidays.json
    python3 fidic_deadline.py --list-seats
"""

import argparse
import json
import os
import sys
from datetime import date, datetime, timedelta
from pathlib import Path

try:
    from version import VERSION
except ImportError:
    VERSION = "2.11.0"

HOLIDAYS_DIR = Path(__file__).resolve().parent.parent / "data" / "holidays"
SG_HOLIDAYS_JSON = Path(__file__).resolve().parent.parent / "data" / "sg_holidays.json"

VISIBLE_DISCLAIMER = "> \u26a0\ufe0f **Disclaimer:** This is a workflow aid, not legal advice. Verify the contract's definition of 'day', the seat country, and applicable holidays before reliance."

# Only Singapore is bundled and maintained
BUNDLED_SEATS = {'SG'}


def list_available_seats(holidays_file=None):
    """List available country holiday files (bundled + user-supplied)."""
    seats = []
    # Bundled SG
    if HOLIDAYS_DIR.exists():
        for f in sorted(HOLIDAYS_DIR.glob("*.json")):
            try:
                with open(f, 'r', encoding='utf-8') as fh:
                    data = json.load(fh)
                meta = data.get('_meta', {})
                seats.append({
                    'iso': meta.get('iso', f.stem),
                    'country': meta.get('country', f.stem),
                    'years': [k for k in data.keys() if k != '_meta'],
                    'notes': meta.get('notes', ''),
                    'bundled': True
                })
            except (json.JSONDecodeError, OSError):
                continue
    # User-supplied file
    if holidays_file:
        try:
            with open(holidays_file, 'r', encoding='utf-8') as fh:
                data = json.load(fh)
            meta = data.get('_meta', {})
            seats.append({
                'iso': meta.get('iso', Path(holidays_file).stem),
                'country': meta.get('country', Path(holidays_file).stem),
                'years': [k for k in data.keys() if k != '_meta'],
                'notes': meta.get('notes', '') + ' [user-supplied]',
                'bundled': False
            })
        except (json.JSONDecodeError, OSError):
            pass
    return seats


def load_holidays_from_file(filepath, year):
    """Load public holidays from a specific JSON file for a given year.

    Returns a set of date objects.
    Raises ValueError if year not found.
    """
    with open(filepath, 'r', encoding='utf-8') as f:
        data = json.load(f)

    year_str = str(year)
    if year_str not in data:
        available_years = [k for k in data.keys() if k != '_meta']
        raise ValueError(
            f"No holiday data for year {year} in {filepath}. "
            f"Available years: {', '.join(available_years)}."
        )

    year_data = data[year_str]
    # Support both flat list and structured {dates: [...]} format
    if isinstance(year_data, list):
        dates_list = year_data
    elif isinstance(year_data, dict) and 'dates' in year_data:
        dates_list = year_data['dates']
    else:
        raise ValueError(f"Invalid format for year {year} in {filepath}")

    return {datetime.strptime(d, "%Y-%m-%d").date() for d in dates_list}


def load_holidays(seat_iso, year, holidays_file=None):
    """Load public holidays for a given country and year.

    For SG: uses bundled gazette-verified data.
    For other seats: requires holidays_file to be supplied.

    Returns a set of date objects.
    Raises ValueError if country or year not found.
    """
    seat_iso = seat_iso.upper()

    if seat_iso in BUNDLED_SEATS:
        # Use bundled data
        holiday_file = HOLIDAYS_DIR / f"{seat_iso}.json"
        if not holiday_file.exists():
            # Fallback: SG can also be loaded from sg_holidays.json
            if seat_iso == "SG" and SG_HOLIDAYS_JSON.exists():
                holiday_file = SG_HOLIDAYS_JSON
            else:
                raise ValueError(
                    f"Bundled holiday data for '{seat_iso}' not found. "
                    f"Expected at: {HOLIDAYS_DIR / f'{seat_iso}.json'}"
                )
        return load_holidays_from_file(str(holiday_file), year)

    # Non-bundled seat: require user-supplied file
    if not holidays_file:
        raise ValueError(
            f"No bundled holiday data for seat '{seat_iso.lower()}'. "
            f"This tool only ships verified data for Singapore. "
            f"For other jurisdictions, supply your own holiday list with --holidays-file. "
            f"Format: see docs/holiday-file-format.md. "
            f"Source recommendation: your jurisdiction's official gazette or ministry of manpower equivalent."
        )

    return load_holidays_from_file(holidays_file, year)


def get_weekend_days(seat_iso, holidays_file=None):
    """Get weekend days for a country. Returns set of weekday numbers (0=Mon, 6=Sun)."""
    seat_iso = seat_iso.upper()

    # Try to read from the holiday file metadata
    filepath = None
    if seat_iso in BUNDLED_SEATS:
        candidate = HOLIDAYS_DIR / f"{seat_iso}.json"
        if candidate.exists():
            filepath = str(candidate)
    elif holidays_file:
        filepath = holidays_file

    if filepath:
        try:
            with open(filepath, 'r', encoding='utf-8') as f:
                data = json.load(f)
            meta = data.get('_meta', {})
            weekend = meta.get('weekend', ['Sat', 'Sun'])
        except (json.JSONDecodeError, OSError):
            weekend = ['Sat', 'Sun']
    else:
        weekend = ['Sat', 'Sun']

    day_map = {'Mon': 0, 'Tue': 1, 'Wed': 2, 'Thu': 3, 'Fri': 4, 'Sat': 5, 'Sun': 6}
    return {day_map[d] for d in weekend}


def get_in_lieu_holidays(seat_iso, holidays, year, mode='exclude_ph', holidays_file=None):
    """Derive in-lieu holidays based on country rules.

    In 'working' mode, weekends are already excluded, so a PH falling on a
    weekend day does NOT generate an in-lieu weekday — it's already skipped.
    In-lieu rules only apply in 'exclude_ph' mode where weekends count but PHs don't.

    Currently supports:
    - SG: Sunday PH -> Monday in-lieu (Holidays Act 1998 s.4(2)) — always applies
    - User-supplied files: reads in_lieu_rule from _meta and applies accordingly
    """
    seat_iso = seat_iso.upper()

    # Determine which file to read
    filepath = None
    if seat_iso in BUNDLED_SEATS:
        candidate = HOLIDAYS_DIR / f"{seat_iso}.json"
        if candidate.exists():
            filepath = str(candidate)
    elif holidays_file:
        filepath = holidays_file

    if not filepath:
        return set()

    try:
        with open(filepath, 'r', encoding='utf-8') as f:
            data = json.load(f)
    except (json.JSONDecodeError, OSError):
        return set()

    rule = data.get('_meta', {}).get('in_lieu_rule', 'none')
    weekend_days = get_weekend_days(seat_iso, holidays_file)
    in_lieu = set()

    if rule == 'auto_sunday_to_monday':
        # Singapore: Sunday PH -> Monday in-lieu (statutory, always applies)
        for h in holidays:
            if h.weekday() == 6:  # Sunday
                monday = h + timedelta(days=1)
                in_lieu.add(monday)

    elif rule in ('rest_day_replacement', 'substitute_next_working_day'):
        # PH on weekend -> next working day
        # Only applies in exclude_ph mode. In working mode, weekends are
        # already excluded so no replacement is needed.
        if mode == 'working':
            return set()
        for h in holidays:
            if h.weekday() in weekend_days:
                candidate = h + timedelta(days=1)
                while candidate.weekday() in weekend_days or candidate in holidays:
                    candidate += timedelta(days=1)
                in_lieu.add(candidate)

    return in_lieu


def compute_deadline(trigger_date, period, seat_iso, mode='calendar', holidays_file=None):
    """Compute a contractual deadline.

    Args:
        trigger_date: The date the clock starts (e.g. awareness of event)
        period: Number of days in the notice period
        seat_iso: ISO country code for the seat
        mode: 'calendar' | 'exclude_ph' | 'working'
        holidays_file: Path to user-supplied holiday JSON (required for non-SG seats)

    Returns:
        dict with deadline date, holidays skipped, and computation trace
    """
    seat_iso = seat_iso.upper()

    # Determine verification level
    if seat_iso in BUNDLED_SEATS:
        verification_note = 'Singapore holidays verified against MOM gazette (skill-maintained).'
    else:
        verification_note = f'User-supplied holiday data for {seat_iso}. Verification is your responsibility.'

    if mode == 'calendar':
        # Pure calendar days — FIDIC 2017 default
        deadline = trigger_date + timedelta(days=period)
        return {
            'trigger': trigger_date,
            'period': period,
            'mode': mode,
            'seat': seat_iso,
            'deadline': deadline,
            'holidays_skipped': [],
            'weekends_skipped': [],
            'verification': verification_note,
            'note': 'FIDIC 2017 Sub-Clause 1.1.19: "day" means calendar day. No holidays excluded unless Particular Conditions amend this.'
        }

    # For exclude_ph and working modes, we need holiday data
    # This will raise ValueError for non-SG seats without holidays_file
    # Collect holidays for all years the period might span
    years_needed = set()
    # Estimate: period + buffer for holidays/weekends
    estimate_end = trigger_date + timedelta(days=period * 2)
    for y in range(trigger_date.year, estimate_end.year + 1):
        years_needed.add(y)

    all_holidays = set()
    first_error = None
    loaded_any_year = False
    for y in years_needed:
        try:
            year_holidays = load_holidays(seat_iso, y, holidays_file)
            loaded_any_year = True
            all_holidays.update(year_holidays)
            # Add in-lieu days
            in_lieu = get_in_lieu_holidays(seat_iso, year_holidays, y, mode, holidays_file)
            all_holidays.update(in_lieu)
        except ValueError as e:
            if first_error is None:
                first_error = e
            # keep checking later years in case the first estimated year is missing but a later one exists
            continue

    if not loaded_any_year and first_error is not None:
        raise first_error

    weekend_days = get_weekend_days(seat_iso, holidays_file) if mode == 'working' else set()

    # Count days
    current = trigger_date
    days_counted = 0
    holidays_skipped = []
    weekends_skipped = []

    while days_counted < period:
        current += timedelta(days=1)

        if mode == 'working' and current.weekday() in weekend_days:
            weekends_skipped.append(current)
            continue

        if current in all_holidays:
            holidays_skipped.append(current)
            continue

        days_counted += 1

    return {
        'trigger': trigger_date,
        'period': period,
        'mode': mode,
        'seat': seat_iso,
        'deadline': current,
        'holidays_skipped': holidays_skipped,
        'weekends_skipped': weekends_skipped,
        'verification': verification_note,
        'note': f"{'Excludes PHs only' if mode == 'exclude_ph' else 'Excludes weekends + PHs'} for {seat_iso}. Verify contract definition of 'day'."
    }


def format_result(result, fmt='text'):
    """Format the deadline computation result."""
    if fmt == 'md':
        lines = [VISIBLE_DISCLAIMER, ""]
        lines.append("# Contractual Deadline Computation")
        lines.append("")
        lines.append("| Field | Value |")
        lines.append("|-------|-------|")
        lines.append(f"| Trigger date | {result['trigger'].strftime('%d %b %Y (%A)')} |")
        lines.append(f"| Period | {result['period']} days |")
        lines.append(f"| Mode | {result['mode']} |")
        lines.append(f"| Seat country | {result['seat']} |")
        lines.append(f"| **Deadline** | **{result['deadline'].strftime('%d %b %Y (%A)')}** |")
        lines.append(f"| Calendar days elapsed | {(result['deadline'] - result['trigger']).days} |")
        lines.append("")

        if result['holidays_skipped']:
            lines.append(f"### Public holidays skipped ({len(result['holidays_skipped'])})")
            for h in result['holidays_skipped']:
                lines.append(f"- {h.strftime('%d %b %Y (%A)')}")
            lines.append("")

        if result['weekends_skipped']:
            lines.append(f"### Weekends skipped ({len(result['weekends_skipped'])})")
            lines.append(f"- {len(result['weekends_skipped'])} weekend days excluded")
            lines.append("")

        lines.append(f"> **Note:** {result['note']}")
        lines.append("")
        if result.get('verification'):
            lines.append(f"> \U0001f6e1\ufe0f **Verification:** {result['verification']}")
            lines.append("")
        lines.append("> This is a workflow and analysis aid only. It does not constitute legal advice.")
        return "\n".join(lines)

    else:
        # Plain text
        lines = []
        lines.append("FIDIC Deadline Computation")
        lines.append("=" * 40)
        lines.append(f"Trigger:    {result['trigger'].strftime('%d %b %Y (%A)')}")
        lines.append(f"Period:     {result['period']} days ({result['mode']})")
        lines.append(f"Seat:       {result['seat']}")
        lines.append(f"Deadline:   {result['deadline'].strftime('%d %b %Y (%A)')}")
        lines.append(f"Calendar:   {(result['deadline'] - result['trigger']).days} calendar days elapsed")

        if result['holidays_skipped']:
            lines.append(f"\nHolidays skipped ({len(result['holidays_skipped'])}):")
            for h in result['holidays_skipped']:
                lines.append(f"  - {h.strftime('%d %b %Y (%A)')}")

        if result['weekends_skipped']:
            lines.append(f"\nWeekends skipped: {len(result['weekends_skipped'])} days")

        lines.append(f"\nNote: {result['note']}")
        if result.get('verification'):
            lines.append(f"Verification: {result['verification']}")
        lines.append("\nDisclaimer: This is a workflow aid, not legal advice.")
        return "\n".join(lines)


def main():
    parser = argparse.ArgumentParser(
        description="FIDIC Deadline Calculator \u2014 compute contractual deadlines based on seat country holidays",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Day-counting modes:
  calendar    Pure calendar days (FIDIC 2017 default \u2014 Sub-Clause 1.1.19)
  exclude_ph  Calendar days excluding public holidays of the seat country
  working     Excludes weekends AND public holidays (for contracts defining "working day")

Singapore is supported out of the box. For other jurisdictions, supply --holidays-file.

Examples:
  %(prog)s --seat SG --trigger 2026-05-15 --period 28
  %(prog)s --seat SG --trigger 2026-05-15 --period 28 --mode exclude_ph
  %(prog)s --seat AE --trigger 2026-03-18 --period 28 --mode exclude_ph --holidays-file ae_holidays.json
  %(prog)s --list-seats
"""
    )
    parser.add_argument("--seat", help="ISO country code for the seat (e.g. SG, AE, MY, GB)")
    parser.add_argument("--trigger", help="Trigger date (YYYY-MM-DD) \u2014 when the clock starts")
    parser.add_argument("--period", type=int, help="Number of days in the notice/deadline period")
    parser.add_argument("--mode", choices=['calendar', 'exclude_ph', 'working'], default='calendar',
                        help="Day-counting mode (default: calendar)")
    parser.add_argument("--holidays-file", help="Path to user-supplied holiday JSON file (required for non-SG seats in exclude_ph/working modes)")
    parser.add_argument("--format", choices=['text', 'md'], default='text',
                        help="Output format (default: text)")
    parser.add_argument("--output", help="Output file path (default: stdout)")
    parser.add_argument("--list-seats", action='store_true', help="List available seat countries")
    parser.add_argument("--version", action='version', version=f"fidic_deadline v{VERSION}")

    args = parser.parse_args()

    if args.list_seats:
        seats = list_available_seats(args.holidays_file)
        if not seats:
            print("No country holiday files found.")
            print(f"Bundled: SG (Singapore) in {HOLIDAYS_DIR}")
            print("For other jurisdictions, supply --holidays-file <path>")
            sys.exit(1)
        print("Available seat countries:")
        print(f"{'ISO':<6} {'Country':<35} {'Years':<20} {'Source':<12} Notes")
        print("-" * 100)
        for s in seats:
            years_str = ", ".join(s['years'][:5])
            source = "bundled" if s.get('bundled') else "user-file"
            notes_short = s['notes'][:40] + "..." if len(s['notes']) > 40 else s['notes']
            print(f"{s['iso']:<6} {s['country']:<35} {years_str:<20} {source:<12} {notes_short}")
        sys.exit(0)

    if not args.seat or not args.trigger or not args.period:
        parser.error("--seat, --trigger, and --period are required (or use --list-seats)")

    try:
        trigger = datetime.strptime(args.trigger, "%Y-%m-%d").date()
    except ValueError:
        parser.error(f"Invalid date format: {args.trigger}. Use YYYY-MM-DD.")

    try:
        result = compute_deadline(trigger, args.period, args.seat, args.mode, args.holidays_file)
    except ValueError as e:
        print(f"Error: {e}", file=sys.stderr)
        sys.exit(1)

    output = format_result(result, args.format)

    if args.output:
        with open(args.output, 'w', encoding='utf-8') as f:
            f.write(output)
        print(f"Written to {args.output}", file=sys.stderr)
    else:
        print(output)


if __name__ == "__main__":
    main()


path: scripts/version.py
content: """
Single source of truth for the construction-law skill version.
All scripts and generated outputs must import VERSION from here.
"""

VERSION = "2.11.5"

def footer(generator_name: str = "Construction Law Skill") -> str:
    """Standard footer for generated artefacts."""
    return f"*Generated by {generator_name} v{VERSION}*"


path: tests/__init__.py
content: # Construction Law Skill — Test Suite


path: tests/data/golden_deadlines.csv
content: # FIDIC Deadline Calculator — Golden Test Data
# Hand-verified scenarios for Singapore (bundled, gazette-verified).
#
# Modes:
#   calendar   = pure calendar days (FIDIC 2017 default)
#   exclude_ph = calendar days excluding public holidays
#   working    = excludes weekends AND public holidays
#
# Verification sources:
#   SG: eGazette No. 2258 (2026), MOM press release 16 Jun 2025
#
# Scenario descriptions:
#   1. SG calendar (FIDIC default) — no exclusions, pure 28 days
#   2. SG exclude_ph — Vesak/HRH cluster (May 27 HRH, May 31 Vesak Sun, Jun 1 in-lieu)
#   3. SG exclude_ph — CNY cluster (Feb 17-18)
#   4. SG exclude_ph — National Day cluster (Aug 9 Sun + Aug 10 in-lieu Mon)
seat,trigger_date,period,mode,expected_deadline,holidays_skipped_count,calendar_days_elapsed
SG,2026-05-25,28,calendar,2026-06-22,0,28
SG,2026-05-25,28,exclude_ph,2026-06-25,3,31
SG,2026-02-15,28,exclude_ph,2026-03-17,2,30
SG,2026-08-05,28,exclude_ph,2026-09-04,2,30


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)