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
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# The seed templates are compared byte for byte against files older releases
# wrote with LF, so they must check out as LF on every platform, including
# the Windows runner that builds the release binary (DECISIONS.md §39).
src/seed/*.md text eol=lf
25 changes: 23 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,31 @@ All notable changes to `hi` (Human Intent). Format follows
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

The format itself is versioned separately by the `hi:` key in each file's frontmatter. `HI/1` is the
only version so far, and since the Unreleased entry below a file declaring any other version is
only version so far, and since 0.8.0 a file declaring any other version is
refused rather than read as this one.

## Unreleased
## [0.8.0] 2026-09-18

**The 1.0 release candidate.** Everything three readiness reviews called blocking is in this
release, and nothing else is planned before 1.0. [HI-1.md](HI-1.md) is the contract it will
freeze. The tag for 1.0 is this build after a soak, with the version number changed and nothing
else; if a defect in the promise is found meanwhile, it ships as 0.8.x and the soak restarts.

The one change here that can turn an adopter's green build red is `duplicate-family`, the
seventh `hi check` kind: two files both declaring one family. Fix it by leaving the family in one
file's frontmatter. A file declaring a `hi:` version other than `1` is now refused as well.

### After the 1.0 readiness review of #20

- `hi: "1"`, `hi: '1'` and `hi: 1 # comment` are HI/1. They were refused as unknown versions,
which locked the whole repository over YAML punctuation that `owner:` already tolerated.
- `hi seed` rewrites `hi/AGENTS.md` atomically. A truncating write that died halfway would have
left a file that is no longer a template hi shipped, which `hi seed` then refuses forever.
- On Windows, `still_at` now compares the held handle's file identity against the path's, through
`GetFileInformationByHandle`, instead of relying on the delete-pending argument DECISIONS.md §34
admitted nothing tested.
- HI-1.md's id grammar names the digits a family may contain, the `a-z` letter levels, and the
32-bit bound on a number.

### Two files claiming one family is a structural problem, not a tie-break

Expand Down
8 changes: 4 additions & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ serve (`hi: CAPTURE-3`). If you change behavior, update the spec. `specsync chec
`Doc::save`, and do not give it a lock: `capture` and `retire` already hold `lock::acquire` and
it is not reentrant (DECISIONS.md §30, `hi: INDEX-4`, `INDEX-4.a`).
- **`hi check`'s note about that list is a note, not a problem.** `out::index_note` is
pushed onto `Report::note`, which `Report::ok` never reads, so the exit code cannot move. It is
pushed onto `Report::notes`, which `Report::ok` never reads, so the exit code cannot move. It is
the first thing `check` nags about that hi itself maintains, and it is only admissible because
capture and retire keep the list current, leaving one cause: a criterion typed in by hand, which
`FILE-14` allows (DECISIONS.md §30, `hi: INDEX-4.b`, `CHECK-1`).
Expand Down Expand Up @@ -208,7 +208,7 @@ gitignored.

## Releasing

v0.7.0 is out: the repo is public, `human-intent` is on crates.io, `corvidlabs/tap/hi` is in the
v0.8.0 is out and is the 1.0 release candidate; HI-1.md is the contract 1.0 freezes, and the 1.0 tag is 0.8.x with only the version changed. The repo is public, `human-intent` is on crates.io, `corvidlabs/tap/hi` is in the
Homebrew tap, and every tagged release carries binaries for Linux and macOS (both architectures
each) and Windows. The docs are at corvidlabs.xyz/hi, and corvidlabs.github.io/hi publishes this
repository's own `hi view` output on every push to `main`.
Expand All @@ -218,8 +218,8 @@ publish` runs failed on a dirty tree and the failure was not noticed. 0.3.0 clos
lesson is the rule below: read what `cargo publish` actually printed, and check the registry.

`release.yml` fires on a `v*` tag, so **tagging is the release**. Bump `Cargo.toml`, update
`CHANGELOG.md`, commit, push, tag, then `cargo publish` separately. The format is not frozen; this
is 0.x.
`CHANGELOG.md`, commit, push, tag, then `cargo publish` separately. HI/1 is the format 1.0 freezes; until the
tag it may still change, but only for a defect in what HI-1.md promises.

**Publish from a clean tree, and verify the registry afterwards.** `cargo publish` refuses a dirty
working tree, and that refusal is easy to miss in a wall of output. Run `cargo publish --dry-run`
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "human-intent"
version = "0.7.0"
version = "0.8.0"
edition = "2024"
description = "Human Intent; acceptance criteria in human words, with permanent ids"
license = "MIT"
Expand Down
9 changes: 5 additions & 4 deletions DECISIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1803,10 +1803,11 @@ the bootstrap into a repository with no `hi/` locks like every later capture, a
into a fresh repository all land. What is *not* asserted anywhere is the delete-pending argument
itself — that no replacement lock file can be created while a handoff is in flight. Nothing in the
suite forces that interleaving on Windows the way
`a_lock_granted_on_a_file_that_was_replaced_is_not_the_repository_s_lock` forces it on unix. If
that argument is wrong, Windows has the same hazard `still_at` exists to close, and the fix would
be a `GetFileInformationByHandle` comparison in `still_at`, which is a fourth `extern` and no new
dependency.
`a_lock_granted_on_a_file_that_was_replaced_is_not_the_repository_s_lock` forces it on unix. *Since the
1.0 readiness pass, Windows makes the same comparison unix does: `still_at` compares the volume
serial and file index of the held handle against the path's, through `GetFileInformationByHandle`,
a fourth `extern` and no new dependency. The delete-pending argument may well be right; the promise
no longer rests on it.*

### What is still true, and what is not claimed

Expand Down
2 changes: 1 addition & 1 deletion HI-1.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Normative:
2. **`## Intent`.** Human prose. A fenced block in it is prose, so an example of the format is not criteria.
3. **`## Criteria`.** Live criteria. One criterion is one markdown list item, one line, however long the sentence runs. The parser also accepts a bare `ID sentence` line with no bullet and no bold, so a hand-typed file is still read.
4. **`## Retired`.** Criteria the author changed their mind about. The id stays spoken for.
5. **Ids.** `FAMILY-1`, then letters for cases and numbers for steps, alternating strictly: `SEND-1.a.1.b`. Families are uppercase `A-Z` and `_`. A leading zero on a multi-digit level is not an id (`SEND-007` is refused, not normalised to `SEND-7`).
5. **Ids.** `FAMILY-1`, then letters for cases and numbers for steps, alternating strictly: `SEND-1.a.1.b`. A family starts with `A-Z` and continues with `A-Z`, `0-9` and `_`; a letter level is one or more of `a-z`; a number level is a decimal integer that fits in 32 bits. A leading zero on a multi-digit level is not an id (`SEND-007` is refused, not normalised to `SEND-7`).
6. **A criteria file is lowercase `*.md` directly inside `hi/`.** An uppercase name in `hi/` is hi's own (`AGENTS.md`, `CLAUDE.md`) and is not read as criteria.

hi itself always writes the list form, LF or the file's existing endings, and the frontmatter style the file already had. It never rewrites, reflows, or reformats prose it did not write.
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,10 +358,12 @@ on their own product to find it, and the first fix we shipped for it was the wro

## Status

**v0.7.0** on [crates.io](https://crates.io/crates/human-intent), with binaries for Linux (x86_64
**v0.8.0** on [crates.io](https://crates.io/crates/human-intent), with binaries for Linux (x86_64
and arm64), macOS (Intel and Apple silicon) and Windows on the
[release page](https://github.com/CorvidLabs/hi/releases). The Unreleased work on this branch
writes the contract a 1.0 will freeze — [HI-1.md](HI-1.md) — without tagging it.
[release page](https://github.com/CorvidLabs/hi/releases). **0.8.0 is the 1.0 release candidate.**
[HI-1.md](HI-1.md) is the contract 1.0 will freeze, and 1.0 is this build after it has soaked:
the same code with the version number changed. A defect in the promise found meanwhile ships as
0.8.x and restarts the clock.

**Permanence of an id is a convention over shared history: the merged tree, not an unmerged
branch.** Two workstreams can each choose the same hand-chosen id against the tree they captured
Expand Down
Loading
Loading