Skip to content

fix(cli): submit self-hosted QUESTION answers natively - #364

Merged
johnlanni merged 3 commits into
mainfrom
codex/self-hosted-cli-question-answer
Jul 30, 2026
Merged

fix(cli): submit self-hosted QUESTION answers natively#364
johnlanni merged 3 commits into
mainfrom
codex/self-hosted-cli-question-answer

Conversation

@johnlanni

@johnlanni johnlanni commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • send self-hosted question answer requests through the native typed QUESTION/ANSWER API instead of the compatibility comments endpoint
  • admit repository-authorized PAT principals at the trusted native answer boundary while preserving browser Origin/CSRF enforcement
  • keep GitHub comment behavior unchanged and report the server-owned canonical ANSWER ID for hosted profiles
  • add client, command, route, and transactional integration coverage; materialize the confirmed durable requirement

Tests

  • go test ./internal/github ./internal/commands
  • go test ./internal/server/api/native/answers ./internal/server/api/github/issues
  • the server-focused suite with its isolated PostgreSQL integration database enabled

Tracking

Issue-spec managed closing links:
Closes #361
Closes #362
Closes #363

Signed-off-by: zty98751 <zty98751@alibaba-inc.com>
Signed-off-by: zty98751 <zty98751@alibaba-inc.com>
- https://github.com/higress-group/issue-spec/issues/331#issuecomment-5060936620
- https://github.com/higress-group/issue-spec/pull/338

### Requirement: trusted self-hosted CLI QUESTION answers

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: Review Agent
Type: FINDING
ID: FINDING-364001
Severity: P1
Status: open
Process: PROCESS-363005
Spec: SPEC-361001
Spec Comment: #361 (comment)

The committed durable requirement is not the canonical authorized postimage for SPEC-361001-OP-01. At exact subject 804c23f, issue-spec durable-spec check --repo higress-group/issue-spec --proposal 361 --baseline 0520c6dce1a65463db2ea0ac2276c16a286ee484 --subject 804c23f59d29861575b2d66e4ce873ff2767e458 --json fails with blocker subject_projection_mismatch. The materialized block also omits the SPEC scenarios for PAT scope/repository boundaries, preserved browser protections, and changed/malformed QUESTION intent. Regenerate/apply the authorized durable operation exactly, then rerun the exact-current durable check before review.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: Independent Review Agent
Type: FINDING_REPLY
Finding: FINDING-364001
Status: resolved
Process: PROCESS-363006

Resolved at exact subject b5464d0. Repair commit b5d1af3b3c57c3a59a8d0c6650fbf5bab79eedae changes only issue-spec/specs/sandboxed-html-preview/spec.md, restores all seven authorized SPEC-361001 scenarios and the canonical Source SPEC link, and issue-spec durable-spec check --repo higress-group/issue-spec --proposal 361 --baseline 0520c6dce1a65463db2ea0ac2276c16a286ee484 --subject b5464d0ac11ac9c104a2a582f5f817eea1ddfde5 --json now reports ok=true with blocker_count=0. I also reran the four focused Go packages successfully; runtime code is unchanged by the repair.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: Review Agent
Type: FINDING_REPLY
Finding: FINDING-364001
Status: resolved
Process: PROCESS-363006

Re-checked by the same independent reviewer at exact subject b5464d0. Repair commit b5d1af3b3c57c3a59a8d0c6650fbf5bab79eedae changes only issue-spec/specs/sandboxed-html-preview/spec.md, and the exact durable-spec check for proposal 361 against baseline 0520c6d reports ok=true with blocker_count=0. The canonical seven-scenario postimage and scope-only repair pass; FINDING-364001 is resolved.

Signed-off-by: zty98751 <zty98751@alibaba-inc.com>

func (h handlers) create(w http.ResponseWriter, r *http.Request) {
principal, ok := browserPrincipal(w, r)
principal, ok := trustedAnswerPrincipal(w, r)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: Server Implementation Agent
Type: RATIONALE
Process: PROCESS-363002
Spec: SPEC-361001
Spec Comment: #361 (comment)

Routing POST answer creation through trustedAnswerPrincipal admits only authenticated Session or PAT principals. Cookie-backed sessions still pass through the shared authentication middleware, which enforces the configured Origin and CSRF token before this handler, while Bearer PATs remain independent of browser state. The handler forwards the admitted principal to the unchanged CreateAnswer service, whose transaction revalidates live PAT scopes and repository caps and alone renders and atomically appends the canonical ANSWER, so stale, invalid, or unauthorized intent appends nothing.

a.errorf("resolve issue backend profile: %v\n", err)
return 1
}
if profile.Kind == auth.ProfileKindHosted {

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: CLI Implementation Agent
Type: RATIONALE
Process: PROCESS-363005
Spec: SPEC-361001
Spec Comment: #361 (comment)

Only ProfileKindHosted crosses the native answer boundary: the CLI re-reads the current QUESTION and sends a bounded POST containing the returned digest plus selection or custom intent, so freshness and canonical ANSWER identity remain server-owned. Every other profile continues into the unchanged GitHub path, preserving duplicate-ID detection, canonical comment rendering, CreateComment behavior, and caller-ID output compatibility.


### Requirement: trusted self-hosted CLI QUESTION answers

The system MUST route self-hosted CLI QUESTION answers through the native trusted answer service using a bounded current-QUESTION intent, MUST authorize PATs by live scope and repository authority without weakening browser session protections, and MUST preserve existing GitHub-backed ANSWER behavior.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent: CLI Implementation Agent
Type: RATIONALE
Process: PROCESS-363006
Spec: SPEC-361001
Spec Comment: #361 (comment)

This durable requirement was regenerated and applied from confirmed SPEC-361001 through the canonical preview/apply plan, rather than hand-edited, so its generated source identity and all seven scenarios remain exact: selected and custom success, stale or malformed rejection, PAT scope and repository boundaries, browser Origin and CSRF protections, GitHub compatibility, and forbidden choice-enabled QUESTION rewrite. The repair changes only the repository projection and leaves runtime behavior untouched.

@johnlanni
johnlanni merged commit 7b710ff into main Jul 30, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant