Templates and checklists for battery energy storage system QA/QC, FAT/SAT readiness, supplier evidence review, and commissioning handover.
BESS reliability depends on evidence that can be inspected before energization, commissioning, and handover. This repository collects practical templates that help engineering teams make inspection logic easier to review and reuse.
- Toolkit contents is the lifecycle-organized template catalog.
- Template quality gate is the shortest local validation path.
- Readiness audits explain the executable review controls.
- Fictional worked example shows the existing readiness fields with executable audit inputs.
- Scope and limitations defines how to adapt the toolkit.
- Contributing, citation metadata, and license support sharing.
The catalogue follows a typical BESS delivery lifecycle. A template may be adapted for another gate when the project plan or contract assigns it there; the grouping below is a navigation aid, not a required sequence.
- Supplier document review tracker.
- Supplier query log.
- Document readiness scoring guide.
- Fire safety interface review.
- Grid interconnection evidence pack.
- Relay settings review checklist.
- FAT readiness checklist.
- Acceptance evidence wording guide.
- Instrument calibration traceability register.
- SAT readiness checklist.
- Site acceptance risk register.
- Site walkdown photo log.
- Communication interface test log.
- Metering acceptance checklist.
- Punch-list and nonconformance tracker.
- Commissioning evidence matrix.
- Commissioning evidence review examples.
- Commissioning hold-point checklist.
- Commissioning shift handover log.
- Emergency response drill record.
- Availability test evidence template.
- Environmental condition log.
- Handover document index.
- Cyber asset handover checklist.
- Residual-risk acceptance template.
- BESS closeout review checklist.
- BESS closeout owner map.
- BESS closeout timeline template.
- Spare parts readiness checklist.
- Warranty evidence checklist.
- O&M training record.
- Defect aging summary.
- Lessons learned capture template.
bess battery-energy-storage qaqc commissioning fat sat
renewable-energy utility-scale energy-storage
The lifecycle worked example is a small, fictional record that demonstrates the existing readiness fields across the lifecycle catalogue. It is illustrative only: its fabricated evidence IDs are not compliance evidence and must not be used to support a real energization or handover decision.
Run the same executable readiness gate used by the passing examples:
python scripts/audit_readiness.py examples/lifecycle-worked-example.md `
--status-policy config/readiness-status-policy.example.json `
--completeness-policy config/readiness-completeness-policy.example.json `
--as-of 2026-01-15 `
--require-source-coverageDraft toolkit. Use the templates as starting points and adapt them to project-specific requirements, standards, and contractual obligations.
The templates and audit scripts are project-neutral starting points. They do not replace the governing contract, applicable standards, authority requirements, manufacturer instructions, legal review, or a competent engineer's acceptance decision. Do not treat a passing example or a clean local audit as evidence that a real BESS project is safe, compliant, or ready for energization.
Every template must start with one title and an explanatory paragraph, then provide at least one structurally valid Markdown table. The repository workflow checks table separators and column counts in addition to testing links.
Run the same checks locally with Python 3.12:
python -m unittest discover -s tests -v
python scripts/validate_templates.pyAfter copying and filling project templates, aggregate Status, Review Status, and Approval Status columns into a reviewable Markdown report:
python scripts/summarize_status.py project-records `
--output project-records\readiness-summary.mdUse JSON for another reporting tool, or make a pipeline fail on one or more project-defined blocking states:
python scripts/summarize_status.py project-records --format json
python scripts/summarize_status.py project-records `
--fail-on Blocked --fail-on FailedThe gate compares status names case-insensitively and exits with code 2 when
a configured state occurs. Status-definition tables are excluded from the
roll-up. Running the command without a path summarizes the repository templates.
Use a version-controlled status policy to reject missing values, status typos, and project-defined blocking states in one reproducible gate:
python scripts/summarize_status.py project-records `
--policy config/readiness-status-policy.example.json `
--output project-records\readiness-summary.mdThe JSON policy defines global allowed_statuses, blocking_statuses, and the
Boolean require_status fallback. Optional column_rules can assign a complete
replacement rule to headings such as Approval Status or Review Status, so a
valid state cannot silently appear in the wrong workflow column. Column names
match case-insensitively after whitespace normalization.
Policy violations retain the source file, line, item, status, column, and reason
in Markdown and JSON output; the command exits with code 2 when any violation
is found. Copy and adapt the example policy
to the controlled vocabularies and release gates for each project. A matching
column rule replaces rather than merges with the global fallback, keeping each
column's accepted and blocking states explicit.
Audit dated owner actions separately from status vocabulary. Supply an explicit
--as-of date so the same project snapshot produces the same deadline states
in a local review and in CI:
python scripts/audit_deadlines.py project-records `
--as-of 2026-07-21 `
--output project-records\deadline-audit.mdThe report classifies each nonblank row as overdue, due_today, upcoming,
missing, or closed, and preserves its source file, line, item, status,
deadline heading, deadline value, and days to deadline. Use JSON for another
reporting tool, or fail a pipeline on selected states:
python scripts/audit_deadlines.py project-records `
--as-of 2026-07-21 --format json
python scripts/audit_deadlines.py project-records `
--as-of 2026-07-21 `
--fail-on overdue --fail-on missingBy default, the audit recognizes Due Date, Target Close Date, and Required By columns. Accepted, Approved, Closed, Complete, and Completed are
terminal statuses. TBD, TBC, N/A, NA, and - are controlled missing-date
markers; other nonblank dates must use YYYY-MM-DD.
Repeat --date-column, --terminal-status, or --missing-date-value to replace
the corresponding default list for a project. Matching is case-insensitive
after whitespace normalization. Tables with more than one recognized deadline
column and rows with malformed dates fail instead of choosing silently.
A valid status and deadline do not prove that a readiness row is controlled. Audit the fields required by each workflow state with a version-controlled JSON policy:
python scripts/audit_completeness.py project-records `
--policy config/readiness-completeness-policy.example.json `
--output project-records\completeness-audit.mdEach rule selects rows through one-of matching column names and
case-insensitive values, then requires one nonmissing value from every
configured field group. This supports heading variants such as Owner or
Action Owner, and Evidence Link or Closeout Evidence, without treating
them as different controls.
The example policy covers active closeout actions, accepted deferrals, and
approved handover documents. It requires the applicable owner, deadline,
approval, revision, and evidence fields while treating TBD, TBC, N/A,
NA, and - as controlled missing values. Copy and adapt the rule values and
column aliases for each project.
Reports preserve the source file, line, item, matched rule and state, required
field, candidate columns, observed values, and reason in Markdown or JSON. The
command exits with code 2 when violations exist and code 1 for malformed or
ambiguous policies, tables, or a policy that matches no rows. Generated reports
are excluded from later scans.
Cross-check commissioning rows against their controlled evidence register so a valid status cannot hide an unknown, orphaned, duplicated, or unapproved evidence record:
python scripts/audit_evidence_traceability.py project-records `
--output project-records\evidence-traceability-audit.mdThe check table requires a unique Check ID, the check or test, one or more
Evidence IDs, an acceptance reference, an owner, and a status. The evidence
register requires a unique Evidence ID, controlled location, revision, and
approval status. IDs use uppercase hyphenated values ending in digits, such as
CHK-001 and EVD-001; one evidence record may support multiple checks.
Ready for verification, Closed, and Accepted checks require every linked
evidence record to be Approved or Accepted. Repeat --completed-status or
--accepted-evidence-status to replace those defaults for a project. Repeat
--missing-value to replace the default TBD, TBC, N/A, NA, and -
placeholders. Matching is case-insensitive, while identifiers remain strict.
Markdown and JSON reports preserve source files, line numbers, check coverage,
register metadata, reverse references, and every finding. The command returns
0 for a clean audit, 2 for controlled findings, and 1 for malformed input
or missing check/register records. The
passing example is
exercised by the repository workflow.
Cross-check completed commissioning measurements against dated instrument calibration history so an evidence package cannot rely on a certificate that was expired, not yet effective, unapproved, or ambiguous on the test date:
python scripts/audit_calibration_traceability.py project-records `
--as-of 2026-07-21 `
--output project-records\calibration-traceability-audit.mdThe measurement-use table links a unique Measurement ID and Check ID to one
or more Instrument IDs, an ISO Test Date, owner, and status. The calibration
history retains one row per certificate period with a unique Calibration ID,
instrument, Valid From, Valid Through, approval status, and controlled
certificate location. Multiple nonoverlapping periods for one instrument are
supported so recalibration does not erase historical traceability.
Complete, Completed, Accepted, and Ready for verification measurements
require exactly one calibration period per instrument to cover the test date,
and that period must be Approved, Valid, or Accepted. Unknown instruments,
duplicate references and IDs, malformed or reversed dates, coverage gaps, and
overlapping periods are reported with source file and line number. Overlapping
certificate periods are flagged even when no completed measurement uses their
shared date range. Repeat
--completed-status, --accepted-calibration-status, or --missing-value to
replace the corresponding defaults for a project.
When --as-of is supplied, a completed measurement dated after the audit date
is also reported; planned work may still carry a future date.
Markdown and JSON reports preserve measurement coverage, complete calibration
history, reverse instrument references, and every finding. The command returns
0 for a clean audit, 2 for controlled findings, and 1 for malformed input
or a missing register. The
passing calibration example is
exercised by the repository workflow.
Gate a punch-list or nonconformance tracker before verification, deferral, or handover review:
python scripts/audit_punch_list.py project-records `
--as-of 2026-07-21 `
--output project-records\punch-list-closeout-audit.mdThe audit recognizes the tracker fields for unique ID, severity, finding,
system area, owner, evidence link, target close date, status, and verification
or closeout note. It enforces the documented Critical, Major, and Minor
severity vocabulary and the Open, In progress, Ready for verification,
Closed, and Deferred status lifecycle.
Active rows fail when their ISO target date is overdue. Critical rows must be terminal and cannot pass as deferred. Verification-ready, closed, and deferred rows require controlled evidence; terminal rows also require a closeout note. Malformed dates and identifiers, duplicate IDs, missing controlled values, and unknown severity or status values remain separate line-level findings.
Markdown and JSON reports preserve source files, row numbers, aggregate status
and severity counts, days to target, overdue state, and every issue. The command
returns 0 for a clean audit, 2 for controlled findings, and 1 for malformed
input or a missing tracker. The
passing punch-list example is
exercised by the repository workflow.
Audit the controlled revision history behind a handover package so an approved document cannot silently replace an earlier issue without a traceable supersession chain:
python scripts/audit_document_control.py project-records `
--as-of 2026-07-21 `
--output project-records\document-control-audit.mdThe register retains one row per document revision. Revisions use either
alphabetic (Rev A) or numeric (Rev 2) ordering consistently for each
document. Every later issue must name the immediately preceding revision in
Supersedes Revision, and its ISO issue date must increase. Historical rows
must be Superseded or Withdrawn; the latest row must be Approved,
Accepted, or Released and link to its controlled location.
Unknown statuses, duplicate document/revision pairs, inconsistent document
metadata, mixed revision schemes, future issue dates, and broken supersession
chains are reported with source file and line number. Repeat
--accepted-status, --working-status, --obsolete-status, or
--missing-value to replace the corresponding defaults. The command returns
0 for a clean audit, 2 for controlled findings, and 1 for malformed input
or a missing register. The
passing example is exercised in CI.
Cross-check punch-list items, residual-risk approvals, and the signed acceptance decision before releasing a BESS handover package:
python scripts/audit_handover_acceptance.py project-records `
--policy config/handover-acceptance-policy.example.json `
--output project-records\handover-acceptance-audit.mdThe audit requires each deferred punch-list item to resolve to exactly one
active, approved residual-risk record through Source Item ID. Closed items
must retain their evidence link and verification note. A conditional acceptance
must enumerate every active residual-risk ID, while an unconditional acceptance
cannot retain any active deferral.
The example policy treats open Critical and Major items as release blockers and does not permit Critical items to be deferred. Its controlled punch-list and risk statuses, release decisions, blocker severities, non-deferrable severities, and missing-value markers are all project-configurable. Policy lists are validated for duplicates, overlaps, and complete punch-status classification so a malformed gate fails instead of silently weakening the decision.
Markdown and JSON reports preserve source files, line numbers, all three
registers, aggregate counts, and each cross-register finding. The command
returns 0 for a clean release, 2 for controlled findings, and 1 for a
malformed policy, table, or incomplete register set. The
passing handover example is exercised
by the repository workflow.
Run all three controls as one reproducible release decision when a project snapshot is ready for review:
python scripts/audit_readiness.py project-records `
--status-policy config/readiness-status-policy.example.json `
--completeness-policy config/readiness-completeness-policy.example.json `
--as-of 2026-07-21 `
--output project-records\readiness-gate.mdThe combined Markdown or JSON report records each policy source, the explicit
as-of date, selected deadline failure states, source files, per-check result,
counts, line-level findings, and a matrix showing which source files contributed
to each control. It returns 0 only when status policy, deadlines, and
conditional completeness all pass; controlled findings return 2, while
malformed inputs or a check with no evaluable rows return 1.
Source coverage is report-only by default because a mixed project folder may intentionally contain specialized records. When every contributing file is expected to expose status, deadline, and conditional-completeness rows, enforce that contract explicitly:
python scripts/audit_readiness.py project-records `
--status-policy config/readiness-status-policy.example.json `
--completeness-policy config/readiness-completeness-policy.example.json `
--as-of 2026-07-21 `
--require-source-coverage `
--format jsonStrict coverage creates one finding for every missing source/control pair and
returns 2. Generated audit reports are excluded from the matrix, so writing a
report inside the scanned directory remains safe for repeat runs.
By default, overdue and missing deadlines fail the combined gate. Repeat
--deadline-fail-on to replace that pair for a project, for example:
python scripts/audit_readiness.py project-records `
--status-policy config/readiness-status-policy.example.json `
--completeness-policy config/readiness-completeness-policy.example.json `
--as-of 2026-07-21 `
--deadline-fail-on overdue --deadline-fail-on due_today `
--format jsonThe passing example is exercised in strict coverage mode by the repository workflow and shows the minimum owner, deadline, and evidence fields needed by the example policies. Combined reports can be written inside the scanned directory without being ingested on the next run.
- Add project-specific evidence-traceability examples.
- Add project-specific calibration-history and measurement-use examples.
- Add project-specific handover acceptance policies and records.
- Improve punch-list and nonconformance closeout wording.
- Improve handover document index fields.
- Add project-specific examples to the acceptance evidence wording guide.
- Add project-specific residual-risk acceptance examples.
- Add project-specific closeout review checks.
- Add project-specific commissioning hold points.
- Add more accepted/rejected commissioning evidence examples.
- Add project-specific document readiness scoring examples.
- Add project-specific closeout owner map examples.
- Add project-specific examples to the bess closeout timeline template.
- Add project-specific examples to the commissioning shift handover log.
- Add project-specific examples to the warranty evidence checklist.
- Add project-specific examples to the fire safety interface review.
- Add project-specific examples to the spare parts readiness checklist.
- Add project-specific examples to the site acceptance risk register.
- Add project-specific examples to the grid interconnection evidence pack.
- Add project-specific examples to the energization readiness gate.
- Add project-specific examples to the o and m training record.
- Add project-specific examples to the defect aging summary.
- Add project-specific examples to the supplier query log.
- Add project-specific examples to the cyber asset handover checklist.
- Add project-specific examples to the metering acceptance checklist.
- Add project-specific examples to the communication interface test log.
- Add project-specific examples to the emergency response drill record.
- Add project-specific examples to the availability test evidence template.
- Add project-specific examples to the environmental condition log.
- Add project-specific examples to the relay settings review checklist.
- Add project-specific examples to the site walkdown photo log.
- Add project-specific examples to the final acceptance signoff pack.
- Add project-specific examples to the lessons learned capture template.
If this toolkit supports research, teaching, or a project review, cite the machine-readable CITATION.cff metadata and identify the adapted templates, policies, and project context used.
Released under the MIT License.