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
23 changes: 23 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ jobs:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- uses: astral-sh/setup-uv@v5
with:
python-version: ${{ matrix.python-version }}
Expand All @@ -27,3 +30,23 @@ jobs:
run: uv run mypy
- name: Test
run: uv run pytest -q

html:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
- run: npm ci
- name: Calculation, optimizer and session regressions
run: npm test
- run: npx playwright install --with-deps chromium
- name: Browser workflows, mobile layouts and print
run: npm run test:browser
- uses: actions/upload-artifact@v4
if: always()
with:
name: browser-results
path: test-results/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ env/
.ruff_cache/
.coverage
htmlcov/
node_modules/
test-results/
playwright-report/

# Editor / OS
.vscode/
Expand Down
38 changes: 38 additions & 0 deletions ASSESSMENT_STATES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Assessment states

The HTML tool uses the same intake state on screen, in the site roll-up, and
in print. A sizing PASS covers only the checks this tool calculates.

| State | When it applies | Presentation |
| --- | --- | --- |
| Invalid | A required input is malformed, out of range, or incompatible with its context | CHECK INPUTS; field errors; no calculated verdict |
| Fail | Valid inputs produce at least one failed sizing or installation check | SIZING FAIL; failed checks remain visible |
| Needs review | Calculations are valid but required velocity evidence is missing | NEEDS REVIEW; explain the missing evidence |
| Unassessed | Calculations are valid but the user has not confirmed the inputs for this intake | UNASSESSED; identify prefilled values as an example |
| Pass | All calculated checks pass, required evidence is recorded, and inputs are confirmed | SIZING PASS |

The site takes the first applicable state in the order above across all intakes.
An empty site is unassessed. Invalid intakes are excluded from totals and this
exclusion is stated. Calculated totals for unassessed intakes remain illustrative.
Editing assessment inputs or site environment/species clears confirmation.
Changing display units or converting a flow value between units does not.

Elevated sweeping credit is invalid for a still waterbody. In flowing or tidal
water it needs baseline confirmation. SPOT input needs a governing species and
a recorded source/basis. Above 0.12 m/s it additionally needs an explicit QEP
review confirmation. This is a review policy, not a new regulatory velocity cap:
DFO §3.1.1 and Table C-1 specify the 0.12 ceiling for sweeping credit, while
species-specific design uses SPOT. Verified against the
[DFO standard](https://www.dfo-mpo.gc.ca/pnw-ppe/standards-normes/fish-screen-grillage-poisson-eng.html)
on 2026-09-18.

Optimization uses the intake validator and evaluates every proposed design with
the complete calculation/check path. Candidates must pass all checks and have
the required velocity evidence. Recommendations list changes and preserve every
dimension except the selected free dimension. Applying a candidate clears input
confirmation; the user reviews the resulting design before a sizing PASS.

Saved files are validated into temporary state before any live state changes.
Older files without confirmation or checklist fields load as unassessed with
an empty checklist. Invalid numeric drafts can be saved and restored for
correction; malformed structure, enums, and product references reject the file.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,25 @@ intakes, product library, display units), intakes can be imported from CSV (same
columns as `fish-screen --batch`), and an imperial display toggle adds cfs / ft² /
ft/s / in equivalents alongside the SI values.

New intakes start **unassessed**. Review the inputs and confirm them for the
site before the tool can report **SIZING PASS**. Invalid inputs suppress the
verdict; missing velocity evidence produces **NEEDS REVIEW**. The assessment
states and site aggregation rules are documented in [ASSESSMENT_STATES.md](ASSESSMENT_STATES.md).
SPOT inputs require a recorded basis and governing species; values above
0.12 m/s additionally require explicit QEP review confirmation.

Changing an intake's flow unit converts its value. Product presets are copied
snapshots, and editing the library does not change an intake's saved values.
Save/Load includes the inspection checklist and rejects malformed files before
changing the current session. Older saves load with an empty checklist and
unassessed inputs. Deletions offer Undo for 30 seconds.

CSV rows use the Python defaults, including zero extra support blockage. A blank
`water_type` means `waterbody`; rows must match the site's environment
(`watercourse` also covers tidal marine sites). Mismatches are reported per row.
Imported intakes remain unassessed, and elevated credit still needs baseline
confirmation. Numeric inputs use a period decimal throughout the app and reports.

All regulatory constants live in one audited `DFO_CRITERIA` config block at the top of the
script, each annotated with its standard section. **The standard is internally inconsistent
on the still-water design approach velocity** — §3.1.1 body text gives **0.055 m/s** while
Expand Down Expand Up @@ -179,10 +198,23 @@ uv sync --extra dev # same environment CI uses
uv run ruff check .
uv run mypy
uv run pytest -q

