Ocideck/CHANGELOG.md
Brenno de Winter f93417dc3c Add fail-closed export classification gate (release ceiling)
Enforce an optional TLP release ceiling at the single export chokepoint
so no format (PDF/PPTX/HTML) can bypass it. Classifying a deck stays
optional; the gate only blocks decks classified above the configured
ceiling, and is off by default.

- ClassificationPolicy + ExportDecision: pure, tested decision logic
  (release ceiling, fail-closed; null = no gate).
- ExportService.export() evaluates the policy first and refuses without
  building or writing anything when blocked.
- Persist the ceiling as maxReleaseExportTlpKey in app settings/prefs
  (default off) with a setter on SettingsNotifier.
- Export dialog runs the same check up front and explains a blocked
  export before any work starts; app shell builds the policy from
  settings.
- Tests: classification_policy_test plus export_service chokepoint tests
  asserting a blocked export fails and writes no file.
- Docs: CHANGELOG, README, USER_GUIDE, ARCHITECTURE, SECURITY.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 00:26:29 +02:00

130 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Changelog
All notable changes to OciDeck are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and the project aims to follow [Semantic Versioning](https://semver.org/).
## [Unreleased]
### Added
- **Duplicate clean-up in the image library** — a footer button finds
byte-identical images by md5 checksum, keeps one file per group (preferring
the one used in slides, then the oldest), merges the tags/descriptions and
captions of the copies onto it, repoints slides that used a copy — in open
decks and in `.md` presentations on disk that are not currently open — and
deletes the copies after confirmation.
- **Untagged-images filter in the image library** — a toggle next to the search
box shows only images without a description/tags, making it easy to see which
ones still need attention.
- **Delete warning covers decks on disk** — deleting an image from the library
now also warns when presentations that are not currently open still
reference it.
- **Source-code slides** — a "code sheet" with per-language syntax highlighting,
stored as a fenced code block. Background, text colour and monospace font are
part of the style profile, with a syntax-colouring toggle; turning it off renders
the block in a single colour (e.g. green on black for a CRT-terminal look). The
code is sized to fill the panel — larger when there's room, smaller for long
fragments.
- **Charts** — bar, line, pie, and **spider/radar** chart slides. Data is entered
in an in-app grid or imported from CSV; the spec is stored as JSON in a ```chart
block. Data can stay inline or be linked to a CSV in a separate `data/`
directory. Rendered natively in-app (preview, presenter, PDF, PPTX) and as
self-contained SVG in the HTML export.
- Optional **min/max**: horizontal reference lines on bar/line charts, or a
fixed scale on spider/radar charts shown as a small legend beside the figure.
- **Legend hover** highlights the matching series (or pie slice). Line-chart
tooltips attach to the dot under the cursor (showing every overlapping dot),
and spider/radar points show a tooltip on hover too.
- **Custom theme colours** — every style-profile colour can be entered as a custom
hex value in addition to the presets.
- **Per-slide TLP classification** — each slide can carry its own Traffic Light
Protocol level; slides classified stricter than the level the deck is shown at
are withheld when presenting and exporting.
- **Export release ceiling** — an optional maximum TLP level that may be
exported. When set, a deck classified *above* it cannot be exported in any
format; the gate is enforced at the single export chokepoint and fails closed
(no file is written when blocked, and the export dialog explains why).
Classifying a deck stays optional — the ceiling only stops decks that exceed
it, and it is off by default.
- **Dual-screen presenter** — on a second display the beamer shows the slide
while the laptop shows the presenter view (current/next slide, notes, timer),
kept in sync over method channels.
- **Annotation layer** — draw on slides while presenting (pen, highlighter,
eraser, laser pointer). Kept fully separate from the Marp Markdown, mirrored
live to the beamer, and persisted in a `<name>.ink.json` sidecar.
- **App theming** — customizable app appearance profiles, including a dark
interface.
- **Paste a table into a table cell** — pasting a spreadsheet selection (Excel,
Numbers, LibreOffice Calc, Google Sheets), CSV (comma or semicolon), or a
markdown table into any cell of the table editor fills the whole grid from
that cell, growing rows and columns as needed. Works with `Ctrl/Cmd+V` and
`Shift+Insert` on macOS, Windows, and Linux; plain text still pastes into the
single cell.
- **Slide-type chooser previews** — the add-slide dialog shows a miniature
wireframe of each layout (in the spirit of other presentation tools) instead
of an abstract icon, and is fully keyboard-operable (`Tab`/`Enter`/`Esc`).
- **Accessibility (WCAG 2.1)**:
- An **interface text size** setting (100200%, Settings → General →
Accessibility) that scales all editor text; slides themselves keep their
fixed design size.
- The panel divider is focusable and **keyboard-resizable** (arrow keys), with
a visible focus state, and presents itself to screen readers as a slider.
- **Screen-reader support**: slide thumbnails announce one concise label
("Slide 3/12: title") instead of their full content; charts expose their
type, title, and underlying values as a text alternative; the presenter
announces each slide change.
- Improved contrast for hint/label text in the editors.
- Project documentation: contributing guide, security policy, architecture and
build notes, user guide, keyboard-shortcut reference, third-party notices, and
the EUPL-1.2 licence text.
### Changed
- **Bullet slides** can now carry an optional **subheading** under the title; the
**two bullet columns** type can have an optional **heading above each column**,
separate from the slide title.
- Slide text auto-sizing now measures with the deck's own font, so text grows to
use the available space more accurately instead of staying smaller than needed.
- The two bullet columns are measured **independently** and then rendered at a
**shared size** set by the busiest column, so the two columns always look
typographically related. Dense two-column slides spend less height on the
title, headings, and gaps so the list items themselves render larger.
- Slide transitions in the presenter no longer flash a black frame (neighbour
images are precached and `gaplessPlayback` is enabled) — important for
recording.
- **Spider/radar charts** now use the available space: axis labels are measured
and placed snugly around the polygon (up to three lines, full remaining
width), so the diagram renders considerably larger and long labels stay
readable instead of being truncated.
- Bullet auto-fit now stops growing at ≈32 pt (on a 16:9 deck) — the upper end
of the 2432 pt range presentation-design guidance recommends for body text —
so slides with few bullets no longer render body text that competes with the
title.
- After resizing the slide panel (dragging the divider or resizing the window),
the list scrolls the slide being edited back into view.
### Fixed
- Hover on charts (tooltips, legend highlight) now works on a second screen:
macOS only delivered mouse-moved events to the key window, so the borderless
beamer window never saw them; the stuck hover state after the pointer left a
window is gone for the same reason.
- Bar-chart x-axis labels could run through each other: the spacing maths now
matches how bar groups are actually laid out, and the final label shrinks to
the real gap when it sits closer than a full step.
- A crash in the slide list ("A _RenderLayoutBuilder was mutated…") when its
keyed items were rebuilt during layout — both the resize-detection inside the
panel and the shell's width computation now avoid LayoutBuilders above the
reorderable list.
## [1.0.0]
### Added
- Initial release: structured, slide-by-slide editor for Marp presentations with
typed slide templates, live preview, fullscreen presenter, deck-wide TLP
marking, media handling, import, and export to Marp Markdown, PDF, PPTX, and
self-contained HTML. Decks save as a self-contained project/package with copied
assets. Localized in Dutch, English, Italian, German, French, Spanish, Frisian,
and Papiamento.
[Unreleased]: https://example.com/ocideck/compare/v1.0.0...HEAD
[1.0.0]: https://example.com/ocideck/releases/tag/v1.0.0