Skip to content
Merged
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
20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Bug
description: A crash, an error on a file that should read, or anything else that does not work.
labels: ["bug"]
body:
- type: textarea
id: what
attributes:
label: What happened
description: The command, its output, and what you expected.
validations:
required: true
- type: textarea
id: file
attributes:
label: The input
description: A synthetic file or scene that reproduces it (never a file you are not free to share).
- type: input
id: version
attributes:
label: luxpath version or commit
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Security vulnerability
url: https://github.com/Erry91/luxpath/security/advisories/new
about: Report a vulnerability privately (crafted files that crash, hang or exploit luxpath).
29 changes: 29 additions & 0 deletions .github/ISSUE_TEMPLATE/wrong-result.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Wrong result
description: luxpath computed a value or a verdict you believe is wrong. These are treated as the most serious bugs.
labels: ["wrong-result"]
body:
- type: markdown
attributes:
value: |
Please do not attach manufacturers' photometric files or real building plans unless you are free to share
them. A synthetic scene or file that shows the problem is ideal.
- type: textarea
id: what
attributes:
label: What luxpath reported, and what you expected
description: The values (lux, ratios, verdicts) and, if you compared with another tool, which one and its version.
validations:
required: true
- type: textarea
id: input
attributes:
label: How to reproduce
description: The scene (TOML) and the command; or a description of the luminaire and the geometry.
render: toml
validations:
required: true
- type: input
id: version
attributes:
label: luxpath version or commit
description: "`luxpath --version`, or the commit you built"
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,10 @@ jobs:
targets: wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- run: cargo xtask ci

licences:
name: licences and advisories (cargo deny)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ iterating: `cargo test -p luxpath-calc`.
## Commits and PRs
`main` is the integration branch. Branch as `<type>/<slug>` (`feat/`, `fix/`, `docs/`, `chore/`, `refactor/`), one
task id per commit (e.g. `M1.2: EULUMDAT reader`), commit only green states, open a PR using
`.github/pull_request_template.md`, merge when CI is green.
`.github/pull_request_template.md`, merge when CI is green. `cargo deny check` for dependency changes.

## Running
- `cargo run -p luxpath-cli -- --help`
Expand Down
34 changes: 34 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Contributing to luxpath

Thank you for helping. luxpath computes emergency lighting, a life-safety subject, so a few rules come before
everything else. They are in [AGENTS.md](AGENTS.md) (they bind people and AI agents alike); the short version:

- **Never commit a standard's text, tables or figures** (EN 1838, EN 50172, IES, CIE…). Requirement values may be
encoded with their clause and edition, in our own words (`docs/standards-parity.md`).
- **Clean-room with respect to other lighting software.** Compare results with DIALux, Relux and others on your own
synthetic scenes; never decompile them, and never copy their luminaire databases, artwork or sample projects.
- **No GPL or AGPL code**, not even as a dependency (`cargo deny check` enforces the licences).
- **Never commit manufacturers' photometric files or real building plans.** Test fixtures are synthetic and listed
with their source in a `README.md` next to them.
- **A wrong "pass" is the worst bug.** Missing or ambiguous data gives "cannot verify". Requirement checks are
tested on both sides of every threshold.
- **Never panic on input.** No `unwrap`, indexing or unchecked arithmetic on anything read from a file.

## Where help is most useful

- Photometric files that luxpath reads wrongly or refuses (gaps 12 and 15 in `docs/gaps.md`): a description, or a
synthetic file reproducing the quirk.
- Comparing luxpath's results with DIALux evo or Relux on synthetic scenes (milestone M6, `docs/roadmap.md`).
- National editions and rules around EN 1838 (`docs/standards-parity.md`).
- The work list: `docs/gaps.md`, top rows first.

## How to work

1. Read `docs/status.md`, `docs/gaps.md` and `docs/architecture.md`; `CLAUDE.md` describes the day-to-day workflow.
2. Branch as `<type>/<slug>` (`feat/`, `fix/`, `docs/`, `chore/`, `refactor/`).
3. Run `cargo xtask ci` (format, clippy, tests, the performance budget, the WASM build, layers, the feature
checklist) and, for licence changes, `cargo deny check`.
4. Open a pull request with the template; record what changed in `parity/features.toml`, `docs/status.md`,
`docs/gaps.md` and the `ROADMAP.md` log.

By contributing, you agree that your contributions are licensed under the project's licence, MIT OR Apache-2.0.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
repository = "https://github.com/Erry91/luxpath"
# Nothing is published to crates.io until the owner decides (docs/publishing.md).
publish = false

