Goal
Write down what was decided, so the next person does not re-litigate it.
Do this last, when the code is green — not first.
ADR-041 in docs/DECISIONS.md
Credentials live on accounts; a context source references an account.
Record, with the reasoning:
- One registry holds every machine credential. A context source is a source, not a credential
holder. context_provider was cloned from llm_provider rather than from scm_provider, and an
LLM provider has an API key and no identity — which is how the context registry ended up with a
key and no identity, no workspace, no role and no link to the forge account that is the same bot at
the same host. Nothing in docs/DECISIONS.md ever decided that; ADR-035 argues the opposite.
role stays a scalar. REVIEWER and FACTORY can never share a row. That is ADR-038's separation
and it is unamended by this change.
CONTEXT is a role value, not a NULL. A nullable role lets a forge row lose its role by
accident (docs/HISTORY.md:1391,1397).
- Scope detection is advisory. Two of the four credential families report nothing; scope is
necessary-but-not-sufficient on every forge. Detection informs, never decides.
- ADR-035 is satisfied rather than touched — one account narrowed by the adapter it is handed is
exactly its "rights, not transport".
- ADR-020 is respected by keeping the kind dispatch in
ProviderClients, a composition root.
Other docs
| File |
Change |
docs/DATA-MODEL.md |
The encryption boundary: one AAD prefix, provider:<id>. context-provider:<id> is retired. |
docs/UNVERIFIED.md |
The five unmeasured scope claims, and the scoped-Atlassian-token limit. |
docs/SECURITY.md |
The credential surface is one table now. |
CLAUDE.md Status snapshot |
Rewrite it, never append. |
docs/HISTORY.md |
Append a new milestone entry: what shipped, what review found, what it cost. |
techdebt/global/3-2-… |
Close it — the code reader no longer guesses by host substring. |
techdebt/spire-ui/4-3-the-account-form-holds-thirteen-state-hooks.md |
Close or narrow, per the form task. |
Explicitly out of scope — write this down too
So nobody thinks it was forgotten:
- The workspace stays on the forge account. Moving it to the repository is M3's re-model
(analysis §6.4). Doing both as one migration would hide which half broke — and that shape has cost
this project three milestones.
- Per-repository push-rights verification. M3.
- Typing
@handle in an allowlist and storing the numeric id. Already agreed for M3 and recorded
in docs/factory/ROADMAP.md.
- Many accounts per (forge, workspace, role). Still not possible.
- Nothing re-checks a credential on a schedule.
Acceptance
Part of #148
Goal
Write down what was decided, so the next person does not re-litigate it.
Do this last, when the code is green — not first.
ADR-041 in
docs/DECISIONS.mdCredentials live on accounts; a context source references an account.
Record, with the reasoning:
holder.
context_providerwas cloned fromllm_providerrather than fromscm_provider, and anLLM provider has an API key and no identity — which is how the context registry ended up with a
key and no identity, no workspace, no role and no link to the forge account that is the same bot at
the same host. Nothing in
docs/DECISIONS.mdever decided that; ADR-035 argues the opposite.rolestays a scalar. REVIEWER and FACTORY can never share a row. That is ADR-038's separationand it is unamended by this change.
CONTEXTis a role value, not a NULL. A nullable role lets a forge row lose its role byaccident (
docs/HISTORY.md:1391,1397).necessary-but-not-sufficient on every forge. Detection informs, never decides.
exactly its "rights, not transport".
ProviderClients, a composition root.Other docs
docs/DATA-MODEL.mdprovider:<id>.context-provider:<id>is retired.docs/UNVERIFIED.mddocs/SECURITY.mdCLAUDE.mdStatus snapshotdocs/HISTORY.mdtechdebt/global/3-2-…codereader no longer guesses by host substring.techdebt/spire-ui/4-3-the-account-form-holds-thirteen-state-hooks.mdExplicitly out of scope — write this down too
So nobody thinks it was forgotten:
(analysis §6.4). Doing both as one migration would hide which half broke — and that shape has cost
this project three milestones.
@handlein an allowlist and storing the numeric id. Already agreed for M3 and recordedin
docs/factory/ROADMAP.md.Acceptance
docs/UNVERIFIED.mdcarries every unmeasured claim this epic made, with retrieval dates.CLAUDE.mdStatus section is rewritten, not appended to.docs/HISTORY.mdhas a new entry.Part of #148