This is the record of an abcd-managed repository

abcdBetav0.16.2 · 2026-11-06

Development record

Unattended work runs on a named profile, one per way of paying

intentdraftsmajoritd-2611040344170206

Press Release

Unattended work in any abcd-managed repository runs on a profile: a separate login and bare settings for one way of paying, a subscription or a named API key, kept beside the others under abcd's home. Maya keeps three subscriptions of two agent tools, each in an account of its own, and two API keys. In each account they type one abcd command naming the tool, and for a key the key's name; abcd makes a directory under ~/.abcd.noindex/profiles/ with a memorable name from a themed list Maya can edit, writes that tool's settings there with abcd's own hooks wired in, and for a subscription hands them the tool's own login step to run. A key's profile needs no login, and abcd never sees a token. A registry they can read says which tool and which way of paying each name holds, and abcd ahoy says whether each profile is ready: logged in where a login is needed, carrying abcd's guard, rules loader and session names, and admitting only the tools on the allow-list. A worktree is where the files are; a profile is who pays and what an agent can reach; when Maya starts abcd drain --drive or any other unattended run, abcd pairs one of each per agent, choosing the account's subscription while both its usage windows stand below 95 per cent, then the key they named within its budget, never another account's subscription, and proves that tool's wall on the profile before it runs a stage. A session Maya starts by hand that sets work running off a profile is warned in a line they cannot miss, never refused, and their own attended sessions are untouched. "I used to keep a hand-made directory per login and a start script nobody else could read," said Maya, an autonomous-development practitioner. "Now a profile is a thing abcd knows: it makes it, checks it, picks it, and says plainly what it is, a separate login on my account, not a wall around the account."

Why This Matters

The subscription route of abcd drain --drive (itd-2610222215485265) rests on a dedicated configuration directory the person logs into once, and its spec (spc-2610230813348813) names no location for it, so the first live proof (dcn-2611031720003633, lab lab-261103171720-c0bdccf) chose a directory by hand and started it from a hand-written script that pinned abcd's hook to one versioned plugin path in one account (iss-2611032326573729). No abcd verb knows that directory: a session cannot find, create, pick or report it, and every account repeats the setup by hand.

The same evening's test (2026-11-03) found three things the directory alone does not give. A wall defined by denying connected services left built-in tools that reach the person's account in the coordinating session, so the wall has to name what a session may hold, not what it may not. A tool appeared in a session after its start, so a wall proved once at the start does not stay proved. And a profile that kept only the guard hook lost its session name and the rules loader, so none of the repository's rule domains reached the agents working there. The third attempt, on an allow-list of named tools, ran the implement and validate stages on a subscription with no API key and reached an open pull request, which is the evidence that the route works once the wall is an allow-list.

Nothing enforces the wall (iss-2611032327111678): the verbs that start unattended work accept a session holding the person's connected services and personal memory as readily as one on a profile, and the one exception made on 2026-11-03 (dcn-2611032348409091) had to be ruled by hand because no verb could tell the two apart. The product thinker ruled that watching is no control, since a person cannot interrupt a tool call as it runs (dcn-2611031722512037), so the wall is the control, and a control nothing checks is a request.

A person running abcd unattended on subscriptions, moving to a key when a window reaches 95 per cent and back when it resets (dcn-2611031615094092), needs several logins of several tools side by side, and the keys beside them, each one abcd can create, prove, pick and report. That is what a profile is: one per way of paying (dcn-2611041550129278).

What no record covered until the planning interview is the reading the switching rule turns on. abcd sees a subscription's windows only through the status-line payload (internal/core/statusline/payload.go, five_hour_pct and seven_day_pct), which the host runs on its own events; the subscription test of 2026-11-03 found the hand-made recorder appended only on a change, in whole percents, so a flat line could not tell no change from a status line not firing. Nothing reads a window at the moment a stage is handed out. The loop's one existing reaction to a limit is the rate-limit checkpoint (internal/core/implement/loop/ratelimit.go, itd-2609201925079472 criterion 8), which with the bundled pause at zero waits nothing (iss-2610100602595553), and only the claude runner recognises the response (iss-2610100913095172). The criteria below carry that half, folded in from a scratch draft of 2026-11-04 whose own decomposition routed it here rather than to a record of its own.

Mechanism

We expect a profile to keep an unattended run off the person's own setup, and to stay that way through a run, because each tool's login, settings and hooks live in a directory the tool itself treats as its whole home, and the tools a session on it may hold are named in one allow-list abcd re-reads before each stage, so what reaches the agent is what the list admits rather than whatever a deny list did not happen to name. The claim is shown wrong if a stage started on a profile, on a machine where the person's own instructions, memory, connected services, hooks and saved sessions are all present, holds a tool the list does not name or reaches any of those, in the live check abcd runs before the stage.