[workspace.dependencies]
# internal (layer order: see docs/architecture.md and `cargo xtask layers`)
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ cargo xtask parity # feature progress by milestone
| [docs/gaps.md](docs/gaps.md) | Every known shortfall, ranked: the work list |
| [docs/status.md](docs/status.md) | Where work stands right now, blockers, open questions |
| [docs/architecture.md](docs/architecture.md) | Crates, layers, data flow, design decisions |
| [docs/scene-format.md](docs/scene-format.md) | The scene file format that `luxpath check` reads |
| [docs/standards-parity.md](docs/standards-parity.md) | EN 1838:2024 requirements and their implementation status |
| [docs/research.md](docs/research.md) | Market and standards research behind the project |
| [parity/features.toml](parity/features.toml) | Machine-readable feature checklist (`cargo xtask parity`) |
| [CONTRIBUTING.md](CONTRIBUTING.md) / [SECURITY.md](SECURITY.md) | How to help, and how to report wrong results and vulnerabilities |
| [AGENTS.md](AGENTS.md) / [CLAUDE.md](CLAUDE.md) | Rules and working instructions for contributors and agents |

## Disclaimer
Expand Down
1 change: 1 addition & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ luxpath's one-page summary. Details live in:

| Date | Change |
|---|---|
| 2026-10-21 | Publishing prepared (docs/publishing.md): history scanned clean, `cargo deny` with a CI job, SECURITY.md, CONTRIBUTING.md, issue templates (wrong result, bug), `publish = false` until a crates.io decision. |
| 2026-10-21 | M3: scene format version 1 (docs/scene-format.md: photometry with emergency output, luminaires, routes, open and high-risk areas, points of emphasis; unknown fields refused, errors with line and column); `luxpath check` with exit codes 0/1/2/3, results per element with their assumptions, "cannot verify" when an emergency output is missing; three example scenes with synthetic photometry. |
| 2026-10-21 | M2: luminaires with heading and tilt (IES tilt factors applied), illuminance on any surface, area and full-width route grids summed over luminaires, statistics that are unverifiable when any point is; isotropic and Lambertian cases within 1e-6; 100 luminaires × 10,000 points in about 55 ms (release, in `cargo xtask ci`); photometry plausibility warnings. |
| 2026-10-21 | M1: IES LM-63 (1986–2019) and EULUMDAT readers, symmetry expansion, tilt data, emergency flux, located errors, property tests, a 10-minute fuzz run (22.8 million inputs) without a panic; `luxpath photometry`. Existing crates evaluated first: none usable (docs/architecture.md). |
Expand Down
25 changes: 25 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Security and safety reports

luxpath reads untrusted files (photometric files, scenes, IFC models) and computes values used in life-safety
design. Two kinds of report matter most:

1. **A wrong result that could make a design look safe when it is not**, for example illuminance computed too
high, a requirement reported as met that is not, or missing data treated as present. These are the most serious
bugs this project can have (AGENTS.md §2).
2. **A crash, hang or excessive memory use on some input file.** Every input must give a result or an error
(AGENTS.md §3).

## How to report

- For anything that could be exploited (a crafted file that runs code, reads files, or exhausts a machine), use
GitHub's **private vulnerability reporting** (Security tab, "Report a vulnerability"). Please do not open a
public issue for these.
- For wrong results and crashes on ordinary files, open an issue with the **wrong result** or **bug** template.
Do not attach manufacturers' photometric files or real building plans unless you are free to share them;
a description or a synthetic file that reproduces the problem is enough.

We aim to acknowledge reports within a week. There is no bug bounty.

## Supported versions

luxpath is pre-alpha: only the latest `main` is supported, and nothing is yet released.
1 change: 1 addition & 0 deletions apps/luxpath-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[[bin]]
name = "luxpath"
Expand Down
1 change: 1 addition & 0 deletions crates/calc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[dependencies]
luxpath-geom.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/geom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[lints]
workspace = true
1 change: 1 addition & 0 deletions crates/ifc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[dependencies]
ifc-lite-core.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/photometry/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[dependencies]
luxpath-geom.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/report/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[dependencies]
luxpath-scene.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/rules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[dependencies]
luxpath-scene.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/scene/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ edition.workspace = true
license.workspace = true
rust-version.workspace = true
repository.workspace = true
publish.workspace = true

[dependencies]
luxpath-geom.workspace = true
Expand Down
20 changes: 20 additions & 0 deletions deny.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# `cargo deny check`: licences, advisories and sources (AGENTS.md §1.2: no GPL/AGPL). CI runs it; locally:
# cargo install cargo-deny.

[graph]
targets = ["x86_64-unknown-linux-gnu", "aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-pc-windows-msvc", "wasm32-unknown-unknown"]

[licenses]
# Permissive licences only; MPL-2.0 as an unmodified dependency (ifc-lite-core).
allow = ["MIT", "Apache-2.0", "Apache-2.0 WITH LLVM-exception", "BSD-2-Clause", "BSD-3-Clause", "ISC", "Zlib", "Unicode-3.0", "MPL-2.0", "CC0-1.0", "BSL-1.0"]
confidence-threshold = 0.9

[advisories]
yanked = "deny"

[bans]
multiple-versions = "allow"

[sources]
unknown-registry = "deny"
unknown-git = "deny"
50 changes: 50 additions & 0 deletions docs/publishing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Publishing checklist

> **Last updated:** 2026-10-21 · **Change:** prepared after M3

What has to be true before the repository goes public, and the switches the owner flips. Decision recorded
2026-10-21: go public after M3, as a clearly labelled pre-alpha.

## Done in the repository

| Item | State | Where |
|---|---|---|
| History scanned: no secrets, keys, tokens, local paths or private notes | clean (2026-10-21) | every commit before this checklist; only synthetic photometry in history |
| No manufacturers' photometric files, real plans, standard texts or IFC samples committed | clean | `plan/` is git-ignored; fixtures listed in their `README.md`s |
| Licence files and `license` metadata | MIT OR Apache-2.0 | `LICENSE-MIT`, `LICENSE-APACHE`, `Cargo.toml` |
| Dependency licences and advisories checked | `cargo deny check` passes | `deny.toml`; a CI job |
| README states the stage and that nothing is validated yet | done | `README.md` |
| Every report says it is a calculation, not a certificate | done | `luxpath-report` |
| How to report vulnerabilities and wrong results | done | `SECURITY.md` |
| How to contribute, with the provenance and safety rules | done | `CONTRIBUTING.md`, `AGENTS.md` |
| Issue templates (wrong result, bug) and the PR template | done | `.github/` |
| Accidental `cargo publish` blocked | `publish = false` in every crate | `Cargo.toml` |
| Hosted CI ready (gates on Linux, macOS, Windows; cargo deny) | ready, unused while private | `.github/workflows/ci.yml` |

## The owner's switches, in order

1. **Read the history once more yourself:** `git log -p` (eight commits). Commit authorship shows
`enrico.sita@gmail.com`; it is already public on your other open-source contributions. To use GitHub's
no-reply address for future commits instead, set it in the repository's git config before the next commit
(history keeps the old address unless rewritten, which is not worth it).
2. **Make the repository public:** Settings → General → Danger Zone → Change visibility.
3. **Turn on private vulnerability reporting:** Settings → Code security → Private vulnerability reporting
(`SECURITY.md` points to it).
4. **Protect `main`:** Settings → Branches → require a pull request and the CI checks (`gates (ubuntu-latest)`,
`gates (macos-latest)`, `gates (windows-latest)`, `licences and advisories`). Public repositories get Actions
minutes free, so hosted CI resumes; the first run tells us whether Windows needs fixes.
5. **Description and topics:** "Open, scriptable emergency-lighting calculations (EN 1838) in Rust"; topics such
as `lighting`, `emergency-lighting`, `en1838`, `photometry`, `ies`, `eulumdat`, `rust`, `bim`.
6. **Code of conduct (optional):** Insights → Community → Code of conduct → Contributor Covenant, generated by
GitHub in one click.
7. **Discussions (optional):** useful for practitioners who want to ask rather than file issues.

## Decisions for later

- **crates.io:** the `luxpath` name was free on 2026-10-16. Reserving it means publishing a version (a placeholder
or the current pre-alpha library); then `publish = false` comes off the crates to publish. Publishing a
life-safety library before M4 and M6 invites use before validation, so the suggestion is to wait for alpha and
watch the name meanwhile.
- **Announcement:** wait for alpha (M4 checks and M6 validation). Before it, share the repository directly with
people who can help: designers with DIALux or Relux licences for M6, people with real photometric files.
- **Ashlar's plugin (R2.9)** builds on the public library from then on.
2 changes: 1 addition & 1 deletion docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ FireExit flags. Luminaires collapse into few types (410 → 5), so a photometry
- **B. IFC scene:** read luminaire positions and space outlines (geometry) and define the mapping file
(type name or product code → photometric file, emergency yes/no).
- **C. Obstruction** (gap 16): walls in the scene block light; an alpha blocker before M4's checks.
- **E. Going public:** the publishing checklist (`docs/publishing.md`).
- **E. Going public:** the repository side is ready; the owner's switches are in `docs/publishing.md`.
- **D. Real files:** photometric files of luminaires the owner's practice uses, privately in `plan/` (gap 12).

## Blockers
Expand Down
Loading