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
9 changes: 7 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ trim_trailing_whitespace = true
indent_style = space
indent_size = 2

[*.{cs,csproj,props,targets}]
indent_size = 4
[*.cs]
# K&R: the opening brace ends the line that opens the block, and else/catch/finally
# continue the line that closed the previous one. Indentation is the 2 spaces from [*].
csharp_new_line_before_open_brace = none
csharp_new_line_before_else = false
csharp_new_line_before_catch = false
csharp_new_line_before_finally = false

[*.{md,markdown}]
trim_trailing_whitespace = false # trailing spaces are hard line-breaks
Expand Down
55 changes: 55 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,61 @@ public listing validates).
Stable releases are **manual** (`gh workflow run release.yml`) — never cut
one unless explicitly asked.

## Sourcing an implementation

Never write a format, codec, cipher or compression scheme out of your own understanding when
somebody has already got it right. Work **down** this ladder, stop at the first rung that applies,
and say in the commit body which rung you used and why the ones above it did not.

**1 — Licence-compatible source you can take.** MIT, BSD, Apache-2.0, LGPL, public domain: anything
this repository's LGPL-3.0-or-later can absorb. Search for it before writing anything. There are two
ways to take it and the choice is not cosmetic:

- **Vendor it** — a verbatim subtree under `Vendored/<Library>/` next to its own `LICENSE.txt`, kept
in the upstream's own formatting. Do *not* restyle it: the whole point is that the next upstream
version still applies cleanly, and a reformatted copy conflicts on every update. Keep it out of
the published API surface with the `exclude-namespace` input of the `package-readme` action rather
than by editing the source.
- **Convert it** — carry the algorithm across into this codebase properly. Converted code is *our*
code, so every rule under "Code conventions" applies to it, including the current C# language
version (C# 14) wherever that says the same thing more plainly. Do not restate those rules
here or anywhere else: one stale copy of them is how this guide spent years asking for a brace
style the code had never used. A conversion that still reads like C, or like a decompiler's
output, is not finished.

Either way, record where it came from — a `THIRD_PARTY_NOTICES.md` in the package, or a
`THIRD-PARTY-NOTICE.<Name>.txt` beside the code. Attribution is a licence term, not a courtesy.
Comment on lines +65 to +66

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve upstream licenses when converting code

When the compatible-source path uses “Convert” rather than “Vendor,” requiring only a provenance file is insufficient: a translation or adaptation remains derivative code subject to the upstream license. For example, Apache-2.0 requires preservation of its license, applicable NOTICE contents, and prominent notices of modifications. Agents following this guide could therefore ship converted code without satisfying its license; require compliance with every upstream license condition for both paths, not merely attribution, while retaining this repository's LGPL licensing.

AGENTS.md reference: AGENTS.md:L113-L114

Useful? React with 👍 / 👎.


**2 — Licence-incompatible source: use it, but not its code.** GPL where we ship LGPL, anything
proprietary, anything with no licence at all. Read it and *build material from it*: a written
specification, a set of test cases, and a third-party oracle you can run to produce expected output.
Then implement from that derived material. Do not paste it, do not transliterate it line by line,
and do not carry its file layout or its identifier names across — that is still the same copy.

**Constants are not expression.** Tables, S-boxes, magic numbers, CRC polynomials, Huffman code
tables, quantisation matrices, window and filter coefficients: copy them exactly, from whichever
source is authoritative, on every rung of this ladder. A re-derived S-box is simply a wrong S-box,
Comment on lines +74 to +76

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Do not copy constants from incompatible sources

The “on every rung” exception explicitly directs contributors to copy tables even from the preceding proprietary or unlicensed-source rung. Although some standardized constants are uncopyrightable facts, arbitrary quantization matrices, filter coefficients, and collected tables can still be protected by copyright, database rights, patents, contract, or trade-secret restrictions. Limit verbatim copying to authoritative sources whose terms permit redistribution; incompatible sources should remain oracle-only so an implementation does not compromise the repository's LGPL distribution.

AGENTS.md reference: AGENTS.md:L113-L114

Useful? React with 👍 / 👎.

and a table somebody worked out for themselves is the defect that nothing catches until real files
arrive. Where a value is arbitrary-but-agreed, matching it *is* the specification.

**3 — Original reference material.** The specification, the standard (RFC, ITU-T, ISO, ECMA), the
academic paper, the vendor's own documentation, the format author's write-up. Prefer the normative
text over anybody's description of it; where the two disagree, the normative text wins and the
disagreement is worth a comment.

**4 — Other trusted sources.** Reverse-engineering write-ups, articles and blog posts by named
people with a track record, and long-lived project wikis that cite their evidence.

**5 — Untrusted material, by agreement only.** Forum answers, unattributed gists, wiki edits with no
provenance. Only when nothing above exists, and only where several *independent* sources agree —
majority vote, discounting the ones that plainly copied each other. Treat the result as a hypothesis
and mark it as one in the code.

Whatever rung you land on, the finished implementation is judged the same way: it must agree with an
oracle or with real files, not merely compile and look plausible. When a licence-incompatible
implementation was your oracle, keep the comparison as a test wherever it can run, and where it
cannot, commit the captured expected output with a note saying what produced it.

## Code conventions

- Latest C# features; namespaces/assemblies are `Hawkynt.PhotoManager.*`
Expand Down
Loading