# HTML regression checks; Node 22+
npm ci
npm test
npx playwright install chromium
npm run test:browser
```

CI runs lint (`ruff`), strict type-checking (`mypy`), and the test suite on
Python 3.10–3.13 for every push to `main` and every pull request.
It also runs the HTML calculation/session regressions and Chromium browser
workflows, and uploads mobile screenshots and PDFs. The shared CSV fixture in
`tests/fixtures/intakes.csv` is compared between Python and JavaScript during
pytest (requires Node). An existing Chromium installation can be selected for
local browser tests with `PLAYWRIGHT_CHROMIUM_EXECUTABLE=/path/to/chrome`.
These dependencies are only for development; the distributed HTML remains one
self-contained offline file with no build step.

## Status

Expand Down
39 changes: 24 additions & 15 deletions TASKS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Project: DFO-compliant water-intake fish-screen spec calculator
Repo: https://github.com/shepherd70/fish-screen-specs
Last updated: 2026-09-17 (UI review plan)
Last updated: 2026-09-18 (HTML correctness, session safety, accessibility and tests)

Status legend: ✅ done · 🔄 in progress · ⬜ not started · 🅿️ blocked · ⛔ superseded

Expand Down Expand Up @@ -151,20 +151,29 @@ Findings, priorities, and the four-phase plan live in `UI_REVIEW_PLAN.md`.
optimizer skipping input validation, false FAIL on a non-numeric
envelope, enum validation on JSON load, CSV parity with the Python
reader, locale-mixed number formatting)
- ⬜ Phase 1 — make results trustworthy: written-down state model
(example / invalid / needs review / pass / fail), one strict validation
path shared with the optimizer, environment gating for elevated credit,
remove the verdict that cannot fail, fix the `Intake 2` off-by-one
- ⬜ Phase 2 — predictable recommendations and state changes: optimizer runs
the full intake checks and never alters fixed dimensions, transactional
JSON load with enum validation, shared CSV fixture read identically by
both tools, unit-switch behaviour decided and labelled, checklist state
in Save/Load, undo for deletions
- ⬜ Phase 3 — keyboard / assistive-tech / small-screen usability, print
pagination, one decimal convention
- ⬜ Phase 4 — regression harness (script block under node `vm` with a
stubbed DOM, run in CI beside pytest) plus Playwright for print, mobile,
and focus workflows
- ✅ Phase 1 — assessment state model in `ASSESSMENT_STATES.md`; strict shared
numeric validation; explicit input confirmation; elevated credit gated by
environment and baseline evidence; SPOT basis/species and review policy;
informational sweeping ratio; intake numbering fixed.
- ✅ Phase 2 — optimizer evaluates complete intake checks, preserves fixed and
displayed calculated dimensions, and previews changes; transactional JSON
load validates structure/enums/product references; checklist round-trip;
shared CSV fixture and environment mismatch guidance; flow units convert;
explicit product snapshots; 30-second deletion undo.
- ✅ Phase 3 — programmatic labels, contextual actions, intake headings, field
error associations and stable live regions; focus preserved on updates and
moved after add/duplicate/remove; mobile controls and grids fit; stronger
chart contrast; compact result summary; fixed period decimal convention;
print values wrap and headings/verdicts stay with their content.
- ✅ Phase 4 — 34 Node regression cases, 46 Python tests including shared CSV
parity, and 13 Chromium browser workflows pass locally; ruff and strict
mypy pass. Browser coverage includes 320/390/640 px, 200% CSS scaling,
French locale, keyboard sizing/save, JSON rollback, snapshots/undo, and
default/assessed/multi-intake PDFs. CI runs both test stacks and retains
browser artifacts. Default Letter PDF is five pages (previously six).

Verification limits: browser checks used Chromium; no human screen-reader
session or other browser engine was exercised. Hosted CI awaits a push/PR.

## Notes

Expand Down
6 changes: 6 additions & 0 deletions UI_REVIEW_PLAN.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# UI review and implementation plan

Implementation completed locally on 2026-09-18. The findings below preserve the
original review evidence; fixes and validation are tracked in `TASKS.md`.
Assessment behavior is specified in `ASSESSMENT_STATES.md`. Regression coverage
now includes Node calculation/session cases, a shared Python/HTML CSV fixture,
and Playwright browser workflows. The HTML remains self-contained and offline.

Reviewed 2026-09-17. Scope: the primary offline app, `fish-screen-tool.html`.
Three focused reviews covered visual/responsive presentation, accessibility, and
the intake-sizing workflow. The default page was rendered at 1280 px and 390 px
Expand Down
Loading
Loading