Skip to content

Subroutine 0.10.0

Latest

Choose a tag to compare

@github-actions github-actions released this 05 Oct 09:04
· 99 commits to main since this release

This release changes the database schema, to 6c708db1582c.

Install it, then run subroutine db upgrade. That reports both versions, takes a
verified backup, migrates and checks the result - in that order. Stop the service
first if you are running one; expect it to be down for the length of the migration.

  • The subroutine plugin passes its token field as SUBROUTINE_PLUGIN_TOKEN alone. It
    passed it as SUBROUTINE_TOKEN too, for programs older than 0.9.9, and its pin admits none of
    them from this release.
  • An agent's API tool cannot make a calendar feed or give one a new URL, either of which
    answered with a feed's address - a bearer URL with its owner's whole sight - into the agent's
    context. And a route refused because it answers with a credential says so, where every refusal
    said the act could not be undone and the command line would ask first.
  • Half a character in a link type, a tag name, a role, an account name, a scope or a search is
    refused, naming the field
    , where it was a 500 over HTTP, a codec error to an agent and a crash
    report in the terminal. Wherever else one reaches the database it is refused rather than
    reported as a fault.
  • A link whose other end you cannot see is not yours to remove. A member could remove a
    link to an item moved into a private project they were not in, and its owner's item lost
    what blocked it. It is refused as a link that is not there, as their list of links already
    leaves it out.
  • An agent acting as the terminal's account cannot sign anybody else out everywhere. Named
    in local_user, it could sign a superuser out, which the same agent presenting a credential
    is refused. A person at the terminal still can.
  • The conventions an agent reads give a filter that does list every document of a kind,
    whatever its status: the one they gave listed open documents only, so a superseded design was
    left out. And the agents' project list says its summaries were left out, rather than cut,
    when none of them would fit.
  • Leaving an item while a change to it is on its way stays left. Completing or saving an
    item and going elsewhere before it answered brought the item back. Back, Forward or a reload
    onto an item keeps the arrangement it was opened from, so All items returns to the board or
    the list rather than the agenda, and the list behind an item shows a save made on its page
    straight away rather than at the next check for changes.
  • Two backups taken in the same second both succeed, under names a second apart. One of
    the pair failed.
  • A PostgreSQL address setting a server option backs up and restores. One carrying a
    space in its query - options=-c%20jit%3Doff, how libpq sets a setting per connection - served
    every ordinary command, and every backup, upgrade and restore failed on it.
  • Crash reports are owner-only and carry no value a database statement was given, which
    could include the hash a credential is looked up by. And a configuration file being rewritten
    is made owner-only before the new text goes in, not after.
  • db copy into SQLite no longer writes through files others can read. The new database
    was owner-only, but its write-ahead log and shared memory were made before it was, at the
    default mode, and every copied row went through them.
  • Leaving an item while it loads leaves it behind. Going home, to another workspace or
    project, or Back while an item was still loading drew it over the page you went to, and Back
    then wrote its address over the one you had stepped to. And choosing a project from an open
    item closes the item, where it stayed drawn with no list behind it.
  • The browser no longer draws the project you just left. A list or an agenda refreshed by
    something that started before you moved - the background check for changes, or adding an item
    • could draw the old project's rows or agenda under the new one's address, and on a quiet
      workspace they stayed until the next change.
  • A workspace given to -w by its id takes the checkout's file naming it by name. The two
    were compared as written, so the file was ignored and the work went to the Inbox.
  • The agent tools name a project by its key, not its id. With a credential that may not list
    projects, the conventions said what they were narrowed to by the project's id, and a checkout
    whose file carries only ids said a write had gone in that id; both name the project now.
  • A repeat counted from when it is done keeps its start's time beside a whole-day
    deadline.
    A weekly one starting Monday at 09:00 and due Friday, finished at 11:17, started
    next on Sunday at 20:17; it starts on Monday at 09:00 again.
  • Capture reads a repeat in brackets, and says when it leaves one on several days. Water
    the plants (every day)
    kept the repeat in its title with nothing said, and every day.) was
    refused as a phrase it did not know; both repeat daily now. A repeat on several days is said
    to be left as written wherever it is in the line, where words after it kept it quiet.
  • A repeat is refused in words that fit what is wrong. A phrase naming the 32nd of the month
    was told to send a rule that is refused for the 32nd; a repeat holding a C1 control character
    or a line separator was read as though it held a space and stored as sent; a frequency or a
    weekday written in other letters was told how a number is written; and a rule with a space
    after a ; was answered in the words of the library that reads it - it is read now. Refusals
    also put an before a word that needs one, and no longer write A A view's name.
  • A repeat's new rule is asked about the occurrence already made. A rule ending before that
    occurrence was accepted when any date between came after now, and the series ended there
    without a word; a series counted from when it is done was checked along a grid it does not
    follow; and a date sent with a new rule was checked on the date it replaced. Each is refused
    now, and a rule naming no date at all says so rather than that its dates have passed.
  • Clearing a repeat's deadline from now on asks whether the series is left a date. An
    occurrence given a start of its own, then cleared of its deadline for every one from now on,
    left the series with neither, and every completion after it was refused. It is refused instead.
  • A repeat started again is given its next occurrence when it has none open. One stopped
    after its last occurrence was finished, then given a new rule, said it repeated and nothing ever
    came round. A rule with no date left to give is refused instead.
  • Changing how often something repeats keeps what it is counted from. A new rule sent
    without saying whether the series counts from its schedule or from when the last one was done
    • by the agent tools, which have no way to say it, or by update --repeat without
      --repeat-from - turned a series counted from completion into one counted from the schedule.
      Leaving it out now leaves it as it was.
  • What privacy cannot hide about a name is written down. A project's key is one among the
    projects beside it and a saved view's name one per workspace, so making either with a name
    already taken is refused, naming it, even when what holds it is private and out of sight.
    Privacy keeps such a name off every list but cannot make it a secret, and the API's own
    descriptions, subroutine explain views, explain connecting and the connecting guide now
    say so.
  • Opening a sign-in link asks before it signs a browser in. A browser signed in as nobody
    now gets the page a browser signed in as somebody else already got: it names the account the
    link is for, and only its button spends the link. So a link handed to somebody no longer puts
    them in that account unseen, and a chat app's preview or a mail scanner that fetches the
    address leaves it usable. A browser already signed in as that account is signed in again at
    once.
  • A lost database is not made again, empty, by the next command. With the database file
    gone and its folder still there, every command made an empty, world-readable file and said to
    run subroutine init; it now says no instance has been set up here. A restore over a lost
    database restores without asking, where it made the file itself, refused to back it up and
    asked whether to go on.
  • The change feed refuses a period only for events you could have seen. A reader who
    cannot see a private project was refused for a period in which only that project's events had
    moved to the archive, a refusal they could never satisfy, telling them something hidden had
    happened then.
  • Walking the change feed back reads every event it still holds, and then ends. Once
    anything had been archived, every page after the first was refused, though what it would
    answer was all still there, and a client fetching several pages was refused where one reading
    the database directly was answered. Asking past the end is refused, naming the journal, newest
    first or not; an oldest-first walk past it answered nothing, as though nothing had happened.
  • Bringing a rule that binds the whole workspace into force takes what marking it takes, as
    taking one out of force already did: setting it back to a status in force, making it a type
    that binds, restoring it from the trash, and restoring, making public or moving out from under
    a private project the project that holds it. Any contributor could put a retired rule back,
    rewritten, into every agent's conventions.
  • On the night the clocks go forward, a repeating item's dates stay in order. Where the
    date it repeats on fell in the skipped hour, the hour was carried into every other date, so a
    start could land after its deadline and an event end before it started. A date whose time does
    not exist that night now keeps its distance from the date the item repeats on.
  • Only a project's owner, or a workspace administrator, decides who owns it and who can see
    it
    : changing its owner, making it private, and moving it under a private project. A member
    shared into a private project could make themselves its owner and then remove the owner, and
    any member could move somebody else's project under a private one of their own, where its
    owner could no longer see it and no administrator's listing showed it.
  • A calendar feed stops answering when its owner leaves the workspace, and when the person
    an agent answers to is deactivated. A feed's address went on serving everything its owner
    could see, private projects included, after they were taken out. Added back, they find it
    answering again, with what they can see then.
  • A .subroutine file is read only when it belongs to you or to root, much as git refuses
    a repository another account owns, and through a link only when the link is yours or root's
    too. One anywhere above the working directory was read, so a /tmp/.subroutine chose the
    project for anything run under /tmp, among the projects its reader could see. One belonging
    to another account is passed over, and the terminal and the agent's tools say so, naming it;
    subroutine use --here will not write over one.
  • The plugins' skill names the seven routes subroutine_call_api will not reach, where it
    said three, and why the four that answer with a credential are among them, and says what an
    instance that archives old events answers a since from before them. It says the
    .subroutine file is read only where the subroutine plugin or subroutine mcp runs, and not
    through subroutine-remote.
  • The conventions an agent reads no longer advise an argument the listing refuses. They told
    it to call subroutine_list with a type, and now name filter={"type.eq": "decision"},
    which finds drafts too.
  • In the browser, an item that is slow to open no longer replaces one opened after it, and
    closing an item reached by its address goes back to its project's list rather than to the
    agenda.
  • Creating something too deep is told to file it somewhere shallower, rather than to move
    what was never moved.
  • Saving a repeating item in the browser no longer fails over its repeat. The repeat is
    sent with every save, so one stored before the stricter checks of 0.9.13 refused the whole save,
    title and all; and every save moved the series' version, so a client holding it was told
    somebody else had changed it. A repeat sent back unchanged is now no change.
  • A repeat that can never come round is refused at once, saying so. The 1st of every
    month, when it is the second Monday
    , and every seventh day on a Monday from a Tuesday, were
    walked to the year 9999 before anything said they had no dates, and then refused for dates
    that had passed. A repeat written with a number too long to read is refused rather than
    answered with an error. A repeat holding a control character, or
    a number written in digits other than 0 to 9, is refused as other text is; and the 5th
    Monday
    no longer reads back as the 5 Monday.
  • A repeat at the end of a sentence is read. Water the plants every day. set no repeat
    and said every day. was not a repeat it understood, suggesting every day; so did every 14
    days!
    and every sunday?. The mark that ends the sentence stays in the title.
  • subroutine mcp given two different workspaces, or two different connections, tells the
    agent's client why
    , rather than stopping before it could answer, with the reason on standard
    error where a client does not show it.
  • An email address too long once lowercased is refused by name. Some capital letters become
    two when lowered, so an address that fitted was stored over-long, or answered with a server
    error on PostgreSQL.
  • An agent named as the local user is refused what it is refused over the network. The
    terminal's exemption is for a person holding the database; an agent named there issued a
    credential for a person, which an agent may not.
  • Only a person makes an owner of a workspace whose owners can no longer act. An agent that
    administers the workspace could make itself its owner with nobody else involved.
  • Moving a repeating item's day from now on keeps its time, whoever moves it. An all-day
    occurrence of a timed series, moved a day by somebody in another time zone, moved the whole
    series by their offset - a London 10:00 became 2am from Tokyo - and gave it their zone. The
    series now moves by the day and keeps its own time and zone.
  • A repeat cannot be added to finished work. It made a series that never came round while
    the task still said it repeated. It is refused, naming the status: reopen the task first, or
    file the next one with the repeat.
  • A repeating item keeps its times across a change of the clocks. Where its start and its
    deadline fell either side of one, every later start was an hour out for good, and an all-day
    start landed at 11pm the day before. And a series repeating from when it was done no longer
    gives an all-day deadline the time it was finished, which made it overdue that afternoon.
  • Clearing a repeating series' own date is refused, whichever occurrence the edit is for.
    Cleared for that one occurrence it was accepted, and finishing the occurrence was then refused
    for want of a date it already had.
  • A repeat whose dates have all passed is refused when it is made or changed. One running
    since January took an end date last week, or a count long since reached, and the next time it
    was finished the series simply ended; one made with every date behind it handed back an
    overdue item and nothing after. A repeat now has to name a date still to come.
  • Half a character in a status, a type, an assignee, a project or an @name is refused by
    name.
    Text was refused that way already; a name that is looked up reached the database as it
    was, and the answer was a server error, or a crash at the command line when an argument held a
    byte that is not text.
  • A listing's cursor works only in the workspace it came from. Passed to the same listing
    in another workspace, it carried on there from where it had stopped: a task listing answered
    with no rows and said there were no more, and nothing said anything was wrong. It is now
    refused, as a cursor from a different listing already was; ask for the first page again
    without it. A cursor issued before this upgrade is refused once in the same way.
  • Listing tasks on PostgreSQL no longer spends seconds preparing a query that takes
    milliseconds.
    PostgreSQL compiled the checks every task listing makes for what is ready
    before running them, having misjudged how much work they were: a page of eight took about
    two seconds on a workspace of a few thousand tasks, and a page of ready work about eight -
    past the command line's five-second wait, so subroutine list --ready failed every time.
    Subroutine now turns that compiling off on its own connections, and the same pages take a
    tenth and a quarter of a second.
  • The agent's project listing answers in a workspace where no project is described. Past the
    length one answer is kept to, it answered with an error, max() iterable argument is empty;
    and where even the tree without its summaries was too long, it said the summaries had been cut
    so the list fits. It now lists every project and says the list is longer than one answer is
    kept to.
  • An agent's credential that may not list projects writes from a checkout marked for somewhere
    else.
    In a checkout whose .subroutine names another workspace or instance, every write such
    a credential made - add and document create, and subroutine_add and subroutine_document
    • was refused there is no project here, with advice to make one it could not make, and
      subroutine://conventions answered an error. The marker is now ignored, and said to be, as it
      always was for a credential that can list projects. A project an old marker or the agent's
      address names, which the credential cannot find, is also ignored with a note rather than
      refused.
  • A PostgreSQL restore that is stopped part way leaves nothing hidden. Stopped before its
    backup loaded, it left the database empty and its data in a schema nothing named, and every
    command then advised subroutine init, which made an empty-looking instance beside it; later
    backups carried that schema, and restoring one failed. Now every command that reports on the
    database names the schema and says how to put it back or drop it, init and db migrate
    refuse to build beside it, doctor reports one wherever it is, backups leave it out and say
    so, and db restore refuses to start until it is dealt with, with an error code of its own,
    restore_unfinished. A restore that cannot put the old schema back says where the data is,
    and one that loaded and could not drop what it set aside says it finished, naming the schema.
  • A backup stopped on its way to the backup folder is never taken for a real one. A copy
    interrupted part way - Ctrl-C, systemctl stop, the out-of-memory killer - left a short file
    under a backup's name: listed as a routine backup, counted by --keep, which could delete a
    good backup to keep it, and named by doctor as the newest. A copy is now marked unfinished
    beside it until it has been proved, a marked copy is never listed, pruned or restored, and
    doctor, db backups and the listing over HTTP name it, with the command that removes it.
  • Taking a backup into a folder the server may not search is refused by name, as listing that
    folder already was, rather than failing as an unexpected error - a 500 over HTTP and a crash
    report in the terminal.
  • A backup is readable by its owner alone from its first byte. The copy staged in the data
    directory, the backup itself and the note beside it were each made readable by every account
    on the machine and tightened only afterwards, so the whole database - password and token
    hashes included - could be read while a backup was taken, and for good if it was stopped part
    way. A restore's copy lay beside the database the same way. The staging folder is now its
    owner's alone, and a take clears away what a stopped one left there after a day.
  • The plugins' skill corrects what it said about missing tools and the desktop apps, and teaches
    two things it left out.
    When the subroutine plugin's tools are missing, uv is the only thing
    to install and claude mcp get plugin:subroutine:tools says why the server did not start; it
    no longer asks for uv tool install or a configured path, neither of which helps. Neither
    plugin claims a desktop app works, since none has been tried. A session reached by address can
    name its project on the address, beside the workspace, and the skill gives the order a write's
    project is found in. A decision is a document in the project it governs, even one taken in
    passing. Refresh the plugin to read it: claude plugin marketplace update subroutine, then
    claude plugin update subroutine@subroutine.
  • Each version of a long description or body is kept once. Every edit recorded the whole
    text before and after it, so a document revised twenty times held forty copies of itself in
    the history, where it now holds each of its twenty-one versions once. What the change feed,
    an item's history and an export report is unchanged: the whole text, every time.
  • Events can be kept in the change feed for a set number of days, and nothing is deleted.
    Set events_retention_days and older events move to an archive, which the journal, each item's
    history, revised N times, the touched_at and touched_by filters and an export all still
    read. A served instance moves them once a day while it is in use, and subroutine db archive
    does it on demand. A client resuming the change feed from before them is answered
    410 cursor_expired, which names where to carry on, and the browser starts again from the
    newest by itself. A read of the feed for a period reaching back past them, or a walk back
    with before that has read every event the feed still holds, is answered with the new error
    code 410 period_archived, which names the journal.
    Unset, which is the default, every event stays in the feed as before.
  • user create and user add say that what is filed in the workspace without naming a
    project goes to its Inbox, which everybody in it can see
    , and the README and the hosting
    guide name the two ways to a list of one's own: a private project, or a workspace of one's own.
  • subroutine explain handing-back names subroutine claim, beside the release it
    already named. Both are hidden from --help until a second connection is configured, and no
    topic mentioned claiming, so an agent with a shell had nothing in the program that did.
  • An agent issues credentials and sign-in links only for itself or for another agent. One
    holding instance:user_create could issue a person a credential and then act as them, so
    every rule that keeps an act to a person was two calls away from it. Issuing either for a
    person is now refused to an agent by name, saying who may do it instead; a person issues
    for anybody their permissions allow, as before.
  • Listing the backups answers backup_failed when their folder cannot be made or read, as
    taking one does. GET /v1/admin/backups answered service_unavailable, which says the
    instance cannot serve anything yet, for a folder it could not make, and an unexpected error
    for one it could not read, which subroutine db backups met too.
  • A task created already finished says when: one created with a done or cancelled
    status, through status on POST /v1/tasks, was stored with no completed_at, so it
    stayed on the list of open work and went on blocking whatever it blocked. A repeat cannot be
    created finished, and is refused naming status: it was created open, and the status given
    was lost.
  • subroutine://conventions reaches the projects above yours and every rule that binds the
    whole workspace
    : an agent in a project inside another is shown the rules filed above it as
    well as its own, and a document marked to bind the whole workspace is listed wherever the
    reader stands, saying so beside its project. The list closes with how many in force elsewhere
    were left out, including when nothing is listed for the reader, where it used to say nothing
    was in force at all.
  • A document can bind the whole workspace: --binds workspace on document create and
    document edit, binds on subroutine_document and on POST and PATCH /v1/documents, and
    binds.eq=workspace on the listing. Every document binds its own project until it is marked.
    Marking one, setting it back, writing one marked and superseding a marked one each take
    project:write, from a credential that reaches every project, and a document superseding a
    marked one is marked too. So does taking a marked one out of force by another door - a status
    out of force, a type that binds nobody, moving or deleting it or a document holding it, and
    making private, moving under a private project or deleting the project it is in.
    subroutine show and the document's page say when one binds the whole workspace.
  • A repeat on several days is left as written, and said so: Gym every monday and
    thursday
    , every monday, wednesday and friday, every other monday and thursday, every 2
    weeks on monday and thursday
    , every month on the 1st and 15th, on the 1st and 15th of every
    month
    and on the 1st and 3rd monday of every month keep their words in the title, set
    nothing, and the note says a repeat is read on one day. The last two were read as every month,
    with of ending the title, and the item was then refused, and every 2 weeks on monday and
    thursday
    was filed as every 2 weeks and thursday, starting on the Monday. Given to --repeat
    or the API, such a phrase is refused naming the rule that does repeat on those days, such as
    FREQ=WEEKLY;BYDAY=MO,TH.
  • document create and document edit read the text from standard input only for
    --body -
    : subroutine document create "Review findings" --body - < notes.md. On document create, text piped in without it is ignored, with a warning, only beside --body "...", and
    refused otherwise before anything is written; on document edit it is ignored, with a
    warning, when a field is named, and refused when nothing else is asked. It was read whenever a
    pipe was attached: a loop over lines,
    or a hook reading its own input, gave the first document every line after it, and an edit
    replaced a document's text. --body '' now means no text.
  • user deactivate names every workspace it would leave with nobody who can administer
    it
    , before you agree and again afterwards, each with the command that makes somebody its
    administrator: subroutine user add <you> --role admin -w <workspace>. Deactivating such a
    person is still allowed, as it is for a private project's last member. instance workspaces
    marks such a workspace, and GET /v1/instance/unadministered-workspaces answers which they
    are, or with leaving, which a departure would leave so.
  • An administrator of the installation can make themselves a workspace's administrator from a
    terminal on this machine's own database
    , as they could over a connection. Adding, regrading
    and removing members, listing them and deleting the workspace were refused there with a hint
    to join it first, using the command that had just been refused.
  • The Inbox cannot be made private, or moved under another project, as it cannot be
    deleted. Everything filed in a workspace without a project goes there, so a private Inbox
    refused every other member's capture, saying they had named a project they could not see.
  • A credential narrowed to instance:workspace_create founds a workspace, as the
    permission's description has always said it may. It was refused, first for adding its own
    account as the owner and then for making the Inbox, which are part of founding and now ask
    nothing more. Nothing else widens: it may not add a member or file a task in what it founded
    unless it also carries the permission for that.
  • A backup the server could not take or write says backup_failed, at 503, a new error
    code. Most such failures said malformed_request, at 400, which tells a caller to fix a request
    that was read perfectly well, and the rest service_unavailable, which says the instance
    cannot serve anything yet. It reaches an agent taking a backup over the API before something
    bulk; the terminal's db backup says the same sentences as before.
  • A claim refused because somebody else holds the task, or because it is finished, says
    not_claimable
    , a new error code. It said duplicate_key, which is published as Already
    exists
    , so an agent branching on the code read the task as a name already taken.
  • Nesting something past the depth limit is refused as too_deep, a new error code, where it
    was cycle_detected, which says the change would make something its own ancestor. It covers
    making a project, a task or a document deeper than max_hierarchy_depth allows, and moving
    one there. A client matching cycle_detected for depth should match too_deep; a real cycle
    is still cycle_detected.
  • An agent tool call whose arguments is not an object is refused as invalid params, as a
    request whose params is not one already was. An empty list, an empty string, 0 and false
    ran the tool as though no arguments had been sent. Leaving arguments out, or sending null,
    still means none.
  • serve says when it and the rest of its machine would decide OSC differently. Started with
    --host, or with its address only in the service's environment, a server could send nothing
    while a terminal on the same machine, reading config.toml, went on sending. It now says so as
    it starts, and the workspace settings page says this server sends nothing rather than this
    installation
    .
  • A credential narrowed to some projects cannot make a project at the top level, nor move one
    there unless it names that project. It could make one it then could not read, change or
    delete, while everybody in the workspace saw it. Inside a project it may change, it makes and
    moves projects as before, and the refusal says so.
  • A tag only private work uses is out of sight to anybody outside it. It was listed to
    everybody in the workspace - in the tag list, /v1/meta and an export - and somebody outside
    the project could delete it, or rename it without first using its name on their own work. A
    tag you can see is still the workspace's: renaming it reaches every item that carries it, and
    deleting it takes it off everything you can read and leaves it on work you cannot. Using a
    hidden tag's name on your own work brings it, and what it says it means, into sight. Hiding
    hands out no names, but cannot make one secret: creating a tag with a name already taken still
    says so.
  • What is yours to act on is tasks only: list --to-act-on and to_act_on=true in the agent
    tools no longer answer with every open document in the workspace, and neither does the agent
    tools' assignee, as the terminal's --assignee already did not. A document has no assignee
    and nobody claims one; a sign-off is a task linked to it.
  • Nothing reaches an item in the trash but its restore. Filing something under it, moving
    something under it, recording a check on it and linking to it or from it are refused, saying
    it is in the trash, as editing, finishing, claiming and commenting on it already were. A link
    made before it was deleted stays, and is still answered when it is sent again.
  • Deleting a project, a task or a document takes everything beneath it out of sight with it,
    and restoring it brings everything back as it was. A sub-project's work, and a task's or a
    document's own sub-items, were still listed, offered as ready and holding up other work while
    what they sat under was in the trash. Only what you deleted is in the trash. Asked for by
    number, something out of sight says what it is beneath, where it used to say there was no
    such item, and it cannot be restored on its own until that comes back.
  • Who is shared into a project says which project by its id, beside its key, since a key is
    unique only among one parent project's children.
  • api_version says what it promises: it names the contract the API's base path names, so it
    reads 1.0 for as long as that path is /v1 and becomes 2.0 only with a /v2. Which
    additions an instance has is instance_version, beside it in /v1/meta and /v1/me.
  • A status and an item type say what kind of item they are for, task, project or
    document, and an item type says where it stands in its list, as a status already does.
  • subroutine export <folder> takes away your work on one connection, as files to keep. Each
    workspace becomes a folder with one file of JSON lines per kind of thing - items, documents,
    comments, links, changes, tags, statuses, saved views, accounts, the workspace's own settings,
    who belongs to it and to each project, and the rest - and a manifest.json saying what is in
    it, what an export never holds, and which version wrote it.
    Done, archived and deleted items are included, and so is the history of changes; nothing you
    could not already read is, and no password, token or sign-in link ever is. It reads one
    connection - the one a write would go to, or the one -c names - so you can leave somebody
    else's instance with your work too, where it runs this release or later. Beside the files is a
    markdown/ folder you can read: a page for each item and document, foldered by project, with
    its comments under it. A workspace or project name no instance would send stops the export,
    rather than writing where it points.
  • GET /v1/export/<kind> answers everything of one kind your credential can read, a page at
    a time: the workspace, projects, tasks, documents, comments, links, verifications, events,
    tags, statuses, item types, link types, saved views, users, members and project members.
    Done, archived and deleted items are included,
    and each is the object the API returns for it everywhere else. A link is given with both its
    ends, and now also says what its type is, when it was made and who made it, wherever a listing
    includes links.
  • A link says when it was made and who made it, a project says who made it and who last
    changed it, and a status says its position.
    All three were stored and reported by nothing, so
    a status's position could be set and never read back. Each is a new field in the API's
    answers, beside the ones a task already has.
  • subroutine -c work mcp serves the connection it names, as mcp --connection work does. It
    served the default connection, so an agent's work went to another instance without a word. Two
    different names, one before mcp and one after it, are refused.
  • document edit with nothing named no longer waits for ever under an agent's shell. With
    nothing piped in either, it says there is nothing to change.
  • db copy carries a workspace where two projects share a key, such as a root web beside
    shop/web, or clienta/web beside clientb/web. It failed on the second and left the target
    with no projects.
  • A line with two repeats keeps both in its title, and says a line takes one. Gym every monday
    every friday
    repeated on Mondays with every friday gone and nothing said, and every monday
    and every friday
    lost the repeat and its second day together.
  • The browser no longer draws one project's list on another's page. A list still loading when
    the reader moved on replaced the rows of the page they had moved to, and a refusal arriving late
    said the first project had gone and showed the whole workspace there.
  • A credential that may write only in some projects makes and moves projects only into them.
    One writing only in web could make ops/sub and move web under ops, while it was refused
    a task in ops.
  • A name or a filter holding a character no text can hold is refused in one sentence on this
    machine's own database
    , as it is over a connection. It was a missing account on SQLite, and the
    database driver's own error on PostgreSQL.
  • Three values that answered 500 are refused by name: half of a character in any text, a tag or
    a username that outgrows its limit once written in lower case, as İ does, and an estimate with
    more digits than a number can be read with.
  • Configuration and checkout markers that are slightly off are said rather than crashed on. An
    address with an unclosed [ is refused by name, a config.toml that is not UTF-8 says where
    its first stray byte is, subroutine connections leaves an address's password out, a marker's
    workspace is matched as workspace names are stored, a marker written before workspace ids files
    by its project again, and a bare use names the marker when nothing is chosen.
  • Repeats: the last occurrence of a series an older build put in the trash can be finished;
    deleting a stopped series says it is kept as the record of what it ran; clearing the only date of
    a repeat that needs one is refused, as making one is; a whole-day deadline series ends in a
    calendar feed on the last day it falls on; and a repeat's description names every month in
    full, says once and twice, and names the month wherever the rule does.
  • Smaller permission faults: a credential that may change projects names one over a
    connection without being allowed to list them, as it could locally; an owner refused by their
    own token is told it is the token; a name two projects share is not listed to a credential that
    may not list projects; the compact token row says where a credential is pinned and what it
    reaches; and an agent whose person has left no longer counts as the administrator left behind.
  • The agent's tools: the project list counts its titles against its bound, a marked write
    asks who the caller is once rather than twice, a checkout marked for another instance is said as
    that without quoting an id, a workspace put in the trash by its name in capitals is restored by
    it, and an administrator names a workspace by its id however it is written. Locally, a
    document's project given as nothing is left alone, as it is over a connection.
  • In the browser, a sub-task added from a form whose projects arrived late keeps its parent's
    project
    , as one added from any other form does. The form sent the project it showed once the
    projects arrived, and was refused.
  • Smaller wording faults: a calendar made or reset over a connection names the connection in
    the command it gives, token create gives the whole rule for the variable a client reads,
    setup claude no longer says a session gives back what it holds where the hook cannot run, the
    agent's project tool says a key can be renamed, and the guides no longer promise a calendar is
    read every fifteen minutes or that subroutine connections names workspaces.
  • Events are left out of the list, the board and the agents' listing, and counted. A birthday
    or a payday happens to you rather than being done, so subroutine list, subroutine_list and
    the browser's list and board leave them out and say how many: 1 event not listed.
    'subroutine list --events' to include it.
    --events, naming an event type or
    type_category:occasion,
    a search, and the trash bring them back. GET /v1/tasks takes events=include, exclude or
    only, still include unless asked, and filters by type_category.