You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**Acceptance**: No container environment contains a credential valid beyond one hour or beyond one
268
-
repository, except the provider key.
275
+
-**Acceptance**: (a) **Code-checkable** — no container environment holds a credential that is
276
+
broad-scope or long-lived; the App path scopes the token to exactly one repository; the token is
277
+
env-injected and never written to `/workspace`, `.git/config`, argv, or logs; no acceptance clause
278
+
mandates a specific expiry duration. (b) **Operator obligation** — a single-owner deployment must
279
+
supply a repo-scoped, minimally-permissioned, short-expiry fine-grained PAT (or use the App); a broad
280
+
or long-lived classic PAT is non-conformant. Multi-tenant deployments must use the App.
269
281
270
282
## CONST-PI-VERSION-PINNED
271
283
@@ -291,3 +303,4 @@ that always fires is one nobody reads.
291
303
|---|---|
292
304
| 2026-07-15 | Initial. Extracted from `DESIGN.md` v0.1 (2026-07-14, local, uncommitted). That document recorded "50 claims adversarially verified: 48 confirmed, 2 refuted" — but verified **against documentation**. Source-verification at `earendil-works/pi @ 5e336cf` subsequently corrected ~7 points, two of them architecture-breaking. Hence the evidence convention above: source is authoritative, docs are a hint. |
293
305
| 2026-07-15 |`CONST-NO-CONTEXT-FILES-MANDATORY` amended: it named only the CLI flag (`-nc`), but the runner uses the **SDK**, where the mechanism is `noContextFiles: true` on a caller-constructed `DefaultResourceLoader` — and it is **off by default**. The constraint therefore fails **open by omission**: there is no flag to forget, there is an entire object to forget to build. Statement and Evidence corrected; Acceptance unchanged (it was right; the named mechanism was wrong). This is the distinction the evidence convention exists to catch — the *requirement* was verified, the *mechanism* was assumed. |
306
+
| 2026-07-17 |`CONST-TOKEN-SCOPED-PER-JOB` amended: Statement, Why, and Acceptance rewritten from a single-mechanism mandate (App installation token with one fixed expiry duration) to mechanism-neutral **required properties** — repo-scoped, minimally-permissioned, short-lived, host-held, env-injected, not merge-capable in practice. The App path satisfies them and stays **mandatory for multi-tenant**; a tightly-scoped short-expiry **fine-grained** PAT satisfies them for **single-owner**; a broad or long-lived classic PAT is excluded. The bound is the token's **expiry**, not a fixed duration — no acceptance clause mandates one. Provider-key exception preserved unchanged. |
## OQ-006 — Which GitHub auth mechanism is the default, and when is an App required?
101
+
102
+
-**Status**: **CLOSED — default `gh` / fine-grained PAT for single-owner; App for multi-tenant**
103
+
-**Answer**: The default `GITHUB_AUTH_SOURCE` is `gh` (or a repo-scoped, short-expiry fine-grained PAT)
104
+
for a single-owner deployment. The GitHub App path is optional, strictly stronger on the token axis
105
+
(true per-repo scoping, shorter expiry), and **mandatory for multi-tenant** deployments — a
106
+
fine-grained PAT is per-account and cannot isolate mutually-distrusting owners. A broad or long-lived
107
+
classic PAT is non-conformant either way. This is the property set `CONST-TOKEN-SCOPED-PER-JOB`
108
+
enumerates; the App is no longer a hard prerequisite for running GitHub jobs.
109
+
-**Why it was an open question**: the original design assumed a GitHub App was mandatory. Research
110
+
found no GitHub requirement forcing an App for a single-owner tool, and `@octokit/auth-app` shipped
111
+
declared-but-unused — so the mechanism was undecided in practice while the docs implied App-only.
112
+
-**What closed it**: this plan (the pluggable `makeGitHubAuth(pat|gh|app)` resolver) plus the E1
113
+
amendment of `CONST-TOKEN-SCOPED-PER-JOB` from App-mandatory/one-hour to mechanism-neutral required
114
+
properties. Recorded here so the decision is durable and greppable rather than buried in a closed PR.
115
+
-**Related risk**: `OQ-004` (unrestricted egress) is the reason the credential mechanism matters — the
116
+
token's short expiry, not network policy, is the exfiltration bound, so the mechanism must keep that
117
+
expiry short and the scope narrow. `OQ-004` remains **ACCEPTED RISK** (unchanged by this entry).
118
+
100
119
---
101
120
102
121
## Retired from the source design document
@@ -135,3 +154,4 @@ adversarial passes did.
135
154
| 2026-07-15 | Initial. Replaces `DESIGN.md` v0.1 §10. Collapsed from ~10 checklist items to 5 rows: source-verification at `earendil-works/pi @ 5e336cf` answered most of them. The register's value inverted in the process — from "holds ten unknowns" to "holds one known-incoming breaking change" (`OQ-005`). |
136
155
| 2026-07-16 |`OQ-005`**retracted and re-corrected** to `WATCH — NOT IN THE PIN`. The 2026-07-15 "correction" below was itself wrong: it read `sdk.ts` at `5e336cf` (**HEAD**) to describe npm `0.80.7` (**the pin**), concluded `modelRuntime` had already landed, and declared the changelog unreliable. `ModelRuntime` does not exist in `0.80.7` — no `model-runtime` in its `dist/`, not exported from `dist/index.js`. The changelog said `[Unreleased]` and was exactly right. The runner was written against the phantom API, the image built cleanly, and every job would have died on a missing export; CI caught it on the first real container run. `constitution.md`'s evidence convention now requires verification against the **published artifact**, and `pinned-api.test.mjs` asserts `ModelRuntime` is absent so the real migration fails a test instead of a job. |
137
156
| 2026-07-15 |~~`OQ-005` corrected to **WATCH — PARTIALLY LANDED**~~ — **this entry was wrong; see above.** It claimed `modelRuntime` was already in `CreateAgentSessionOptions` at the pinned sha and that the changelog was not a reliable signal. Both false: the sha was HEAD, not the pin. Kept rather than deleted, because a spec that hides having been wrong teaches the next reader to trust it more than it deserves. |
157
+
| 2026-07-17 | Added OQ-006 recording the GitHub-auth-mechanism decision (default gh/fine-grained PAT single-owner; App mandatory multi-tenant), closed by this plan + the E1 CONST-TOKEN-SCOPED-PER-JOB amendment. |
0 commit comments