Repository navigation
Subroutine 0.9.9
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 planand the agent tools
read a start and an end the same way, soplan 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 --untildoes. 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 aTis read with its offset. With a space in place of theT, 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
Tto 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,
throughincludesand 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.
Movingblocksto counting made every task that blocked something read as including work, and
movingincludesto 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
includesunder 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/blogwhenacmeis renamed. -
subroutine view runwith--connectionreads 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:meoranswers_to:meis marked as drawing each reader their
own work, as one sayingassignee:mealways 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.gtewas told to useref.gte,ref.nethat a ref is
stored to the microsecond, andcreated_at.isthatcreated_attakesis. A range is now
suggested only for a field that takes one, andison a field that always has a value says so. -
agent create --hereworks in a directory whose name a.gitignoreline 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 --heresays when the plugin's tools will not follow. It names the variable
after the connection a write goes to, and thesubroutineplugin 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 --hereno 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 todone,skip,plan,deferorupdate, anduser createwith
--browseror--terminalare 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 --jsonwith--browseror--terminalis 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.--jsongoes with neither now: a secret is shown once, to a person,
and not to a script. -
The
subroutineplugin passes its token field under a name of its own,
SUBROUTINE_PLUGIN_TOKEN. The field travelled asSUBROUTINE_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 asSUBROUTINE_TOKENas 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_whoamioffersagent create --hereonly where it can work: in Claude Code,
through thesubroutineplugin.--herewrites 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 withagent createand handed
over, which works for any client.