Skip to content

Releases: myfjin/folder-nature

v0.2.4 — a complete sdist, and a PyPI page that is true

Choose a tag to compare

@myfjin myfjin released this 23 Sep 20:38
v0.2.4
6ea85d9

A complete sdist, and a PyPI page that stopped lying. pip install -U folder-nature

The source distribution was missing the project's own files

It carried the tests, AUTHORS and README (52 entries) but not CONTRIBUTING.md,
SECURITY.md, CODE_OF_CONDUCT.md or CREW.md. Somebody who downloaded the tarball got the code,
and the rules that apply to it were only findable by locating the repository — which the tarball did
not tell them about.

MANIFEST.in fixes it: 52 → 62 entries, verified before committing.

The published description said something untrue

The 0.2.3 page said "pip install folder-nature gives you 0.2.1 … install from the tag". True
when it was built; false by the time it was fetched, because the upload changed the answer.

PyPI fixes a description at upload time and offers no way to edit a released version — so the only
correction is another release. That is what this is.

The line itself was already fixed on main (it names no version now), and one more got a
clarification: "Latest development version" now says unreleased work on main, which may be
ahead of any release
.

No behaviour change

The package code is identical to 0.2.3. 124 tests pass on Python 3.10–3.13, Linux and macOS.

v0.2.3 — a signed manifest carries the UTC date

Choose a tag to compare

@myfjin myfjin released this 23 Sep 17:26
v0.2.3
c08537d

One field, one alphabet. pip install -U folder-nature

A signed manifest carried the wrong kind of date

build_manifest() recorded date.today() — the local date — inside a manifest that is then
signed. Two machines signing the same folder at the same instant could disagree about what day
it was, and the signature would faithfully attest both. A signed artifact should not carry a
value that depends on which clock you are standing next to.

Proven before the fix, and proven deterministically — the test renders the manifest under
Etc/GMT+12 (UTC-12) and Pacific/Kiritimati (UTC+14), 26 hours apart, so their local dates
differ at every instant rather than occasionally near midnight:

UTC-12 -> 2026-09-23
UTC+14 -> 2026-09-24

The fix is datetime.now(timezone.utc).date() — same YYYY-MM-DD shape, now unambiguous.

Nothing reads the field, and nothing breaks. Checked before changing it: no code in this
repository or in our downstream consumer parses manifest created; and verify checks the
signature over the stored bytes, so every manifest signed by an earlier version still
verifies unchanged
. Only newly signed manifests differ.

The alphabet was written in invisible characters

The watermark's alphabet is U+200B, U+200C and U+2063 — invisible by definition. They were
written as literal invisible characters, so the only thing saying which characters they were
was a comment beside them. A copy/paste, a re-encoding, or a diff tool that eats the character
could have changed the alphabet without changing anything a reader can see.

They are escapes now ("\u200b"), and a test pins the contract. Verified behaviour-neutral: the
loaded codepoints are identical before and after. The test was made to fail once by corrupting
one escape before being trusted.

Tests

122 → 124 passing, on Python 3.10–3.13, Linux and macOS. Both new tests were written first;
the date test failed against 0.2.2.

A note on how this was made

The first attempt at the tag pointed at a stale checkout whose pyproject.toml said 0.2.2. It
was caught, deleted, and re-cut on the commit that actually carries 0.2.3 — verified by reading
pyproject.toml at the tag through the API, not by assuming. A version and its tag are the
same claim stated twice.

v0.2.2 — the mark line is recognised by structure

Choose a tag to compare

@myfjin myfjin released this 23 Sep 17:01
v0.2.2
ddc6cbf

One defect, in the mark layer. pip install -U folder-nature.

What was wrong

stamp_text() is documented as idempotent — "an existing mark is replaced". It was not, once
anything had indented the channel-A mark line:

channel-A frames in the file
after stamping 1
re-stamp, untouched 1
re-stamp after the line is TAB-indented 2

The old frame survived, a second was added, and the file still verified as authentic — so
the previous payload stayed embedded and extractable beside the new one. That is the wrong
failure for an attribution layer: it accumulates history nobody chose, and it looks healthy
while doing it.

gofmt indents with tabs and Go is a supported language, so this was reachable, not theoretical.

Why it happened

The mark line was recognised by a character-set question:

does this line consist only of comment characters, spaces and zero-width characters?

That is a proxy for "is this a mark line", and it answers wrong the moment the line carries any
other character — a tab, say. It is now recognised structurally: an optional comment prefix,
one sentinel-delimited zero-width frame, and nothing else. Indentation of any kind stops
mattering.

The new recogniser is also stricter, which is the safe direction: it no longer removes a line
it did not write. The old check would have eaten a line of code that merely contained a frame.

How it was found

By reading the lint findings instead of trusting them. A linter said "stripped is assigned to
but never used"
— reported as dead code. It was an omission: the author computed the stripped
line intending to compare it, and the check compared the raw line instead.

Tests

The new test was written first and failed against 0.2.1 with assert 2 == 1.
120 → 122 tests passing, on Python 3.10–3.13 and both Linux and macOS.

Note on the tag

v0.2.2 is SSH-signed and GitHub reports it verified. Verifying it locally needs
gpg.ssh.allowedSignersFile configured — GitHub is the authority here, and it says valid.

v0.2.1 — Go watermark fix

Choose a tag to compare

@myfjin myfjin released this 23 Sep 14:58

One bug, one release. The Go structural channel of the watermark placed its constant
before package + import, which is invalid Go — the mark could not be embedded in a Go
source file at all.

Fixed by emitting the structural constant after the package and import block. Two
commits, four files.

No API change. If you embed marks into Go sources, this is the version you want.

v0.2.0 — the mark layer

Choose a tag to compare

@myfjin myfjin released this 23 Sep 14:57

The version that makes a folder claim who it is, verifiably.

pip install folder-nature (on PyPI since 2026-07-05; this release is what that index now serves).

What landed (8 commits, 29 files)

  • v-next: the mark layer — attribution, signing, enforcement. A folder can carry a
    mark that travels with its contents.
  • Watermark: human-readable attribution in the visible channel — the mark survives
    being read by a person, not only by the tool.
  • verify --root — a self-validating tree: one command checks the whole structure
    from the root.
  • Apache-2.0 NOTICE — attributes the vendored public-domain Ed25519 implementation.
  • License corrected to Apache-2.0, merge-accurate wording. 0.1.0 remains MIT; the
    patent grant from 0.2.0 onward covers the signing/watermark work.
  • Docs: install instructions moved to git+https until the PyPI release went live;
    demo screenshots and a GIF added.

Honest note

The tags in this repo are annotated but unsigned, so GitHub shows them without a
verified badge. That is a gap against our own convention, not a claim of provenance.

v0.1.0 — MVP

Choose a tag to compare

@myfjin myfjin released this 22 Jun 17:19

First public release of folder-nature.

Features

  • Schema v1.0 — versioned YAML with identity / tags / rules / memory blocks
  • 7 CLI commands — init, show, query, search, validate, list, version
  • 5 archetype templates — workspace, client-project, archive, deployment, documentation
  • Walk-upward semantics — find_director + get_folder_nature for ancestor lookup
  • 66 tests passing in <1s
  • MIT licensed, Python 3.10+, single runtime dependency (PyYAML)

Install

pip install folder-nature  # (PyPI publish coming soon)
# OR from source:
git clone https://github.com/myfjin/folder-nature
cd folder-nature && pip install -e .

5-minute tour

See README.md for the full walkthrough.

🐍🦅💎