Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@../AGENTS.md
5 changes: 5 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# BuildingSync Schema - Copilot Instructions

All repository rules for AI agents live in [AGENTS.md](../AGENTS.md). Read and follow it before making changes.

File-scoped rules in [.github/instructions/](instructions/) apply automatically to `BuildingSync.xsd` and `proposals/**/*.md`.
15 changes: 15 additions & 0 deletions .github/instructions/proposals.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
applyTo: "proposals/**/*.md"
description: "Format and process for BuildingSync feature proposals"
---

# Writing a proposal

Follow [proposals/README.md](../../proposals/README.md).

- Location: `proposals/<year of submission>/<Title Case Name>.md` (e.g. `proposals/2026/Add Field-assembled DX system to DXSystemType.md`).
- Required sections, in order: `## Overview` (brief summary), `## Justification` (evidence the change is needed and beneficial), `## Implementation` (exact XSD changes: element paths, types, enumerations, documentation text). Optional: `## References`.
- State whether the change is breaking or non-breaking per [docs/versioning.md](../../docs/versioning.md); breaking proposals must discuss severity of the breakage and the migration path.
- Reference the GitHub issue it addresses.
- Proposal PRs are discussed and accepted/rejected before (or alongside) the implementation PR; the project lead decides if no consensus.
- Markdown is formatted by prettier via `poetry run pre-commit run --all-files`.
47 changes: 47 additions & 0 deletions .github/instructions/schema-xsd.instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
applyTo: "BuildingSync.xsd"
description: "Conventions for editing the BuildingSync XSD"
---

# Editing BuildingSync.xsd

Read the surrounding region first and keep edits minimal; do not reformat unrelated content. Classify the change (breaking / non-breaking / patch, per [docs/versioning.md](../../docs/versioning.md)) before editing.

## Structure

- Indent with 2 spaces, never tabs; no XMLSpy comments (run `bundle exec rake remove_tabs` after editing).
- Never use `xs:complexContent` (test-enforced); compose with named types, `xs:sequence`, and `ref`.
- New elements are optional (`minOccurs="0"`) unless a breaking change is intended and approved.
- Inserting a new optional element into an `xs:sequence` is fine; moving or reordering existing elements is breaking.
- `xs:element` names must be unique across the schema. To reuse a structure, define a named `xs:complexType`/`xs:simpleType` (suffix `Type`) or a global element used via `ref="auc:..."`.
- Global names must not collide with gbXML global names.
- Do not modify the header (`version` attribute, title documentation, root `version` enumeration) outside a release; see [docs/release_instructions.md](../../docs/release_instructions.md).

## Documentation

- Every new element, type, and enumeration-bearing element gets `<xs:annotation><xs:documentation>`.
- Write a clear definition sentence; put units in parentheses at the end, e.g. `... gross floor area. (ft2)`, `(kBtu/ft2)`, `($)`, `(cfm)`, `(W/ft2)`.
- Documentation-only changes are patch-level.

## Enumerations

- Adding a value is non-breaking; removing or renaming one is breaking (deprecate instead).
- Follow the existing wording/casing style of sibling values; include `Other` and `Unknown` where siblings do.

## Common patterns

- Identity: `<xs:attribute name="ID" type="xs:ID" use="required"/>`.
- Links: element with `<xs:attribute name="IDref" type="xs:IDREF" use="required"/>`; document the valid target in [docs/linking_elements.md](../../docs/linking_elements.md).
- Data provenance: `<xs:attribute ref="auc:Source"/>`; system state: `ref="auc:Status"`.
- Extensibility: `<xs:element ref="auc:UserDefinedFields" minOccurs="0"/>`.
- gbXML content uses the `gbxml` prefix (see [docs/gbXML_reference.md](../../docs/gbXML_reference.md)).

## Deprecation

