Skip to content

Releases: oddurs/cairn

v1.0.0-alpha.1

v1.0.0-alpha.1 Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 28 Sep 20:07
68ac154

An alpha: the first release to write format 5, and the one Harrow
0.2.0-alpha.1 is paired with. v0.3.0 remains the stable release. Upgrade
cairn and Harrow together, and migrate a project once, on one branch, with
cairn migrate. Building from source now needs Rust 1.89.

** Writers wait their turn under load

A writer used to give up ten seconds after it began waiting, however many
writers were ahead of it, so forty agents writing at once on a busy machine
failed with every holder behaving. A writer now waits as long as the lock
keeps changing hands, and gives up when one holder has kept it for ten
seconds, by that holder's own recorded time, or after two minutes in all. A
claim queued behind its own worktree's writers no longer holds up claims in
the others.

** Breaking an abandoned lock takes turns

A lock left behind by a process that died is broken after five minutes, as
before. Two writers breaking the same one at once could each delete the
other's new lock and both write; they now take turns, through a lock the
system holds on a file in Git's directory, or in the item directory outside a
repository. Where the system cannot lock files, cairn says so once and breaks
as it used to.

** A reader that stops reading is not a crash

cairn list | head -1 printed a panic about a broken pipe. It now ends quietly,
with the status a process stopped by SIGPIPE reports, 141, so a script can
still tell the output was cut short.

** MCP tools describe ids as the project writes them

Every tool that takes an item's id says it is the item's number, or the
number as the project writes it (0012, BUG-12). show_item still described
format 4's UUIDs.

** Say when a prompt will be misread

cairn prompt ends with what may make an item misread, and cairn check
--prompts reports it for every open item: no acceptance criteria, no context,
a finished dependency with no Result, or ticked criteria with no note saying
how. Advice only; plain check is unchanged, and --strict fails on it only
when asked.

** cairn prompt: an item and everything it rests on

cairn prompt prints an item as the prompt an agent should read: how the
project works, the milestone and parents it serves, what each dependency
concluded (its Result, or its last note), the task, the criteria still open,
numbered for tick, what earlier runs learned, and what to leave behind. Each
part names its source. --json returns the layers; MCP gains prompt_item, and
the generated agent instructions start from it. Read-only.

** cairn split: a prompt's numbered steps become sub-prompts

cairn split makes each top-level numbered step of an item's Approach an
item of its own, each depending on the one before (--parallel for none), with
the parent depending on all of them and, where the schema has one, a part_of
reference back. --dry-run shows the plan; an item is split only once.

** A finished item says what it concluded

cairn close --result "..." writes a ## Result section, replacing an earlier
one; JSON carries it as result when there is one, and MCP close_item takes
it too. It is what
the work that depends on an item is handed instead of its whole history.
Closing an item that open work depends on, without a result, names that work.
The specification describes the convention in §10.2.

** Migrating is one safe step

cairn migrate refuses uncommitted changes to the files it rewrites
(--allow-dirty overrides), names branches carrying items not yet merged, and,
before writing anything, reads its own plan back and verifies that every item
keeps its body and every non-identity value, that references still name what
they named, and that restored numbers are the ones items had. It re-renders
the roadmap, and --commit records the migration as one commit. The dry run
counts files rather than listing them; --verbose lists them.

cairn migrate --all [DIR] does this for every project under a directory,
skipping, with the reason, any it should not touch, and exits non-zero if any
migration failed. A write to an older project from a terminal now asks whether
to migrate and, on yes, migrates and carries on; agents and scripts are still
refused with the command to run.

** cairn next explains an empty selection

cairn next --blocked now lists only blocked work, each item with what blocks
it; before, it added blocked work to the ranked list, and the top five were
usually ready work. MCP next_items keeps include_blocked as it was. Every count
cairn next prints is taken over the list's own selection, so the summary, the
blocked hint and list --filter blocked=true agree within a view. Finished items
no longer count as blocked in any summary. An empty view says how much ready
work lies outside it, and the hint keeps the view and filters it was given.

cairn agent --view notes a view that excludes the status cairn new assigns, or
that has nothing ready while work waits outside it, and names the file it was
written to in its regenerate line. cairn check notes a generated block whose
view has nothing ready; it is a note, so check --strict still passes.

** Claims are seen across worktrees

An agent's claim lands in its own worktree's copy of the item, so another
worktree used to take the same item. next, claim and the MCP tools now read
what the other worktrees of the repository have changed since they diverged,
uncommitted edits included. Work claimed or finished in one is not offered in
another, and claiming it is refused with the branch named unless --force.
Concurrent claims in separate worktrees are serialised by a lock in Git's
common directory. cairn worktrees lists what every other worktree has changed
or filed; cairn show adds an elsewhere line. Nothing is stored, and separate
clones are not read. A copy is matched to its item by uid where both carry
one, so an item renumbered on another branch is still recognised, and the same
number on a differently tagged item is not mistaken for it.

** Readable ids, a hidden tag, and collisions that repair themselves

Format 5 numbers items again, and a project says how its numbers read, as
before: id_format = "MP-{n}". New: a type may declare its own, so a bug reads
BUG-12 beside a feature's 0013. Every type shares one counter, so the number
alone is unique, and retyping an item changes how it reads, not what it is.
Commands accept the bare number and every rendering; a prefix naming the wrong
type is refused.

Every item cairn creates also carries a uid: a random UUID, written once and
never shown in tables, filenames or references. JSON carries it, and hooks get
CAIRN_ITEM_UID. Commands accept a uid, or a prefix of at least eight hex digits
with a letter in it, so references written while a project was format 4 still
resolve. CAIRN_ITEM_ID is the number and CAIRN_ITEM_REF its rendering.

A new number is one more than the highest the repository has seen anywhere:
every linked worktree's uncommitted items and every item file ever added on any
local or remote-tracking branch. Parallel agents in separate worktrees never
collide, and a deleted number is never reused. A collision between machines is
repaired by renumber, which the merge hook runs: the published item keeps its
number, and references that arrived with the moved item follow it, found by
its tag. Which side of a merge was published is now decided by tag; asking git
which commit added each file mistook one new item for a rename of another.

Migration from format 3 adds one uid line to each item and nothing else. The
format-4 identities of the 1.0.0-alpha.1 development builds are undone: from
format 4, every item gets back the number it had, read from _legacy-ids.toml,
items created since are numbered in creation order, each UUID becomes the
item's uid, references and UUID-named files are renumbered, id_format returns,
and the map is removed. Format 4 projects are readable but not writable until
migrated. Work filed on a branch before the migration and merged after is
numbered by renumber. Migrations are journaled and resume exactly.

The interchange document is version 1 for format 5 and carries uid; import
recognises an item already here by its uid, and reads a format-4 document's
UUIDs as uids. The format-4 corpus and specification are frozen beside the
older ones.

What's Changed

  • Set the direction and prepare cairn 0.2.2 by @oddurs in #97
  • Cairn 0.3: trust the daily loop by @oddurs in #98
  • Close v0.3 with published-release verification by @oddurs in #99
  • feat(identity)!: make item identities immutable UUIDs by @oddurs in #100
  • feat(claim): see work under way in other worktrees before claiming by @oddurs in #107
  • Bump the cargo group across 1 directory with 4 updates by @dependabot[bot] in #91
  • fix(next): count blocked work within the selection it describes by @oddurs in #104
  • chore(spec): advance the Harrow pin to worktree status by @oddurs in #108
  • feat(identity)!: readable configurable ids with a hidden uid tag (format 5) by @oddurs in #105
  • feat(migrate): one safe step, many projects at once, offered on write by @oddurs in #106
  • fix(worktree): match other worktrees' copies by uid in format 5 by @oddurs in #109
  • chore(backlog): record Harrow's migration on 0147 and defer rim and nun by @oddurs in #110
  • chore(backlog): plan the items-as-prompts milestone by @oddurs in #111
  • feat(result): a finished item records a Result that dependents can quote by @oddurs in #112
  • feat(prompt): compile an item and what it rests on into one prompt by @oddurs in https://gith...
