Development record
A session's checklist names a credential by its kind, scope and expiry, never its value or anything that retrieves it
Context
The checklist intent (itd-2610170638184486) gives every abcd session a file on disk saying what it may decide, what it waits on and what it owns. Its pre-run blocker sweep asks each session for a credential that is missing or will expire before the person returns, and that answer is written into the checklist. The coordination intent (itd-2610170634394993) gives every autonomous session a short-lived token of its own from abcd's GitHub App (its decision of 2026-10-22, C3), so a session knows of a credential that matters to its night.
The checklist is the most-read file a session has. It is re-injected into the model's context at every start and after every compaction, written by the agent, read back by any later session in that working copy, summarised into the person's return lists, and, in later work, uploaded to a private shared copy and optionally published (itd-2610222029228127, split out on 2026-10-22 by dcn-2610222025212338). Anything written there is copied into every one of those places. Agent-written state is also the least careful writer in the system: a model told to record "the token that expires at 03:00" will as readily paste the token.
On 2026-10-18 the agent routing the draft's decomposition proposed this as a separate trust rule; on 2026-10-22 the product thinker ruled that it be written up as one (dcn-2610222025224993). Through the decomposition table a trust rule becomes an ADR and a clause of the brief's invariants. The rule itself, the first two paragraphs of the decision below, is the product thinker's; how it is enforced, the third, is the technical facilitator's, decided on their delegation and open to change at the plan's sign-off.
Decision
A checklist records a credential only by its kind, its scope and its expiry. Kind is what sort of credential it is (an App installation token, a model-service key, a signing key); scope is what it reaches (a repository and the acts allowed, a service); expiry is when it stops working, or that it has none. Nothing else about it is written.
Never its value, and never anything that retrieves it. A checklist holds no secret, no part of one, no hash or encoding of one, and no pointer that would hand one to whoever reads the file: not an environment variable's value, not a path to a key file, not a keychain item's name and account, not a command that prints a token. The person, or the coordination intent's issuing step, gets the credential; the checklist only says one is needed and by when.
The write refuses, and the read refuses. abcd's checklist writer checks
every field it writes with abcd's native secret scanner
(internal/adapter/scanner), the one capture and decide already run, and refuses a write that carries a secret
pattern, naming the field and the pattern kind and never echoing the match;
the session's last good checklist stays in place. A checklist read from disk
that fails the same check is not re-injected: the reader reports the field
and falls back to the last good copy, as it does for a file it cannot parse;
the last good copy is only ever a file a checked write produced, and it is
checked again on read, so a file that fails both is not re-injected at all.
The check is a pattern scan, so it catches the shapes it knows; the rule
binds whatever it misses, and the fields that name a credential are typed
(kind, scope and expiry, from fixed lists and a timestamp), never free text.
Alternatives Considered
- Kind, scope and expiry only, checked on write and read (chosen). The blocker sweep needs exactly these three facts to tell the person what to renew before leaving, and none of them grants anything.
- Store a reference the session can use to fetch the credential (a keychain item name, a file path). Rejected: the checklist is re-injected, summarised and later uploaded, and a pointer that works for the session works for every reader of every copy.
- Store the value, encrypted at rest. Rejected: the key would have to be reachable by the session that re-reads the file, so it protects nothing against that session's transcript, compaction summary or upload, which is where the copies go.
- Leave it to the agent's instructions, with no check. Rejected: an instruction is a mistake filter at best, and agent-written state is the writer most likely to paste a value it was told about.
Consequences
- The blocker sweep and the return lists can say "the App token for intentdriven/abcd, push and pull requests, expires 03:10" and nothing more; renewing it is a step the person or the issuing step takes.
- The checklist writer depends on the native secret scanner, so a new pattern added there protects the checklist too; a second scanner is not built (principle one-canonical-primitive).
- The later shared and public copies (the phone and shared-copies intent) inherit a file with no credential in it, so their own checks start from a clean source rather than being the only line of defence.
- The rule is stated in the brief's invariants as invariant 24, consumed by itd-2610170638184486.
Frontmatter
| id | adr-2610222026265719 |
|---|---|
| type | adr |
| status | accepted |
| date | 2026-10-22 |
.abcd/development/decisions/adrs/2610222026265719-a-session-s-checklist-names-a-credential.md
open on GitHub ↗ · commit history ↗
References3
- itd-2610170634394993Headless agents in parallel coordinate through the shared remote, not conversationrelated
- itd-2610170638184486Every session keeps a checklist on disk, so no run stalls and no stall spreadsrelated
- itd-2610180912189125A session left to work on never stops while it has workrelated
Referenced by1
- adr-2610222026262980Coordination between headless agents is bounded by deadlines, fenced by the claim's tip, version-checked, and done under each session's own credentialrelated
mentions4
- dcn-26102220252123382026-10-22 — The phone and the shared copies of each checklist become their own intent in the bundle, and no question was put (facilitator, recorded on the product thinker's 2026-10-22 ruling C2, itd-2610170638184486 K1): once the product thinker chose to upload full checklists later, the shared copies are wanted later, and the phone needs them, so keeping them inside the checklist intent would hold its sooner parts back for nothing; splitting them off is the only answer consistent with the record, so asking would have offered a choice already made. The checklist intent keeps the on-disk checklist, waits, wakes and the blocker check
- dcn-26102220252249932026-10-22 — A checklist never holds a password, token or anything that retrieves one, only its kind, scope and expiry, and this is written up as its own trust rule (product thinker's ruling of 2026-10-22, itd-2610170638184486 K-split i): routed through the decomposition table as a trust rule, so it becomes an ADR and a clause of the brief's invariants rather than a line inside the checklist intent
- itd-2610222029228127Every session's checklist reaches a shared copy and the phone
- spc-2610230805429429every-abcd-session-keeps-a-checklist-on