- Never remove elements outside a major version (XSD header Rule #1).
- Mark deprecated items in documentation: `WARNING: This element is being deprecated, use <Replacement> instead.` (for enum values: `WARNING: This enumeration is being deprecated, use ... instead`).
- Update examples to use the replacement.

## Verify

`bundle exec rake` and `bundle exec rake generate_data_dictionary` must pass.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,4 @@ gbxml.xsd
*.bak
*.backup
*.tmp
/tmp
75 changes: 75 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# BuildingSync Schema - AI Agent Instructions

This is the canonical instruction file for AI coding agents (Copilot, Claude Code, Codex, Cursor, etc.). `.claude/CLAUDE.md` and `.github/copilot-instructions.md` point here.

BuildingSync is an XML schema (`BuildingSync.xsd`, namespace prefix `auc`) for exchanging building energy audit and building characteristics data. Every change must keep historical documents and downstream tools (Audit Template, Use Case Validator, BuildingSync-gem, bsyncpy, website schema viewer) working unless a major version bump is intended.

## Repository layout

| Path | Purpose |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `BuildingSync.xsd` | The schema (single file). Imports gbXML v6.01 via URL. |
| `examples/*.xml` | Example instances. All must validate (except files named `*Invalid Schema*`). |
| `proposals/<YEAR>/*.md` | Feature proposals (see [proposals/README.md](proposals/README.md)). |
| `docs/` | Versioning, release, linking (ID/IDREF), gbXML, developer docs; Jupyter notebooks in `docs/notebooks`. |
| `migration_scripts/` | `upgrade_from_X_to_Y.py` scripts for breaking upgrades between adjacent versions. |
| `spec/validation_spec.rb` | RSpec checks run by `bundle exec rake`. |
| `src/data_dictionary.rb`, `src/change_log.rb` | Data dictionary and changelog generators. |
| `.github/instructions/` | File-scoped rules; read before editing matching files (see below). |
| `tmp/` | Git-ignored scratch space. Never commit it. |

## File-scoped rules (read before editing)

- `BuildingSync.xsd`: [.github/instructions/schema-xsd.instructions.md](.github/instructions/schema-xsd.instructions.md)
- `proposals/**/*.md`: [.github/instructions/proposals.instructions.md](.github/instructions/proposals.instructions.md)

## Commands

- Tests (CI): `bundle exec rake` then `bundle exec rake generate_data_dictionary` (the latter also detects name conflicts).
- Format XSD/examples (removes tabs and XMLSpy comments, 2-space indent): `bundle exec rake remove_tabs`.
- Lint/format everything else: `poetry run pre-commit run --all-files` (prettier for Markdown/YAML/JSON, ruff for Python with line length 140, trailing whitespace, end-of-file newline, JSON pretty-format).
- Bulk documentation edits: `bundle exec rake generate_documentation_csv`, edit `updated_documentation` column, then `bundle exec rake update_documentation`.
- On Windows, `C:\Ruby32-x64\bin\ruby.exe -S bundle exec rake` is more reliable than bare `bundle`.

## Rules enforced by tests (`spec/validation_spec.rb`)

1. Every `examples/*.xml` (except `*Invalid Schema*`) validates against `BuildingSync.xsd`.
2. No tab characters in `BuildingSync.xsd` or `examples/*.xml`.
3. No `XMLSpy` text in `BuildingSync.xsd` or `examples/*.xml`.
4. No `xs:complexContent` anywhere in `BuildingSync.xsd`.
5. Global `xs:element`/`xs:complexType`/`xs:simpleType`/`xs:attribute` names must not collide with gbXML global names (only `Capacity Latitude Location Longitude Manufacturer State ZipCode` are permitted).
6. Named `xs:element` names must be unique across the whole schema, except the legacy `ignored_dupes` list. Never add to that list; reuse a shared type or `ref` instead.

## Versioning and change classification ([docs/versioning.md](docs/versioning.md))

Classify every schema change before making it and report the classification:

- **Breaking (MAJOR)**: any historical document could stop validating - adding a required element/attribute, moving/renaming an element (including order in a sequence or new parent), changing to an incompatible type (e.g. decimal to integer), narrowing a simple-type restriction (removing an enum, tighter bounds).
- **Non-breaking (MINOR)**: new optional element/attribute, compatible type widening (e.g. decimal to string), new enum value.
- **Patch**: documentation-only changes, or restructuring that does not change what validates (e.g. inline definition to named type or `ref`).

Deprecation policy (in the XSD header): **"Schema elements may only be removed by incrementing the major version of the schema document."** In a minor/patch release, deprecate instead of removing or renaming. Breaking changes need a migration script in `migration_scripts/` (see [upgrade_from_2.4_to_2.5.py](migration_scripts/upgrade_from_2.4_to_2.5.py)) that updates the root `version` and inserts a generated-from comment.

## Workflow for a schema change

1. Non-trivial features start with a proposal in `proposals/<current year>/<Title Case Name>.md` containing at least **Overview**, **Justification**, **Implementation** (breaking changes must discuss severity); optional **References**.
2. Edit `BuildingSync.xsd` following [.github/instructions/schema-xsd.instructions.md](.github/instructions/schema-xsd.instructions.md).
3. Update or add `examples/*.xml` when the change affects them; keep examples free of deprecated elements where possible.
4. If a linking (`IDref`) element is added, update [docs/linking_elements.md](docs/linking_elements.md).
5. Run `bundle exec rake remove_tabs`, `bundle exec rake`, `bundle exec rake generate_data_dictionary`, and pre-commit.
6. Do **not** edit `CHANGELOG.md` or schema version numbers in feature PRs; the changelog is generated from PR labels at release time ([docs/release_instructions.md](docs/release_instructions.md)).

## Pull requests ([docs/developer_resources.md](docs/developer_resources.md), `.github/workflows/CI_Labels.yml`)

- One logical/discrete change per PR (e.g. removing an element is separate from adding an unrelated enum).
- Use [.github/PULL_REQUEST_TEMPLATE.md](.github/PULL_REQUEST_TEMPLATE.md): background, what it does, how to test, relevant tickets, screenshots.
- Labels (CI-enforced on `develop-v2`/`develop-v3`): either exactly one of `Breaking Change` / `Non-breaking Change` **plus** a `Schema: ...` scope label (`Controls`, `Documentation`, `General`, `Measures`, `Reports`, `Systems`, `Validation`), or `No Schema Changes` alone, or `ignore` alone (release/procedural PRs).
- Contributions align with the release schedule: two releases per year (about end of May and November), cutoff about two weeks before ([.github/CONTRIBUTING.md](.github/CONTRIBUTING.md)).

## Agent behavior

- Read the relevant XSD region before editing; cite line numbers; never reformat unrelated parts of the 17k-line XSD.
- Prefer additive, non-breaking changes; flag anything breaking and ask before proceeding.
- Do not push, tag, release, or comment on GitHub issues/PRs without explicit approval.
- Do not add files to the repo root or create summary markdown files unless asked; use `tmp/` for scratch notes.
- Keep this file the single source of truth; update it (not the pointer files) when rules change.
6 changes: 3 additions & 3 deletions BuildingSync.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@
<xs:documentation>Details about the the assessment. This might include methods used, criteria, evidence, or basis of evaluation.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="Tightness" type="auc:Tightness" minOccurs="0">
<xs:element name="Tightness" type="auc:TightnessType" minOccurs="0">
<xs:annotation>
<xs:documentation>Description of the infiltration characteristics for an opaque surface, fenestration unit, a thermal zone.</xs:documentation>
</xs:annotation>
Expand Down Expand Up @@ -10677,7 +10677,7 @@
<xs:documentation>True if fenestration is weatherstripped, false otherwise.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="TightnessFitCondition" type="auc:Tightness" minOccurs="0">
<xs:element name="TightnessFitCondition" type="auc:TightnessType" minOccurs="0">
<xs:annotation>
<xs:documentation>Indicator of expected air leakage through fenestration.</xs:documentation>
</xs:annotation>
Expand Down Expand Up @@ -15598,7 +15598,7 @@
<xs:enumeration value="Unknown"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Tightness">
<xs:simpleType name="TightnessType">
<xs:restriction base="xs:string">
<xs:enumeration value="Very Tight"/>
<xs:enumeration value="Tight"/>
Expand Down
Loading
Loading