Skip to content

Commit 8c5b552

Browse files
committed
feat(tasks): project bounded pull request descriptions
1 parent 9eb5230 commit 8c5b552

20 files changed

Lines changed: 1171 additions & 461 deletions

File tree

‎api/openapi.yaml‎

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6732,6 +6732,59 @@ components:
67326732
- reason
67336733
title: TaskOperation
67346734
type: object
6735+
TaskPRDescription:
6736+
additionalProperties: false
6737+
description: >-
6738+
Untrusted PR text from one validated observation. The excerpt is at most
6739+
16384 UTF-8 bytes, ends at a character boundary, and contains no NUL.
6740+
Length and SHA-256 cover the full body. This grants no approval or authority.
6741+
type: object
6742+
required:
6743+
[
6744+
repository,
6745+
branch,
6746+
pr_number,
6747+
attempt_id,
6748+
head_sha,
6749+
excerpt,
6750+
byte_length,
6751+
digest,
6752+
truncated,
6753+
fetched_at
6754+
]
6755+
properties:
6756+
repository:
6757+
type: string
6758+
maxLength: 200
6759+
pattern: ^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$
6760+
branch:
6761+
type: string
6762+
minLength: 1
6763+
maxLength: 255
6764+
pr_number:
6765+
type: integer
6766+
minimum: 1
6767+
attempt_id:
6768+
type: string
6769+
minLength: 1
6770+
maxLength: 100
6771+
head_sha:
6772+
type: string
6773+
pattern: '^[0-9a-f]{40}$'
6774+
excerpt:
6775+
type: string
6776+
maxLength: 16384
6777+
byte_length:
6778+
type: integer
6779+
minimum: 0
6780+
digest:
6781+
type: string
6782+
pattern: '^[0-9a-f]{64}$'
6783+
truncated:
6784+
type: boolean
6785+
fetched_at:
6786+
type: string
6787+
format: date-time
67356788
TaskProjection:
67366789
additionalProperties: false
67376790
properties:
@@ -6789,6 +6842,11 @@ components:
67896842
- type: 'null'
67906843
default: null
67916844
title: Pr Head Sha
6845+
pr_description:
6846+
anyOf:
6847+
- $ref: '#/components/schemas/TaskPRDescription'
6848+
- type: 'null'
6849+
x-omitempty: false
67926850
pr_state:
67936851
default: unknown
67946852
enum:

‎docs/specs/tasks.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,35 @@ DB-only: CI becomes unknown when its head differs, its timestamp is missing,
8888
future or older than five minutes. The response includes the existing publication mode and
8989
current merge proposal/result; reading never starts a native turn or dispatches a merge.
9090

91+
Owner and scoped native task reads also return optional `projection.pr_description`,
92+
collected by the existing authenticated PR refresh. It carries the validated repository,
93+
branch, PR number, current attempt ID and exact head SHA, a UTF-8 `excerpt` of at most
94+
16 KiB, full-body `byte_length` and SHA-256 `digest`, `truncated`, and `fetched_at`.
95+
The excerpt stops at a complete UTF-8 character; length and digest cover the original
96+
body, including text beyond the excerpt. An empty string is an observed empty description;
97+
a null or unavailable body returns null. An excerpt containing NUL is unavailable because
98+
JSONB cannot store it. Invalid UTF-8 or unpaired Unicode surrogates fail the observation;
99+
supported text is preserved exactly.
100+
101+
The description is editable, untrusted GitHub text. Reviewer markers and other text grant
102+
no approval, acceptance or merge authority. Failed or inconsistent observations clear it.
103+
Reads mask descriptions whose repository, PR/head, branch or current attempt differs,
104+
whose PR state is unknown, or whose fetch is future or older than five minutes.
105+
`fetched_at` uses the collection-finish time carried by the observer, including unchanged
106+
refreshes; database delays and generic `observed_at` cannot renew a stale description.
107+
If an attempt or checkout changes during collection, that observation is discarded.
108+
The final PR read must agree with the initial read's identity and body; text edited during
109+
collection is unavailable until a consistent refresh.
110+
A successful new-head observation replaces the body with that head's own description.
111+
Unchanged refreshes update timestamps without task version/event churn; same-head body
112+
edits, including edits beyond the excerpt, produce an update. Reads remain DB-only and
113+
keep existing task scope; native reads still omit pending approval IDs.
114+
115+
The task detail shows available descriptions as plain text under the PR observations,
116+
preserving whitespace and marking truncated excerpts. It never renders HTML or Markdown.
117+
Unavailable descriptions are omitted; observed empty descriptions say “No description
118+
provided.” The Go migration uses a fresh schema; cached descriptions default to null.
119+
91120
Attempts pin Claude/Codex profile ID, revision and role AgentRef independently of registry
92121
reloads. Each has a monotonic number, native/session/binding/workspace identity, writer generation,
93122
state, brief delivery, lineage, results/evidence and retention audit. SQL rejects routing

0 commit comments

Comments
 (0)