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
Section 11 of doc/swagger/swagger.md contains three before/after annotation examples (GET+path params, GET+query params, POST+body param). These examples belong next to the rules they illustrate in Section 3 (Annotation Rules) — not orphaned at the end of the document in a rarely-reached dead zone. A developer reading Section 3.1 to learn the inline annotation pattern has to scroll past Sections 4-10 (anti-patterns, TDD, validation, smoke tests, verification, bugs) to find the examples.
Additionally, the existing codebase contains one val-bound route (listStatusesRoute in ApiRepositoryStatusControllerBase.scala:45) that uses a legacy alias pattern. Section 3.1 and Section 4 (anti-patterns) currently describe val-bound as a hypothetical pattern with a generic example (val getApiRoot = apiOperation[...]; get("...", operation(getApiRoot))). With a real val-bound example being added in §3.7.4, these sections must be updated to reference the actual pattern and cross-link to the concrete example.
Fix
Move the three before/after examples from Section 11 into a new subsection Section 3.7 (Annotation Examples) with subsections 3.7.1-3.7.3, add a fourth subsection 3.7.4 for the val-bound route with legacy alias, update Sections 3.1 and 4 to reference the real val-bound pattern from the codebase, and delete Section 11.
ID
Example
Moves From
Moves To
11.1
GET with path params — getIssue
old §11
§3.7.1
11.2
GET with query params — listIssues
old §11
§3.7.2
11.3
POST with body param — createIssue
old §11
§3.7.3
(new)
Val-bound route with legacy alias — listStatusesRoute / listStatuses
(new)
§3.7.4
3.1 and §4 wording updates
Section 3.1 currently says:
Where a pre-existing val-bound operation already exists in the codebase (e.g., val getApiRoot = apiOperation[...]; get("...", operation(getApiRoot))), that val-bound instance may be retained — do not rewrite it solely for style consistency. All new annotations must use the inline pattern.
Section 4 (anti-patterns) currently says:
Do NOT use val-bound pattern for new annotations (val name = apiOperation[...]; get("...", operation(name))) — use inline pattern instead. Pre-existing val-bound instances may be retained where they already exist in the codebase.
Both reference a hypothetical val name = apiOperation[...]; get("...", operation(name)) pattern. With a real val-bound example now documented in §3.7.4, these sections must be updated to:
§3.1: Replace the hypothetical example with a cross-reference to §3.7.4 as the concrete val-bound pattern. The wording should explicitly note that the codebase's val-bound pattern is val route = get("...", apiOperation[...]) {...} (route bound to val with apiOperation inline in the transformer list) rather than val op = apiOperation[...]; get("...", operation(op)) (operation extracted to a separate val). The actual pattern in the codebase binds the entire route expression to a val, with apiOperation appearing inline within that route's transformer list — not the Scalatra operation(op) extraction pattern.
§4: Update the anti-pattern to distinguish between the two val-bound patterns. The operation(op) extraction pattern (val op = apiOperation[...]; get("...", operation(op))) remains prohibited for new annotations. The route-level val binding (val route = get("...", apiOperation[...]...) {...}) is the pattern that already exists in the codebase and may be retained — with a cross-reference to §3.7.4.
3.7.4 content
This example comes from the existing codebase — ApiRepositoryStatusControllerBase.scala:45:
vallistStatusesRoute= get("/api/v3/repos/:owner/:repository/commits/:ref/statuses",
apiOperation[Seq[ApiCommitStatus]]("listStatuses")
.summary("List commit statuses for a ref")
.description("Returns commit statuses for a specific ref in the specified repository")
.parameters(
pathParam[String]("owner").description("Repository owner"),
pathParam[String]("repository").description("Repository name"),
pathParam[String]("ref").description("Ref to list statuses for (SHA, branch name, or tag name)")
)
.responseMessages(ResponseMessage(404, "Ref not found")))(referrersOnly { repository =>// ... response logic ...
})
get("/api/v3/repos/:owner/:repository/statuses/:ref") {
listStatusesRoute.action()
}
Only the primary val route binding receives the apiOperation annotation. The legacy alias route uses .action() to dispatch without a separate apiOperation — Scalatra-Swagger introspects the val binding to discover the operation, so the alias inherits the documentation automatically.
Verification against source code
The implementing agent MUST verify the §3.7.4 example against the actual source file src/main/scala/gitbucket/core/controller/api/ApiRepositoryStatusControllerBase.scala to confirm:
The route path strings in the before/after example match the actual route definitions exactly
The referrersOnly authenticator in the before example matches the actual code
The parameter names (owner, repository, ref) match the actual route path parameters
The .action() delegation pattern in the legacy alias matches the actual code
The description text (summary, description, parameter descriptions) is accurate for what the endpoint actually returns
If the verified source code differs from the proposed example, the example MUST be updated to match the actual source code — code is the authoritative source per project guidelines.
Success Criteria
SC
Criterion
Evidence Type
SC-1
§11 deleted from doc/swagger/swagger.md
string
SC-2
§3.7 exists with four subsections (3.7.1, 3.7.2, 3.7.3, 3.7.4)
string
SC-3
All three original before/after examples preserved verbatim
semantic
SC-4
§3.7.4 contains a val-bound route with legacy alias example showing listStatusesRoute and listStatusesRoute.action()
string
SC-5
§3.7.4 example references the source file ApiRepositoryStatusControllerBase.scala
string
SC-6
§3.7.4 after example includes apiOperation annotation on the val declaration
string
SC-7
§3.7.4 explains that the legacy alias inherits documentation via .action() without its own apiOperation
semantic
SC-8
Route paths, authenticators, and parameter names in §3.7.4 verified against actual source code in ApiRepositoryStatusControllerBase.scala
semantic
SC-9
§3.1 updated to reference §3.7.4 as the concrete val-bound example and accurately describes the route-level val binding pattern (val route = get("...", apiOperation[...]...)) rather than the operation(op) extraction pattern
semantic
SC-10
§4 anti-pattern entry for val-bound updated to distinguish the prohibited operation(op) extraction pattern from the permitted route-level val binding pattern, with cross-reference to §3.7.4
Inline annotation pattern (not val-bound) preserved in examples 3.7.1-3.7.3
Val-bound example (3.7.4) documents a pre-existing pattern — new annotations must still use inline pattern per §3.1
§3.1 and §4 wording must accurately distinguish between the prohibited operation(op) extraction pattern and the existing route-level val binding pattern, cross-referencing §3.7.4
🤖 Co-authored with AI: OpenCode (ollama-cloud/glm-5.1)
Problem
Section 11 of
doc/swagger/swagger.mdcontains three before/after annotation examples (GET+path params, GET+query params, POST+body param). These examples belong next to the rules they illustrate in Section 3 (Annotation Rules) — not orphaned at the end of the document in a rarely-reached dead zone. A developer reading Section 3.1 to learn the inline annotation pattern has to scroll past Sections 4-10 (anti-patterns, TDD, validation, smoke tests, verification, bugs) to find the examples.Additionally, the existing codebase contains one
val-bound route (listStatusesRouteinApiRepositoryStatusControllerBase.scala:45) that uses a legacy alias pattern. Section 3.1 and Section 4 (anti-patterns) currently describe val-bound as a hypothetical pattern with a generic example (val getApiRoot = apiOperation[...]; get("...", operation(getApiRoot))). With a real val-bound example being added in §3.7.4, these sections must be updated to reference the actual pattern and cross-link to the concrete example.Fix
Move the three before/after examples from Section 11 into a new subsection Section 3.7 (Annotation Examples) with subsections 3.7.1-3.7.3, add a fourth subsection 3.7.4 for the val-bound route with legacy alias, update Sections 3.1 and 4 to reference the real val-bound pattern from the codebase, and delete Section 11.
getIssuelistIssuescreateIssuelistStatusesRoute/listStatuses3.1 and §4 wording updates
Section 3.1 currently says:
Section 4 (anti-patterns) currently says:
Both reference a hypothetical
val name = apiOperation[...]; get("...", operation(name))pattern. With a real val-bound example now documented in §3.7.4, these sections must be updated to:§3.1: Replace the hypothetical example with a cross-reference to §3.7.4 as the concrete val-bound pattern. The wording should explicitly note that the codebase's val-bound pattern is
val route = get("...", apiOperation[...]) {...}(route bound to val withapiOperationinline in the transformer list) rather thanval op = apiOperation[...]; get("...", operation(op))(operation extracted to a separate val). The actual pattern in the codebase binds the entire route expression to aval, withapiOperationappearing inline within that route's transformer list — not the Scalatraoperation(op)extraction pattern.§4: Update the anti-pattern to distinguish between the two val-bound patterns. The
operation(op)extraction pattern (val op = apiOperation[...]; get("...", operation(op))) remains prohibited for new annotations. The route-level val binding (val route = get("...", apiOperation[...]...) {...}) is the pattern that already exists in the codebase and may be retained — with a cross-reference to §3.7.4.3.7.4 content
This example comes from the existing codebase —
ApiRepositoryStatusControllerBase.scala:45:Before (un-annotated val-bound route):
After (annotated val-bound route):
Only the primary
valroute binding receives theapiOperationannotation. The legacy alias route uses.action()to dispatch without a separateapiOperation— Scalatra-Swagger introspects the val binding to discover the operation, so the alias inherits the documentation automatically.Verification against source code
The implementing agent MUST verify the §3.7.4 example against the actual source file
src/main/scala/gitbucket/core/controller/api/ApiRepositoryStatusControllerBase.scalato confirm:referrersOnlyauthenticator in the before example matches the actual codeowner,repository,ref) match the actual route path parameters.action()delegation pattern in the legacy alias matches the actual codeIf the verified source code differs from the proposed example, the example MUST be updated to match the actual source code — code is the authoritative source per project guidelines.
Success Criteria
doc/swagger/swagger.mdstringstringsemanticlistStatusesRouteandlistStatusesRoute.action()stringApiRepositoryStatusControllerBase.scalastringapiOperationannotation on thevaldeclarationstring.action()without its ownapiOperationsemanticApiRepositoryStatusControllerBase.scalasemanticval route = get("...", apiOperation[...]...)) rather than theoperation(op)extraction patternsemanticoperation(op)extraction pattern from the permitted route-level val binding pattern, with cross-reference to §3.7.4semanticDependencies
devdoc/swagger/swagger.mdConstraints
.opencode-specific references (per [SPEC-FIX] Add before/after annotation examples and remove .opencode references in swagger docs #93 scope) — verify none introducedbathPathupstream typo preserved as-isoperation(op)extraction pattern and the existing route-level val binding pattern, cross-referencing §3.7.4🤖 Co-authored with AI: OpenCode (ollama-cloud/glm-5.1)