Read more

v0.3.0

Choose a tag to compare

@github-actions github-actions released this 24 Sep 00:01

** Select an approved queue once, use it everywhere

cairn next --view NAME and cairn claim --next --view NAME reuse a saved
view's filter. Extra filters narrow it; ranking stays active-first, then
priority. MCP next_items and automatic claim_item accept the same view.
cairn agent --view NAME generates matching instructions. No reserved status
names, implicit defaults, schema changes, or new on-disk format are needed.
Bare commands keep their existing behavior.

** Git setup works in linked worktrees and with custom hook locations

cairn init --git asks Git where its post-merge hook belongs. It respects
relative and absolute core.hooksPath and the common directory of linked
worktrees, and never replaces an existing unreadable or foreign hook.

The collaboration guide and executable tests cover local versus branch-local
claims, committed handoffs, colliding branch references, rebase, cherry-pick,
and review. Renumbering leaves ambiguous references for explicit review;
rebase and cherry-pick require explicit repair and validation. No global lock,
background coordinator, automatic commit or new identifier format was added.

** The companion contract is checked in both projects

The verified Harrow companion is revision e7397a5 (PR 93), not the older
0.1.0 release binary. It reads, displays and filters closed_at without treating
a later edit as a new completion, and fixes query disagreements exposed by
the expanded suite. Cairn and Harrow now run pinned-counterpart CI; Cairn's
make agreement compares the project's views through machine-readable IDs.
See doc/COMPATIBILITY.md for tested versions and intentional differences.

** Minimal initialization starts with actual work

The minimal preset has a plain task type, so its example and ordinary new
items are selectable work, not keyless milestones. Initializing from another
schema also avoids choosing a grouping type for the example. Fresh minimal
projects pass strict validation with or without the example.

Full Changelog: v0.2.2...v0.3.0

v0.2.2

Choose a tag to compare

@github-actions github-actions released this 23 Sep 23:25

** Companion compatibility

Harrow 0.1.0 can read format-3 projects and the existing saved views. Its
closed_at filtering is not yet compatible: use Cairn for completion-date
queries until the companion contract work in v0.3 lands. A later edit changes
updated, not closed_at; do not substitute one date for the other.

** Bare initialization suggests a command that works

cairn init --bare no longer suggests creating work under v0.1, which that
mode deliberately does not create. The next-command hint names a milestone
only when initialization actually wrote the example milestones.

** cairn set no longer reports failure for a change it made

cairn set 1 title=Taken exited 1 with cannot rename to ...: file already exists -- and the title had been changed and written. The rename failed, not
the set. Running it again failed again, while the title had been right the whole
time, and a script keying off the exit status treated a completed change as not
having happened.

The filename is cosmetic in cairn: the identifier lives in the frontmatter, and
cairn check reports drift from the title as a warning. So a name already taken
is now reported rather than failed -- after the line saying what happened, the
way close reports unticked criteria -- and the file in the way is still never
touched.

Every command that keeps a filename in step with a title had the same defect,
because all of them save the item first: set, propose, edit, import and
the MCP update_item, which says it in the reply since no agent reads standard
error. renumber still fails, and deliberately: it exists to make filenames and
identifiers agree, so a name it cannot take means the repair did not happen.
** cairn log --range: what a branch did to the backlog

cairn log answered what happened to one item. Nothing answered what a branch
did, which is the question a reviewer has -- so a pull request touching a dozen
items was read as a dozen YAML diffs, and the summary reconstructed by hand or not
at all.

cairn log --range main..HEAD
cairn log --range v0.2.1..
cairn log --range main..HEAD --json