Scope Conditions

  • Holds for an agent tool whose command line can be pointed at a separate configuration directory and started with a named list of tools, and for which abcd has a runner: Claude Code and OpenCode today; Codex and Grok when their runners exist. Each tool is admitted by its own live proof, never by another's.
  • Holds on one operating-system account. A profile is a separate login and settings on that account, not a sandbox and not isolation: a stage's shell reads whatever the account can, the person's own configuration and the other profiles' logins included. This matters most where several providers' logins sit side by side. What the account itself cannot reach is the sandbox intent's work (itd-2610161621364075), a later and separate step.
  • Holds for both ways of paying: the subscription route, where the tool's own login is the credential, and the key route, where the profile holds no login and the named key (itd-2611011230226453) reaches that launch alone. A stage on the key route runs on a key profile with abcd's hooks on; the bare launch adr-2610222222326104 names gives way for stages (dcn-2611041550129278).
  • Holds where the tool reports its own usage windows; a profile whose tool reports none is chosen only when no reporting subscription is free (dcn-2611041550135566).
  • Holds where the host reports the subscription's usage windows to abcd, as the status-line payload does today; a repository the person has set to the key route never switches.
  • Holds on macOS and Linux, where ~/.abcd.noindex/ is abcd's home; there is no Windows target.
  • Holds for sessions a host reports enough about for abcd to tell a profile from the person's own session: the configuration directory in the environment, and the session id, working directory and permission mode in a hook's input; the session's tool list is shown to the model and to no hook, which is why a session off a profile is warned and not refused (dcn-2611041550129278).

