Outcome
The Issues API keeps exact GitHub parity while growing OpenAgents-specific fields in a way a client — human or agent — can discover mechanically: here are the fields GitHub has, and here are the fields we added.
Background
An audit (2026-08-22) found that "in progress" exists only as a per-project board column: ProjectItem.values["Status"] with hardcoded columns To Do / In Progress / Done, scoped to one project, never synced to the issue, and invisible to the Issues API. Meanwhile the shared status component already ships an unused :started shape (progress arc, blue tint) that renders the moment real data arrives. Agents currently have no machine-readable way to tell which open issues are in progress short of walking every project board.
Design
One namespaced extension object per resource, plus a published field index.
- Every
/api/v3 issue response gains a top-level openagents object alongside the GitHub fields. GitHub clients ignore unknown keys; OpenAgents-aware clients read issue.openagents.*. Nothing existing moves or changes shape.
- The first entry is progress:
issue.openagents.progress with values "to_do" | "in_progress" | "done" (snake_case, like GitHub's own enums). It is derived by default: an issue is in_progress when it sits in a matching column on any board the viewer can read, so projects stop being the only source of truth without forcing a second write path. A direct set through the extension field may come later.
- Discovery is mechanical, not tribal:
GET /api/v3 (root document) lists every extension field with its type, enum values, owning version, and a doc URL.
- Each response carries an
X-OpenAgents-Extensions: progress header naming which extensions are populated, so an agent can branch without hardcoding.
- Filter parity extends the same way:
GET /repos/{owner}/{repo}/issues?progress=in_progress filters through the same derivation, following the bounded-pagination contract from #5.
Governance rules for every future extension field (this issue establishes them):
- Lives under the
openagents namespace; never mutates a GitHub-shaped key.
- Enumerated in the root document before any client is expected to use it.
- Carries a test pinning its JSON shape, like every other API contract in this repository.
- Derivations state their sources explicitly (which boards, whose visibility).
Work
- Add the
openagents object to issue JSON (IssueJSON), empty rather than absent when no extension applies, so the key's presence is itself discoverable.
- Implement progress derivation across readable project items, with visibility honored exactly as list endpoints do.
- Root-document endpoint listing extension fields; header on issue responses.
progress= filter on the issue index within the pagination contract.
- Drive
Circle.issue_status :started from the derived value so the UI arc lights up wherever rows render.
- Contract tests for JSON shape, filter behavior, visibility, and the root document; update the CLI's issue schema.
Acceptance criteria
- A GitHub-shaped client sees byte-compatible issue responses (only an additional object).
- An agent fetching the API root can enumerate
progress and its enum without reading prose.
?progress=in_progress agrees with what the UI shows as started.
- Private-board membership never leaks into a viewer's derived progress.
Verification
Controller tests for shape, filter, and authorization; a root-document test asserting the field index; mix precommit.
Outcome
The Issues API keeps exact GitHub parity while growing OpenAgents-specific fields in a way a client — human or agent — can discover mechanically: here are the fields GitHub has, and here are the fields we added.
Background
An audit (2026-08-22) found that "in progress" exists only as a per-project board column:
ProjectItem.values["Status"]with hardcoded columnsTo Do / In Progress / Done, scoped to one project, never synced to the issue, and invisible to the Issues API. Meanwhile the shared status component already ships an unused:startedshape (progress arc, blue tint) that renders the moment real data arrives. Agents currently have no machine-readable way to tell which open issues are in progress short of walking every project board.Design
One namespaced extension object per resource, plus a published field index.
/api/v3issue response gains a top-levelopenagentsobject alongside the GitHub fields. GitHub clients ignore unknown keys; OpenAgents-aware clients readissue.openagents.*. Nothing existing moves or changes shape.issue.openagents.progresswith values"to_do" | "in_progress" | "done"(snake_case, like GitHub's own enums). It is derived by default: an issue isin_progresswhen it sits in a matching column on any board the viewer can read, so projects stop being the only source of truth without forcing a second write path. A direct set through the extension field may come later.GET /api/v3(root document) lists every extension field with its type, enum values, owning version, and a doc URL.X-OpenAgents-Extensions: progressheader naming which extensions are populated, so an agent can branch without hardcoding.GET /repos/{owner}/{repo}/issues?progress=in_progressfilters through the same derivation, following the bounded-pagination contract from #5.Governance rules for every future extension field (this issue establishes them):
openagentsnamespace; never mutates a GitHub-shaped key.Work
openagentsobject to issue JSON (IssueJSON), empty rather than absent when no extension applies, so the key's presence is itself discoverable.progress=filter on the issue index within the pagination contract.Circle.issue_status :startedfrom the derived value so the UI arc lights up wherever rows render.Acceptance criteria
progressand its enum without reading prose.?progress=in_progressagrees with what the UI shows as started.Verification
Controller tests for shape, filter, and authorization; a root-document test asserting the field index;
mix precommit.