Grouped by what happened rather than by file:

  new        0128  A finished project looks like it contradicts itself
  closed     0044  The rewind works
  changed    0090  Timeline scrubbing  priority p2 -> p0
  removed    0077  Filed twice by mistake
  renumbered 2 item(s)

Items are matched by the id in their frontmatter and never by filename, because
the filename follows the title and is cosmetic. A renumber is counted rather than
listed: it moves identifiers and the filenames follow, so reported as they arrive a
repair of fifty identifiers would read as fifty items gone and fifty arrived, and
bury whatever else the branch did.

--json carries the same, for a script or a comment on a pull request.

** A Windows checkout is no longer told its roadmap is stale for ever

ROADMAP.md is generated with LF and carries no -text attribute, so a checkout
with core.autocrlf set -- the default on Windows -- converts it to CRLF on the
way out of git. The staleness check compared bytes, so it could never match: a
Windows user was told the roadmap was out of date on every run, and cairn render
rewrote it as LF, which git then reported as every line changed. There was no
state in which the project was quiet.

The comparison now ignores line endings, and rendering writes back whichever
ending the file already had -- the same pair item files have always had. A
genuine change is still a genuine change.

** A clone is told the merge driver did not come with it

A merge driver is per-clone configuration: git deliberately refuses to take an
executable name from a file in the repository. .gitattributes is tracked and
the driver is not, so cairn init --git committed a file asking for a driver that
nobody who cloned the project had.

The failure was silent and one-sided. It worked for whoever ran init --git,
which means the one person who could fix it was the one person who could not see
it; everybody else got .gitattributes asking for a driver git had never heard
of, git merged the item files itself, and two branches that had both allocated an
identifier kept it. What the newcomer learned about cairn was that a shared
backlog produces merge conflicts.

cairn check now says so -- as a note about the working copy rather than a
finding about the project, which is the right distinction and not a nicety: every
continuous-integration run is a fresh checkout with no driver and no need of one,
so a warning would have made --strict fail everywhere. cairn config no longer
calls such a project integrated, because the driver is part of the integration and
was not being checked. cairn init --git was already safe to run twice.

** When something was finished, recorded

updated records the last edit, which is exactly why it could not answer what
did we finish this week
: fixing a typo in a closed item moved it, and the week's
work changed retroactively.

cairn close now stamps closed_at, a date, at the transition.

cairn list -A --filter 'closed_at>=2026-09-01'

Stamped at the transition and only there. Closing something already closed
leaves the original date alone, reopening clears it, and every ordinary edit
afterwards leaves it where it is. It can also be set by hand, for an import or a
project adopting cairn mid-life.

closed is unchanged: it remains the derived boolean asking whether an item is
finished at all, which the filter grammar promises keeps working, so the stored
date needed a name of its own.

The key is optional and additive, so no format number and no migration -- the
specification already allows an item to gain an optional key, and requires readers
to preserve keys they do not recognise. §4 documents it, spec/reader.py
implements it, and a corpus case carries it with updated deliberately different,
so the two readers are held to agreeing about the distinction.

** A finished project no longer looks like it contradicts itself

Reported from a project with 70 items done and 7 milestones still open.

cairn list --status backlog printed no items match while seven items had
exactly that status. They matched and were then hidden for being containers, so
the message described the filter rather than what happened to the result -- and
the obvious response was to go and rewrite a filter that was correct. An empty
listing now says how many items were hidden, why, and how to see them, for
containers and for closed items alike. Naming a status still does not unhide
containers, and naming a type still does: that symmetry is deliberate.

Finishing a milestone's last item never said so. The milestone stayed in
backlog for ever, and backlog is usually the initial status, which the
roadmap does not print -- so the only visible fact was 100%. cairn close now
says it once, at the moment it becomes true, and cairn roadmap marks a
milestone whose work is all done while it is still open.

Nothing is closed for you. A project's later or Someday milestone can have
every item under it finished and be meant to stay open, so whether done work
means a shipped milestone is a judgement that stays with the person. A milestone
with nothing filed under it is not reported either: nothing filed is vacuously
complete.

