diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..7afbf18 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,43 @@ +--- +name: Bug report +about: Report incorrect behaviour in the FAT12 engine +title: '' +labels: bug +assignees: '' +--- + +## Summary + +A clear, concise description of the bug. + +## To reproduce + +Steps or a minimal code snippet that triggers the problem. If you can, drive it through +the in-memory device fixture (`InMemoryBlockDevice`) so it's runnable in a unit test: + +```kotlin +// e.g. format -> writeFile -> readFile, and what you observed +``` + +## Expected behaviour + +What you expected to happen. + +## Actual behaviour + +What actually happened — include the exception/stack trace or the wrong bytes/result. + +## Environment + +- fat12-engine version / commit: +- JDK version (`java -version`): +- OS: + +## Correctness-contract impact + +Does this involve a write/`mkdir`/`rename`/`delete`/set-label/set-attributes path, i.e. +the verify-after-write + rollback contract? (yes / no / unsure) + +## Additional context + +Anything else that might help — volume geometry, file names, image dumps, etc. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..aae71cb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,42 @@ +--- +name: Feature request +about: Suggest an addition or improvement to the FAT12 engine +title: '' +labels: enhancement +assignees: '' +--- + +## Summary + +A clear, concise description of the feature or improvement. + +## Motivation + +What problem does this solve? What can't you do today, or what's awkward about the +current API? + +## Proposed API / change + +If you have a concrete shape in mind, sketch it: + +```kotlin +// proposed signatures / constants / behaviour +``` + +## Scope check + +This repo is the `:core` engine only (the Android demonstrator is separate). Is the +request in scope for `:core`? + +## Correctness-contract impact + +Would this touch a write/rollback path, or is it additive (new pure helpers, constants, +read-only accessors)? Additive changes are the easiest to land. + +## Alternatives considered + +Any other approaches you thought about. + +## Additional context + +Links to the FAT spec, related issues, or examples from other tools. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..63b5736 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,31 @@ + + +## What + +Briefly describe what this PR changes and why. + +Closes # + +## How + +Key implementation notes a reviewer should know (design decisions, trade-offs, anything +non-obvious). + +## Correctness contract + +- [ ] This change does **not** touch a write / `mkdir` / `rename` / `delete` / + set-label / set-attributes path, **or** it does and I've explained below why the + verify-after-write + rollback contract is preserved. + + + +## Checklist + +- [ ] Tests added or updated for the change. +- [ ] `./gradlew :core:test` passes locally. +- [ ] Change is scoped to the `:core` engine (the Android demonstrator is separate and not part of this repository). +- [ ] Golden images under `core/src/testFixtures/resources/golden/` are unchanged (or the PR explains why they were regenerated, per `testdata/README.md`). +- [ ] PR is focused on one logical change. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..604c973 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,78 @@ +# Contributing to fat12-engine + +Thanks for your interest in contributing! This document covers how to build and test +the engine, what's in scope, and the one invariant every change must preserve. + +## Build and test + +```bash +./gradlew :core:test +``` + +This compiles the engine and runs the full headless suite on JDK 17. You don't need to +install a JDK yourself — the Gradle `foojay-resolver` toolchain plugin auto-provisions a +matching JDK 17 if one isn't already present. There is **no Android SDK, no device, and +no network access** required at test time. + +## Scope + +This repository is the engine `:core` module only — a dependency-free, pure-JVM FAT12 +read/write layer. The Android application that drives the engine over USB-OTG storage is +a separate demonstrator and is **not** part of this repo. Please keep PRs focused on the +`:core` engine. + +## The correctness contract (read before changing any write path) + +The engine's reason for existing is an atomic **verify-after-write + rollback** contract. +Every multi-step mutation (file write, `mkdir`, `rename`, recursive `delete`, set-label, +set-attributes) goes through a per-operation undo log: + +- each touched sector is captured **before** it is written, +- every data cluster is read back and byte-compared **after** it is written, and +- on **any** failure (write error, verify mismatch, or disk-full) the whole operation is + rolled back to a byte-for-byte identical pre-operation state. + +A PR **must not weaken this contract**. If a change touches a write/rollback path, say so +explicitly in the PR description and explain why it's still safe. The full test suite and +the CI `fsck.fat -n` oracle must stay green. + +## CI + +Two jobs run on every pull request (see [`.github/workflows/ci.yml`](.github/workflows/ci.yml)): + +1. **`core-test`** — the full `:core` suite on a clean, pinned JDK 17. +2. **`fsck-oracle`** — an independent [dosfstools](https://github.com/dosfstools/dosfstools) + check: the engine emits FAT12 images and CI runs `fsck.fat -n` on them (both must exit + 0). This validates the engine's writes against a real third-party FAT checker, not just + against our own expectations. + +Run `./gradlew :core:test` locally and make sure it's green before opening a PR. + +## Tests + +New behaviour should come with tests. Mirror the style of the existing tests under +`core/src/test/kotlin/com/ams/fat12ex/core/` — many of them use the in-memory device +fixture (`InMemoryBlockDevice`) and the `Fat12ImageBuilder` test fixture, so you rarely +need to touch real media. Pure-logic additions (decoders, constants, accessors) just need +a focused unit test asserting exact values. + +## Golden images + +The reference FAT12 images under `core/src/testFixtures/resources/golden/` are committed, +read-only inputs — **not** regenerated by the build. Their provenance and the exact, +version-pinned (`dosfstools 4.2`, `SOURCE_DATE_EPOCH`) regeneration procedure are +documented in [`testdata/README.md`](testdata/README.md). Don't regenerate or replace them +without a clear reason. + +## Commit and PR style + +- Keep PRs small and focused — one logical change per PR. +- Write a clear PR description: what changed, why, and (if relevant) why the + write/rollback contract is preserved. +- Reference the issue you're closing (e.g. `Fixes #123`). + +## License + +This project is licensed under **Apache-2.0**. By contributing, you agree that your +contributions will be licensed under the same terms. See [`LICENSE`](LICENSE), +[`NOTICE`](NOTICE), and [`PROVENANCE.md`](PROVENANCE.md) for details.