feat: add authenticated verification goal imports (#187) - #329
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0ed05885a8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // This command has no caller-controlled payload. Reject the presence of a | ||
| // body without parsing or consuming it so definitions, paths, or operation | ||
| // arguments can never become importer inputs. | ||
| if (request.body !== null) { |
There was a problem hiding this comment.
Detect payload bytes instead of the request stream
In the production Node.js route adapter, Next.js wraps every non-GET/HEAD IncomingMessage in a Web request body stream, including a normal POST with Content-Length: 0. Consequently, request.body !== null is true for every real HTTP call and this endpoint always returns 400 unexpected_request_body; the tests miss this because they construct NextRequest directly without the production adapter. Remove this presence check or consume a bounded stream and reject only when it contains bytes.
AGENTS.md reference: web/AGENTS.md:L2-L4
Useful? React with 👍 / 👎.
Source issue
Part of #187
Parent Epic: #184
Follows #328
Why this is next
PR #328 added the repository-backed verification-goal registry and immutable snapshot storage, but the importer had no production callsite. Epic #184 orders #187 before #188–#191.
This PR exposes only the existing definition importer. It does not add goal execution.
What changed
POST /api/projects/:id/verification-goals/importAPI contract
Successful imports return schema version 1, the canonical project ID, deterministic snapshot results, and inserted/existing counts. An absent or empty registry is a successful no-op.
Expected failures:
400 invalid_project_id400 unexpected_request_body401 unauthorized404 project_not_found409 project_context_unavailable409 project_repository_unavailable409 definition_version_conflict422 invalid_verification_goal_registryUnexpected failures use the existing correlated, redacted
500boundary.Deliberately out of scope
A future manual runner requires a goal-owned run identity, outcome linkage, project authority model, dedicated queue/lease/recovery contract, and reliability source. It must not synthesize tasks merely to reuse task-owned ledgers.
Local validation
Review
Fresh orthogonal Review: No blockers found in the inspected scope, high confidence for code and architecture.
Fresh Security/Adversarial review: No blockers found in the inspected scope, high confidence.
The uppercase UUID defect found during Security review was fixed before publication. The earlier message-based error classifier was also replaced with typed importer errors.
Remaining advisories
These are non-blocking for a manual, owner-only, definition-only endpoint, but must be resolved before execution or scheduling depends on imported snapshots:
500Hosted proof
Exact-head Web CI run
31827714396passed:Hosted proof increases confidence but does not remove the explicitly retained definition-only advisories above.