** What migrating changes, and how to undo it

A project behind the current format says so on every command, and the note was
too short to answer the question it raises. The recurring line stays short, but
the write refusal -- reached once, by somebody who now needs to know -- says that
migrating rewrites cairn.toml, may create item files, changes nothing already
in the item directory, and is undone by restoring that one file. cairn migrate --dry-run says the same, counted exactly, and only where it is true: a migration
that rewrote existing items would not be undone as cheaply.

What's Changed

  • Work is filed under the grouping type's own name by @oddurs in #82
  • Bump the actions group across 1 directory with 10 updates by @dependabot[bot] in #38
  • Cleanup and quality run by @oddurs in #83
  • Clippy pedantic on, exceptions argued by @oddurs in #84
  • A lock that recorded nothing can still be broken by @oddurs in #85
  • A write cannot leave the project in a state check rejects by @oddurs in #86
  • Close 0124 by @oddurs in #87
  • Read the backlog once per bulk change, not twice per item by @oddurs in #88
  • A completed change stops reporting itself as a failure by @oddurs in #89
  • A finished project no longer looks like it contradicts itself by @oddurs in #90
  • File what makes cairn hard to collaborate with by @oddurs in #92
  • Record when something was finished by @oddurs in #93
  • Tell a clone that the merge driver did not come with it by @oddurs in #94
  • A Windows checkout is no longer told its roadmap is stale for ever by @oddurs in #95
  • cairn log --range: what a branch did to the backlog by @oddurs in #96

New Contributors

Full Changelog: v0.2.1...v0.2.2

v0.2.1

Choose a tag to compare

@github-actions github-actions released this 13 Sep 21:54
afedf05

** A milestone you create can be filed under

groups = "one" creates a field addressed by the target's key, and nothing
ever gave a grouping item a key. So the schema cairn init writes described a
feature that did not work: cairn new "v1.0" -t milestone followed by cairn set 2 milestone=v1.0 failed, and said nothing to name yet while cairn config listed the milestone two lines below.

cairn new now derives the key from the title -- v1.0 stays v1.0, "Usable
in anger" becomes usable-in-anger -- and refuses, rather than silently
skipping, the two titles that cannot make one: a title that reads as an
identifier, and one whose key another item of that type already answers to.

cairn check reports an item of a grouping type carrying no key, which finds
the ones that predate this. When a reference misses, the diagnostic now
distinguishes "there is no such item" from "the items are there and none has a
key", which is the difference between the two searches you might start.

cairn config lists the fields the schema implies, milestone and
depends_on, marked as implied. Leaving them out is how the same screen could
show a milestone existing and its field not existing.

** A warning that was always wrong

cairn check warned that render.group_by had nothing to group by whenever no
[[type]] declared groups -- including in every project that grouped by an
ordinary [[field]], which has always worked and rendered correctly from the
same schema in the same run. One project carried the warning through a hundred
runs and its CI logs.

The question is whether group_by resolves to something items carry, not
whether any type groups. The warning now fires only where grouping really does
collapse: the name is undeclared while some other type groups it (and it says
which), or a type of that name exists and does not declare groups (and it says
to add it). cairn board --group-by likewise groups by anything items carry,
including a milestone kept as a plain label.

** cairn tick

Acceptance criteria are the most-touched part of an item in a working loop, and
were the one part with no command: set takes fields, note appends, edit
wants a terminal. What people did instead was rewrite the Markdown from outside
cairn.

cairn show 12 --criteria    # numbered, with state; --json for a script
cairn tick 12 3
cairn tick 12 --all
cairn untick 12 3

Only the box is rewritten, so indentation and anything else on the line survive.
Naming a criterion that is not there refuses the whole command; ticking what is
already ticked writes nothing, because that is what a retried script does. The
MCP server gains tick_criteria, taking the numbers show_item reports.

