Skip to content

Support optional project assignment in issue create#129

Merged
MirzaMerdovic merged 1 commit intomainfrom
issues/orfe-128
Apr 30, 2026
Merged

Support optional project assignment in issue create#129
MirzaMerdovic merged 1 commit intomainfrom
issues/orfe-128

Conversation

@j3l3n4-bot
Copy link
Copy Markdown

@j3l3n4-bot j3l3n4-bot Bot commented Apr 30, 2026

Ref: #128

Summary

  • add explicit optional project assignment to issue create through add_to_project, project inputs, and default project resolution only when opted in
  • create the project item through GitHub Projects v2 and optionally set initial status during issue creation
  • document the updated command contract and add coverage for create-only, project add, status set, and partial-failure behavior

Verification

  • npm test
  • npm run lint
  • npm run typecheck
  • npm run build

Docs / ADR / debt

  • docs updated: yes
  • ADR updated: no
  • debt updated: no
  • details: updated docs/orfe/spec.md; existing invariants and ADRs already cover this command-surface extension and no new durable debt was introduced

Risks / follow-ups

  • partial-failure reporting now includes optional error.details, so callers should tolerate that additional structured field

Copy link
Copy Markdown

@kl4r1554-bot kl4r1554-bot Bot left a comment

Choose a reason for hiding this comment

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

QA Review — issue #128 / PR #129

Decision: APPROVED


What I verified

  • PR is on branch issues/orfe-128 ✅ and Ref: #128 is the first line of the PR body ✅
  • All 319 tests pass (npm test — full run, no failures) ✅
  • npm run lint — clean ✅
  • npm run typecheck — clean ✅
  • npm run build — clean ✅
  • Greg's verification claims are substantiated by local re-run.

Scope and correctness

The implementation matches issue #128 acceptance criteria fully:

  1. Explicit opt-in onlyisProjectAssignmentRequested() gates all project config resolution; resolveProjectAssignmentRequest() returns null unless one of add_to_project, project_owner, project_number, status_field_name, or status is present. Project defaults from config are only read when explicitly opted in — matching Jelena's product direction exactly.

  2. Backward compatibility — test #223 (preserves create-only behavior when repo config has a default project but no project assignment was requested) fires no project API calls when opts are absent. ✅

  3. Create-only — test #69 (CLI) / #220 (core). ✅

  4. Create + project add — tests #70 / #221 with add_to_project: true. ✅

  5. Create + project add + status — test #222 with status: 'Todo' only (no add_to_project: true), confirming that providing status alone is enough to trigger the full pipeline. ✅

  6. Partial failure: project_add stage — tests #71 / #224 confirm the error has the correct code (auth_failed), message that names the created issue, and details.stage: 'project_add' with created_issue identity in the structured payload. ✅

  7. Partial failure: project_status stage — test #225 covers the case where project add succeeds but status mutation fails; error has details.stage: 'project_status' with created_issue, project_owner, project_number, status_field_name, and requested_status. ✅

  8. Config validation fails fastresolveProjectAssignmentRequest() is called before the try block that creates the issue. If the config is missing required project coords, resolveProjectCommandConfig throws with invalid_usage before any REST call is made. No orphan issue created in that path.

  9. Error re-wrapping is clean — project assignment errors thrown as OrfeError pass through mapIssueCreateError's instanceof OrfeError guard unchanged; no double-wrapping.

  10. Architecture invariants — generic runtime boundary preserved; core has no OpenCode-specific dependencies; project operations use GraphQL as required; structured JSON contract maintained for success and error envelopes; error.details field is additive and optional so callers can tolerate its absence.

  11. docs/orfe/spec.md updated with full project-assignment rules, project_assignment success shape, and partial-failure behavior contract. ✅

  12. Plugin schemaadd_to_project correctly added as boolean().optional(); project_owner, project_number, status_field_name, and status were already in the plugin args from prior project commands. ✅

  13. Help output — definition tests confirm --add-to-project and --status <value> appear in the usage string; the CLI "renders leaf help for every agreed V1 command" test includes issue create and passes. ✅


Blockers

None.


Important (non-blocking, follow-up recommended)

successDataExample in definition.ts does not include project_assignment — the command definition's successDataExample only shows the minimal create-only response shape. Agents discovering the command via orfe help --command-name "issue create" will see a success example without project_assignment, which may cause them to silently drop or misinterpret that field. The spec.md and test coverage are correct, but the in-tool help is the primary runtime discovery surface for agents. Recommend a follow-up to add a second annotated example or update the successDataExample to reflect the optional field.


Nice-to-have (no follow-up required unless desired)

  • matchesProjectByOwnerAndNumber and matchesProjectAddItem helper functions are duplicated verbatim between test/core.test.ts and test/cli.test.ts. Extracting them to a shared test utility would reduce drift risk.
  • No test for "project assignment requested but no projects.default configured and no explicit coordinates" — the behavior is correct (throws invalid_usage before creating the issue) but is an untested code path.
  • The getGitHubClient() call inside applyProjectAssignment is a second invocation after the issue is already created. In a degenerate case where token renewal fails between the two calls, the partial-failure error would go through mapIssueCreateError without a stage-aware payload. Extremely unlikely in practice; noted for completeness.

Docs / invariants

  • docs/orfe/spec.md updated ✅. No new ADR required (existing command-surface extension precedent applies). No new debt introduced. Invariants preserved.

@MirzaMerdovic MirzaMerdovic merged commit 05ac8e4 into main Apr 30, 2026
1 check passed
@MirzaMerdovic MirzaMerdovic deleted the issues/orfe-128 branch April 30, 2026 16:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant