Skip to content

Subroutine 0.9.9

Choose a tag to compare

@github-actions github-actions released this 26 Sep 13:03
· 400 commits to main since this release

Fixed

  • A span with a year only on its end starts no more than eleven months before it. A start
    with no year is counted back from an end that has one, so Trip from 3 November to 2026-10-30
    was stored as a trip that began on 3 November 2025. Counted back further than eleven months,
    a span is now left in the title and reported, and giving the start its own year stores it. A
    weekday in front has to fall in that year too: from Friday 2 October to Tuesday 12 October
    2027
    is reported, since 2 October 2027 is a Saturday. subroutine plan and the agent tools
    read a start and an end the same way, so plan 1 "2 October" --until "12 October 2027" is ten
    days in 2027 rather than a year and ten days.

  • The agent tools read a start and an end given together as one span, as subroutine plan --until does. Each was read on its own, counting from today, so friday until monday said
    on a Saturday was refused as finishing before it started.

  • An ISO time keeps its UTC offset. Workshop from 2026-10-02T09:00-05:00 was read as an
    appointment from nine until five the next morning, and the deferral and the offset were both
    lost. A time after a T is read with its offset. With a space in place of the T, the date
    is read as any other date is, so on 2026-10-02 09:00-10:00 is an hour from nine; write the
    T to give an offset.

  • A start written as an ISO time keeps its time. Workshop on 2026-10-02T09:00 was stored
    as starting on 2 October with no time, and the time and any offset were dropped without a
    word. A deadline and a deferral always kept theirs.

  • A date that does not exist is reported rather than refusing the whole line. by 29
    February 2027
    and on 31 April stopped anything being added. They now stay in the title and
    are reported, and the rest of the line is used. An ISO date that does not exist, such as
    2026-02-30, is still refused by name, as it is when sent on its own.

  • A line dated at the very end of the calendar is added rather than failing. from
    9999-12-31 by tuesday
    and a few lines like it were an error from the server.

  • Two times joined by an em dash are treated as two joined by a hyphen. Where the pair could
    not be read as a range, the em dash form set a start at the first time and left the second in
    the title without a word. It is now left whole and reported, as the hyphen's always was.

  • An item's history and the change feed say what an unlink removed. Both said unlinked it
    from something
    , in the terminal and in the agent tools, while the journal beside them named
    the other item.

  • A loop through two relations is refused, as a loop through one always was. X blocks Y
    followed by Y precedes X was accepted, and so were two milestones that each counted the other,
    through includes and a relation of a workspace's own in the same category. A loop that holds
    no work up is now called a sequence that cannot come back to where it started, not work that
    can never begin.

  • A link type cannot move into or out of the gating or counting category under its links.
    Moving blocks to counting made every task that blocked something read as including work, and
    moving includes to gating held every milestone's work off --ready. While links use a relation
    such a move is now refused, saying how many; any other move still goes through.

  • Downgrading the database below 0.9.7 finds the milestone type and includes under any name.
    A workspace that had renamed either made the downgrade fail on a database constraint, rather than
    complete or refuse in its own words.

  • A milestone counts only the work you can see, and says when it includes more. Its row
    counted work in projects you cannot see - how many pieces, and how many were done - while its
    own page counted only what you could. Both now count what you can see, and add and more you
    cannot see
    where there is more, never how much. Included done still means all of it, seen or
    not, so finishing what you can see does not tell you the milestone is finished.

  • A project's agenda can be saved as a view. On a project, whose page opens on its agenda,
    Save was refused for narrowing an agenda by a search line you never typed. The view keeps
    the project, and opening it draws that project's agenda.

  • Renaming a project no longer stops on a saved view it cannot read. One shared view with a
    malformed search line refused every rename in its workspace without naming the view. The rename
    now names it in its question, and counts a view that names the project inside a path, such as
    project:acme/blog when acme is renamed.

  • subroutine view run with --connection reads the view on that connection. It asked the
    connection a write goes to, and said that one could not be reached.

  • A view's name with no letter or digit in it is refused as you typed it. Over HTTP it was a
    redirect the program could not read.

  • A shared view saying touched_by:me or answers_to:me is marked as drawing each reader their
    own work
    , as one saying assignee:me always was.

  • A credential narrowed to some projects cannot change what a shared view says, as it could
    already not share one.

  • A filter refused for its operator says what that field takes. The advice written for a
    timestamp was given to every field: ref.gte was told to use ref.gte, ref.ne that a ref is
    stored to the microsecond, and created_at.is that created_at takes is. A range is now
    suggested only for a field that takes one, and is on a field that always has a value says so.

  • agent create --here works in a directory whose name a .gitignore line would read as a
    pattern
    , such as #notes, [draft] or !x. The line it adds is escaped: it was a comment, a
    class or a negation, and the command refused, leaving the line behind. The command a refusal
    suggests now names the file from where you are, in a form a shell runs as printed.

  • agent create --here says when the plugin's tools will not follow. It names the variable
    after the connection a write goes to, and the subroutine plugin reaches this machine's default
    unless its settings name another, so where the two differ the tools go on as before. It said
    they would name the agent.

  • agent create --here no longer leaves a new credential where git would take it, or where
    nobody has it.
    The file is staged in a directory git ignores and is on the disk before it is
    renamed into place. A settings file that is not UTF-8, or holds text UTF-8 cannot, is refused
    before anything is minted, and any failure after minting shows the credential, where only a
    failure of the disk did. A settings file that is a link out of the repository is refused by
    saying where it leads.

  • A search for an item's parent answers in the agent's tools and the browser. parent:12
    is asked of tasks and documents both, and each refused the other kind's number, so the search
    failed whichever kind the number named - and on a project's page read as the project having
    gone. The terminal already answered it. A number that names nothing is still refused.

  • Moving a document and revising it in one call does both. The move put the document's
    version up, and the revision was then refused as somebody else's change - the call's own - and
    answered that nothing had changed. The browser's edit form did the same when its Parent box
    changed. A version given with such a call is now checked on the move, before anything is
    written.

  • A refusal after part of an act says what had already been done. Several links made in one
    call, a reason given to done, skip, plan, defer or update, and user create with
    --browser or --terminal are each more than one request, and a busy database on a later one
    said this request changed nothing while the earlier ones stood - so a reason was lost, or a
    sign-in link made and never shown. The refusal now names what stands, and the command that
    finishes the rest.

  • user create --json with --browser or --terminal is refused before anything is made.
    It printed the account alone, so the sign-in link or credential it had just made was live and
    had been shown to nobody. --json goes with neither now: a secret is shown once, to a person,
    and not to a script.

  • The subroutine plugin passes its token field under a name of its own,
    SUBROUTINE_PLUGIN_TOKEN.
    The field travelled as SUBROUTINE_TOKEN, which is also the
    variable you may export in a shell for your default connection. An editor that left an empty
    field's variable unset, rather than set and empty, would have let a token you exported be
    taken for the field and sent to whichever instance the plugin names, and the tools could not
    have said that the field had emptied. With this release and a refreshed plugin, neither can
    happen. The plugin passes the field as SUBROUTINE_TOKEN as well, so an older program goes on
    reading it.

  • An appointment inside one day names that day once: Mon 4 Oct, 14:00 to 15:00, where the
    terminal and the browser said Mon 4 Oct at 14:00 to Mon 4 Oct at 15:00. A span across
    midnight still names both days, because there the second day is the news.

  • An event can be given an end in the browser. The form has Until beside Starts, so an
    appointment from 11:00 to 13:00 is written there as it is at the terminal, and an end given a
    time and no day ends on the day it starts. The item page shows a span as one fact. Due was
    the only other date on the form, and an event refuses a deadline - which now says to set
    until to when it is over, where it said only to give it a start.

  • A time range written after its day is read. Meeting tomorrow from 11:00 to 13:00 and
    Standup on monday from 9am to 5pm file appointments, where the first stayed in the title
    and the second was planned for the whole of Monday with from 9am to 5pm left in it. from
    reads two times only beside a day, so Move the meeting from 2pm to 3pm stays as written.

  • subroutine_whoami offers agent create --here only where it can work: in Claude Code,
    through the subroutine plugin. --here writes Claude Code's own settings, so an agent in
    any other MCP client, configured with an address and a token, was sent to a command that could
    not reach it. It is told instead to have a credential made with agent create and handed
    over, which works for any client.