Where a project sets require_criteria, cairn close and the MCP close_item
now refuse an item with unticked criteria rather than only reporting it
afterwards from cairn check. The default still never refuses, for the reason
it always gave: a criterion can stop applying, and a tool that blocked would
teach people to tick boxes rather than to say what is true.

** A filter typo is reported where it is typed

cairn check reported a filter naming a field the schema does not declare, and
no other command did -- so whether you found out about a typo depended on which
command you happened to run. cairn list -f 'piority=p0' said no items match, which is a true statement about an expression that does not mean what
you typed.

list, board, next, search, export, set and render now say the same
thing in the same words, on standard error, with the exit status untouched and
the results still shown. --json, --ids, --count and --plain stay
machine-readable. It stays a warning rather than a refusal for the reason
check always gave: an item may carry a field nothing declared, so the
expression may be exactly right.

render says it for a person and stays silent under -q, which is what the
after-change hook passes -- a true warning repeated after every write is how
people learn to skim the line a real one appears on.

** The filter grammar is a promise about the program

Saved views in cairn.toml are read by programs that are not cairn, which
raises a question worth answering on purpose: is the filter grammar public
interface, or an implementation detail?

It was already answered, in two places that had never been read together. The
Stability chapter promises the grammar -- field names, operators, and the
pseudo-fields -- as additive only within a major version. Section 7 of the
specification says the configuration format is not part of it, and a reader that
ignores configuration conforms. So the grammar is a promise about the program
and not about the format.

What was missing is that nothing held the promise to account -- it was the one
item in the Stability chapter with no test -- and nobody writing a view was told
which dialect they were writing in. tests/stability.rs now pins the operators
and the pseudo-fields, and fails if the set of derived keys changes without
somebody deciding which side of the line the new one falls on. The Filters
chapter, the Integrating chapter and the [[view]] block cairn init writes
all say it now, including the part that matters to another tool: run cairn list --view NAME --json rather than reimplement the grammar, because a narrower
dialect does not fail on a view it cannot parse -- it returns nothing, and a
valid view looks like an empty backlog.

** A combining mark could reach a filename

slug lowercased a character and kept whatever came out. Turkish dotted capital
I lowercases to i followed by a combining dot, which is not a letter -- so
cairn new "İstanbul rewrite" wrote a filename carrying an invisible mark for a
filesystem to normalise however it liked.

Characters are now filtered after lowercasing rather than before. Found by the
property test that has asserted the opposite all along, which had simply never
generated that input; the case is pinned now, both as a unit test and in
proptest-regressions/.

** Documentation that had gone stale

The Configuration chapter still documented [[milestone]] as a block you write,
with a cairn milestone command to edit it. Neither has existed since format
3: a milestone is an item, and the block is refused by name. Somebody meeting
the milestone trouble above would have found that section first.

propose, proposals and migrate reached a release with no entry in the
command reference, documented only in prose elsewhere. They have one now, and a
test fails if a future command ships without one. The README no longer lists
cairn milestone either.

What's Changed

  • A milestone can be filed under, and a criterion can be ticked by @oddurs in #78
  • The release checklist cannot hold the promise the release makes by @oddurs in #79
  • A filter typo is reported where it is typed by @oddurs in #80
  • cairn 0.2.1 by @oddurs in #81

Full Changelog: v0.2.0...v0.2.1

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 06:29
b02e2e7