Acceptance Criteria

  • Given a person with a subscription to a supported tool, when they run the profile-creating command naming the tool, then abcd makes a directory under ~/.abcd.noindex/profiles/ named with the next unused name from a list (abcd ships a neutral list of non-person words; a person may keep their own themed list in their machine configuration, and a repository file never holds one), writes that tool's settings there, bare, with abcd's guard, rules loader and session-name hooks wired to a path that survives a plugin upgrade, records the name, the tool and the date in a registry the person can read, and hands them the tool's own login step to run in their own shell. The name carries no provider and no account; abcd never performs the login, and never reads, stores or forwards the token.
  • Given a person with a key named in the credential store (itd-2611011230226453), when they run the profile-creating command naming the tool and the key's name, then abcd makes a key profile the same way, with no login step, records the key's name (never its value) in the registry beside the tool and the date, and a stage on it is handed the key for that launch alone with abcd's hooks on. Given a tool whose key spend the budget intent does not yet cover (the opencode runner today, so a provider such as OpenRouter reached through it), or a tool that cannot carry abcd's guard, when the creating command names it with a key, then the key profile is refused and names what is missing, since an accepted rule forbids spending on a key outside a cap (adr-2611011231015519); it is admitted once the budget covers that tool and the tool carries the guard.
  • Given a tool abcd has no runner for, when the creating command names it, then the create is refused and names the runner it lacks; nothing is written.
  • Given one or more profiles, when abcd ahoy reports them, then each shows its name, its tool, its creation date and its readiness: logged in (as the tool reports it, by state alone, never an account identifier), every abcd hook present and resolvable, the allow-list the profile starts with, the live proof's state for that tool version, and the usage window where the tool reports one. A gap is named with the step that closes it. Nothing it prints identifies the account behind a profile.
  • Given the allow-list of named tools, when abcd reads it, then it starts from the sensible default abcd ships, lets a repository file narrow it for that repository's runs and never widen it, lets only the person's own machine configuration widen it, and refuses an agent's change to either; built-in tools that reach the machine's other sessions are outside the default and admitted only by a setting the person turns on. When a stage is about to start on a profile, then abcd re-reads the list and checks what it can: the tool list it names itself when it starts the agent, which is the launch's own, and a tool outside the list stops the stage before it starts, naming the tool. A stage that would run inside a session the person started, whose tool set no hook is shown, gets a warning naming what abcd cannot check, never a refusal (dcn-2611041550129278). A session holding built-in tools that reach the person's account is not on a ready profile, whatever its connected-service settings say.
  • Given a tool with no live proof recorded for the version a profile holds, when that profile would first run a stage, then abcd proves the wall on it first: the person's own instructions, memory, connected services, hooks other than abcd's, and saved sessions are out of the agent's reach, the tool set is the allow-list, the guard refuses a harmless command it is meant to refuse, and no API key is in the environment. It records the proof with the tool's version, refuses the stage naming any wall that failed, and a version change voids the proof.
  • Given a tool that cannot carry abcd's guard (no hook surface, or a start mode that skips hooks), when a role would be handed to a profile of it, then no stage runs there and abcd names why; the role goes to another profile or is handed back.
  • Given several ready profiles, when abcd drain --drive or any other unattended start hands out a role, then it pairs the agent's worktree with a profile by the role's route and by window: the account's subscription profile while both of its windows stand below 95 per cent, and when either is at or above (another account's subscription is never taken, decision 20) the key profile of the key the person named for that repository's move off a subscription (itd-2611011230226453), within its budget, or a wait; a key at its cap follows the budget's at-cap setting, waiting by default and moving only to the second key the person named, never to any other key. The stage returns to a subscription profile when its window resets. The run record names the profile by its name for every launch.
  • Given a stage about to be handed out on a subscription profile, when abcd chooses, then it reads that subscription's windows as last reported, no older than a bound the person configures, and never takes a stale reading as current: with no fresh reading it records why and hands the stage to the next route the rule names. A profile whose tool reports no window has no reading, fresh or stale: it is passed over while any reporting subscription profile stands below the mark, chosen only when none does (decision 13), and a stage on it is recorded as run on an unmeasured window.
  • Given the coordinating session's own subscription is the route (dcn-2611031720012399), when either of its windows stands at or above 95 per cent, then no further stage is handed to a host sub-agent until a reading below the mark arrives; the stage goes to the key profile the person named for the move, within its budget, or waits when that key is at its cap and no second named key is set, and the run record says which window and which reading decided it. An agent already running when a window crosses the mark finishes its stage there (dcn-2611041550135566).
  • Given every subscription at or above the mark and every named key at its cap, when a stage is due, then the run waits for the first reset and says so; it never opens a third route (dcn-2611041550126639).
  • Given a subscription's hard limit met mid-stage (a rate-limit response from a runner, or a host sub-agent that reports one), when the loop sees it, then it waits for the reset the response names, independent of the run's pause (iss-2610100602595553), and a sub-agent's report reaches the loop through a verb (iss-2610100913095172).
  • Given any switch of route, when it is made, then the launch ledger entry (itd-2611031342011261) names the profile, the route and the reading that chose it, so the daily digest (itd-2611041549483696) can show how many stages each key carried and why.
  • Given a session that is not on a profile, when it starts unattended work (abcd mode autonomous, a build or drain run in autonomous mode, or a coordinator's start), then abcd warns so that the line cannot be missed, naming what abcd cannot check and, once the profile-creating command exists, that command, and never refuses (dcn-2611041550129278). A managed build or drain move whose away state can be read prints nothing; a first join warns in any mode; an unreadable away state warns. A terminal abcd drain --drive takes no line (dcn-2611050931219213).
  • Given any surface that names a profile (the registry, ahoy, a refusal, a command page, the docs), when it describes one, then it says it is a separate login and settings on one operating-system account, and that a stage's shell reads what the account can; it never calls a profile a sandbox or isolated.
  • Given the hand-written setup this replaces (a directory per account and a start script outside abcd), when this ships, then the drive's precondition that reads "the walled configuration directory has no login" reads the profile registry instead, the live wall proof of spc-2610230813348813's first step becomes the per-profile proof above, and the command pages name the profile store as the one home.

Open Questions

None open. The planning interview's rulings of 2026-11-04 are decisions 9 to 17 below; the two technical questions the interview did not reach are settled on the draft's proposal in decisions 18 and 19, each saying why no question was put.

Decisions

The product thinker's, on 2026-11-03, restated:

  1. Every session that coordinates unattended work starts on the wall itself; a stage run as a host sub-agent gets file and shell tools only; a stage that cannot run within that limit does not run (dcn-2611031722512037, refining dcn-2611031720012399). Read with decision 11: a coordinating session is walled where abcd starts it, and one the person starts off a profile is warned.
  2. Watching is no control: a person cannot interrupt a tool call as it runs, so a person's presence never makes an unwalled agent acceptable (dcn-2611031722512037).
  3. The dedicated directory's home is ~/.abcd.noindex/profiles/, one directory per agent subscription, named for what it is: a profile, a separate login and settings on one account, never a sandbox or an isolated environment (recorded in iss-2611032326573729's remedy).
  4. Each profile's name carries no provider or account, and a registry the person can read says what each holds (the same remedy). The random name this decision first gave is replaced by decision 15.
  5. Each tool's wall is proved on its own before that tool runs a stage; a tool that cannot carry abcd's guard does not run one (the same remedy).
  6. Sessions use the person's subscriptions first and move to a key when a window reaches 95 per cent, returning once it resets (dcn-2611031615094092).
  7. The first live proof runs on the account the drive will run in, after the person logs the directory in once (dcn-2611031720003633).
  8. Real isolation follows as its own step (a separate operating-system user, a container, or the host's own sandbox per directory); it is not this intent (the same remedy; itd-2610161621364075 is the planned sandbox).

The product thinker's, at the planning interview of 2026-11-04, restated:

  1. The key route runs on a profile too (dcn-2611041550129278). Every agent abcd starts unattended carries the guard whichever way it is paid for: a key-route stage runs on a key profile with hooks on, and the bare launch adr-2610222222326104 names for the key route gives way for stages. This answers the former second open question with its first option.
  2. One profile per way of paying (dcn-2611041550129278). A subscription or a named key each gets one profile, its own login and its own bare settings; a worktree is where the files are, a profile is who pays and what an agent can reach, and abcd pairs one of each per agent. A subscription's profile needs one login by the person; a key's needs none. The title and the scope widen to say so.
  3. Warn, never refuse (dcn-2611041550129278). A session the person starts that runs work unattended off a profile is warned in a line that cannot be missed and is never refused; the former first open question takes its second option.
  4. Either window (dcn-2611041550135566). A tool that reports a short window and a long one is passed over when either stands at or above 95 per cent; the former third open question's first half takes its second option.
  5. A tool that reports no window is used unattended only when no reporting subscription is free (dcn-2611041550135566); the same question's second half takes its first option.
  6. Reaching the machine's other sessions is off by default (dcn-2611041550129278): a built-in tool that reaches other local sessions is outside the shipped allow-list, and a setting the person turns on admits it; the former fourth open question takes its first option, made configurable.
  7. Memorable names from a themed list (dcn-2611041550129278). A profile takes a readable name from a list, never a random string, so that it is easy to read and say. abcd ships a neutral list of non-person words; a themed list, a television series' characters for one, is the person's own, kept in their machine configuration and never bundled. A name is fixed at creation and retired for good once used, so an old ledger line can never point at a later subscription: the ledger records an immutable profile id beside the name, and displays say profile before the name so it cannot read as a session. A name does not say which subscription a profile holds; the person learns that by the tool's own status, and the registry records the name, the tool and the date.
  8. A shipped default allow-list, configured per repository within one bound (dcn-2611041550129278). abcd ships a sensible default; a repository file may narrow it and never widen it; only the person's own machine configuration may widen it; an agent can never widen it. The former sixth open question takes its second option, bounded by the draft's rule that an agent's change cannot reach it.
  9. A stage in flight when a window crosses the mark finishes there (dcn-2611041550135566); no stage is checkpointed for the crossing.

Settled on the draft's proposal, no question put, since each is a technical choice with one defensible answer on the record and the standing stance that abcd ships a sensible default the person configures (dcn-2611041550129278):

  1. Where the window reading comes from when no status line fires. The coordinating session writes a timestamped heartbeat of its windows at each step, which the hand-out reads; the runner's event stream (rate_limit_event) is the second source for a launch that has one. No question was put because the heartbeat is the only source that covers a host-routed stage with no stream, which is the case the subscription test ran.
  2. The staleness bound's default. The status line's own refresh cadence, in minutes, configurable by the person. No question was put because the bound is a default a person tunes, not a trade-off.
  3. One subscription per account for the first run (dcn-2611041608057544). Each subscription belongs to one operating-system account, so an account holds one subscription profile beside its key profiles; at 95 per cent of a window it moves to the key the person named within its budget, or waits for the reset, and never onto another account's subscription. To be revisited after the first run.

Evidence

  • 2026-11-03, the subscription test's first attempt: under a wall that denied connected services, the coordinating session still held built-in tools that reach the person's account, and stopped before any stage; the deny-list wall is why the allow-list is the rule above.
  • 2026-11-03, the second attempt: all six wall checks passed at the start, then a tool outside the allow-list appeared in the session within two minutes, and the session stopped; the re-read before each stage is why.
  • 2026-11-03 to 2026-11-04, the third attempt: on an allow-list of named tools, with no API key in the environment, the implement stage and both validate reviewers ran as file-and-shell sub-agents on a subscription, the lane's full check passed, and the branch reached an open, unarmed pull request; the intent audit and the arming did not run. The tool's usage recorder appended only on a change, so the per-stage cost went unmeasured; the sub-agents' token counts were the only per-stage figure.
  • 2026-11-03, the setup's gaps: the hook was pinned to one versioned plugin path in one account; only the guard hook was wired, so the session had no name and the rules loader injected no domain; the guard's canary had to be a command the guard refuses, since a harmless one proves nothing.
  • 2026-11-05, the warning criterion (the one opening "Given a session that is not on a profile") is delivered in part, for abcd mode autonomous, a build or drain run while the away mode holds, and a coordinator's start, read as abcd implement join --role first, the one act by which a session says it coordinates a run (iss-2611032327111678, resolved). It names what abcd cannot check rather than what the session holds, and no step, since no abcd command starts a session on a profile yet. What remains owed is in dcn-2611050931229356. The rest of this draft stands.

Decomposition

Hand-run four-piece table, 2026-11-04, from the product thinker's rulings of 2026-11-03 and the subscription test's three attempts. Routing proposed, for the product thinker to confirm; parts routed elsewhere are named here and not filed.

Part Kind Home
profiles under ~/.abcd.noindex/profiles/, one per way of paying, readable names from a neutral or personal list, the readable registry, one creating command with the person's own login step where one is needed, ahoy readiness, the per-tool live proof, the pairing of worktree and profile per agent by route and window, the window reading at hand-out, the wait when every route is out, the ledger line per switch, abcd's hooks wired in, and the warning for a session not on one capability this intent (the switching half folded in from the scratch draft of 2026-11-04, whose decomposition routed it here; routing confirmed, dcn-2611041550129278)
an agent abcd starts unattended holds only the tools one allow-list names, re-read before each stage, which a repository may narrow and only the person may widen; a tool that cannot carry abcd's guard runs no stage, the key route included; a profile is a login boundary, never an isolation boundary trust rule an ADR owed, extending the wall clause of adr-2610222222326104 from a dedicated configuration directory with deny switches to a profile with an allow-list of named tools, and retiring its bare launch for stages (dcn-2611041550129278), and a brief invariant when it is accepted; not filed here
a key at its cap never falls to a subscription, and a subscription at its mark never opens a third route trust rule one line in itd-2611011230226453's decisions (dcn-2611041550126639); no ADR
a rate limit waits on its own, and every route can report one plumbing iss-2610100602595553 and iss-2610100913095172, already open; the brief's runner chapter
a wall is defined by what it admits, never by what it denies stance a candidate principle, or a bound in an existing one, for the product thinker to confirm; not filed here
the directory layout, the registry's shape, each tool's start flags, where the allow-list lives, how the tool set is read back from the host plumbing the brief's runner and drain chapters, carried by this intent's spec
a separate operating-system user, a container, or the host's own sandbox per profile capability the planned sandbox intent itd-2610161621364075 and the later step the remedy names; not this intent

Verdict: FILE-AS-IS, the trust rule and the stance held for confirmation rather than filed; the routing was confirmed at the planning interview of 2026-11-04 (dcn-2611041550129278), which also widened the capability to every way of paying and folded in the switching half. Typed links: refines itd-2610222215485265, whose subscription-route wall becomes a profile among several and whose spec's first step becomes the per-profile proof; builds_on itd-2609201925079472 (the loop's rate-limit checkpoint) and itd-2611011230226453 (the named key and its budget); related_issues iss-2611032326573729 (no fixed place or command), iss-2611032327111678 (nothing enforces the wall), iss-2610100602595553 and iss-2610100913095172 (the rate-limit wait and its reporting) and iss-2610230716454430 (the runner's subscription default). Flagged for the product thinker, never auto-classified: this draft reverses in part the wall list of spc-2610230813348813, keeping abcd's own hooks where the spec disabled all hooks (already ruled for the guard by dcn-2611031722512037; the rules loader and session names are new) and replacing the connected-services deny with an allow-list of named tools. Neither sandbox draft is superseded or refined: itd-2610161710315026 (a declared list of hosts) fences from outside the launches a profile makes, and itd-2610161710316538 (a run reports how isolated it was) gains the profile a run is on as one of its facts, so each is proposed to build on this draft, an edge set on them with abcd intent edge once the product thinker confirms. supersedes nothing.

Audit Notes

Empty. Populated by intent-auditor when intent moves to shipped/.

Frontmatter

iditd-2611040344170206
typeintent
lifecycledrafts
severitymajor

References2

Referenced by5

mentions21