fix: validate Gitea conversation caches and safe commit messages

This commit is contained in:
2026-10-13 13:50:10 +00:00
parent a7a13aa4d5
commit a74fb747a5
6 changed files with 227 additions and 17 deletions
@@ -36,28 +36,52 @@ pre-write delegation admission.
Schema: `gitea-agent.rework-provider/v1`. The contract explicitly declares the
aggregate semantics for PR and underlying PR-Issue `comments` fields. Each
`components` array contains unique values from `top_level`, `reviews`, `inline`
and must include `top_level`. Choose the reviewed deployment semantics, not the
and must include `top_level`. An optional `cache_mode: "gitea-conversation-v1"`
on each aggregate scope is accepted only for provider version `1.27.3`, field
`comments`, and components consisting of exactly `top_level` and `reviews`.
Omission retains strict legacy behavior. Choose the reviewed deployment semantics, not the
combination that happens to fit a current response. There is no guessed version
or automatic capability downgrade.
Shape example only, **not a claim about this deployment**:
Shape example only: upstream v1.27.3 source supports this shape; it does not attest that a custom build matches upstream:
```json
{
"schema": "gitea-agent.rework-provider/v1",
"version": "<independently-observed-version>",
"version": "1.27.3",
"aggregate": {
"pr": {"field": "comments", "components": ["top_level"]},
"pr_issue": {"field": "comments", "components": ["top_level"]}
"pr": {"field": "comments", "components": ["top_level", "reviews"], "cache_mode": "gitea-conversation-v1"},
"pr_issue": {"field": "comments", "components": ["top_level", "reviews"], "cache_mode": "gitea-conversation-v1"}
},
"inline": {
"mode": "per_review",
"field": "review_comments",
"components": ["inline"]
"components": ["reviews"]
}
}
```
### Cached conversation admission
For the explicit cache mode, snapshot counters must be present non-boolean,
nonnegative integers no greater than the complete collection-derived conversation
count. This admits bounded stale lag, not arbitrary mismatch; counters ahead of
the collected count, missing values and malformed scalars remain BLOCK.
Upstream `v1.27.3` `services/convert/issue.go` reads stored `Issue.NumComments`.
`models/issues/comment.go` counts plain comments and review-summary comments;
review creation bypasses the recomputation that plain-comment creation performs.
This source pin explains the opt-in policy, not a deployed custom-build attestation.
For `create`, fresh readback must prove exactly one canonical top-level addition
and the recomputed aggregate must equal the complete post-write conversation
count. A stale baseline counter `0` with one review can become `2` after the new
plain comment; `before counter + 1` is not the cache-mode rule. All old rows,
reviews, inline evidence, Source Issue metadata/comments, identity, body, head
and unrelated native fields retain their existing protections. For `reuse`, no
addition or counter/metadata refresh is admitted: even a legitimate-looking
cache change without the authorized create action is BLOCK. Strict contracts
without cache opt-in retain exact snapshot projections and the original delta.
For `inline.components`, the explicit projection modes are `["inline"]`,
`["reviews"]`, and `["reviews", "inline"]`. The review-only mode projects
only the number of reviews into `review_comments`; it does not add per-review