What's Changed

  • Verify every install path against the real release by @oddurs in #12
  • Record MCP work under the name the client gave by @oddurs in #13
  • Make the printed views worth looking at by @oddurs in #14
  • A website: landing page and documentation by @oddurs in #15
  • Record the website's terminal samples instead of typing them by @oddurs in #17
  • Back the site with a design system by @oddurs in #18
  • The road to 1.0 by @oddurs in #19
  • Make the recordings reproducible by @oddurs in #21
  • Ask contributors for a licence agreement, and say why by @oddurs in #20
  • Write down the line, before there is anything on the other side of it by @oddurs in #22
  • A sprint on identifiers people can say out loud by @oddurs in #24
  • What the critique turned into by @oddurs in #25
  • The promise, the boundary, and three rules that check themselves by @oddurs in #26
  • Say where to report a bug, and choose an editor that exists by @oddurs in #27
  • Show how an item got here by @oddurs in #28
  • Change several items in one command by @oddurs in #29
  • Test where the defects have actually come from by @oddurs in #30
  • Say what may be scripted against, and review the surface before it freezes by @oddurs in #31
  • Let a project say how its identifiers are written by @oddurs in #32
  • A second reader, and merges that keep the published identifier by @oddurs in #33
  • A cookbook, a test that the manual is true, and the translation decision by @oddurs in #35
  • Make a release verifiable, as far as is possible without a key by @oddurs in #36
  • A release checklist, and the evidence 0067 was missing by @oddurs in #37
  • Eight items from a critique of the schema by @oddurs in #39
  • One table for everything on an item, and the milestone decision by @oddurs in #40
  • Read the acceptance criteria by @oddurs in #41
  • An empty checkbox is a placeholder, not a criterion by @oddurs in #42
  • A field can name another item by @oddurs in #43
  • Composition, and no level names by @oddurs in #44
  • The hierarchy is a query, not a schema by @oddurs in #45
  • What an agent may touch, and who is answerable by @oddurs in #46
  • Say what a cairn item is by @oddurs in #47
  • Merge sequence fields by union by @oddurs in #48
  • Format 2: milestones are items by @oddurs in #49
  • A key is queryable like any other field by @oddurs in #50
  • A plan for not breaking people by @oddurs in #51
  • An older project is readable, and every format it wrote is kept by @oddurs in #52
  • A plan for the configuration side by @oddurs in #53
  • The schema says what it means by @oddurs in #54
  • What the configuration promises, and what it does not by @oddurs in #55
  • Adopt a schema instead of retyping it by @oddurs in #56
  • An alias is not a typo by @oddurs in #57
  • A plan for the durability run by @oddurs in #58
  • The agent surface enforces what it advertises by @oddurs in #59
  • Test the two things that can lose work by @oddurs in #60
  • Be right about data nobody here wrote by @oddurs in #61
  • Unit-test the reference machinery by @oddurs in #62
  • Say what make check proves, and add the target that proves the rest by @oddurs in #63
  • A measured test coverage sprint by @oddurs in #64
  • A test harness worth having by @oddurs in #65
  • A plan for what cairn owes an agent by @oddurs in #66
  • A claim is a promise somebody might not keep by @oddurs in #67
  • Asking for less, and asking what moved by @oddurs in #68
  • A proposal is a proposal, and what an agent is to cairn by @oddurs in #69
  • cairn is MIT by @oddurs in #70
  • The site footer still said GPL by @oddurs in #71
  • Tidy: split the tests, repair what had gone stale, dogfood the driver by @oddurs in #72
  • Format 3: a type declares that it groups work by @oddurs in #73
  • cairn 0.2.0 by @oddurs in #74

Full Changelog: v0.1.0-rc.1...v0.2.0

v0.1.0-rc.1

Choose a tag to compare

@github-actions github-actions released this 05 Sep 07:55
78f9542

What's Changed

  • Add cairn note, for recording why by @oddurs in #1
  • Normalise line endings on every body that comes from outside by @oddurs in #2
  • Teach git to resolve the files cairn generates by @oddurs in #3
  • Close an imported issue with a pointer to the item by @oddurs in #5
  • Audit dependencies, licences and sources on every change by @oddurs in #6
  • Publish the item format as a specification in its own right by @oddurs in #7
  • Release candidate 0.1.0-rc.1 by @oddurs in #9
  • Fix release packaging by @oddurs in #10
  • Build macOS x86-64 by cross-compiling by @oddurs in #11

New Contributors

  • @oddurs made their first contribution in #1

Full Changelog: https://github.com/oddurs/cairn/commits/v0.1.0-rc.1