Skip to content

feat(code): add optional Jira workflow transitions - #2005

Open
ederign wants to merge 2 commits into
fullsend-ai:mainfrom
ederign:feat/618-jira-pr-ready-transition
Open

ederign wants to merge 2 commits into
fullsend-ai:mainfrom
ederign:feat/618-jira-pr-ready-transition

Conversation

@ederign

@ederign ederign commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds optional named Jira transitions after accepted code preflight and after the code agent produces an open, non-draft PR/MR. Both settings default to off; Jira controls allowed source states.

Release dependency: fullsend-ai/fullsend#9437 merged as 2cf5b8f9953c3cbea391d043ee412b342dc30fdf. Its transition CLI contract matches the implementation tested with this PR. Keep this PR on hold until a tagged Fullsend release includes that commit. The current v0.56.0 tag points to the earlier b2945ba14789828dae7a6b99a192c83f00b90981 and does not contain issues transition. The minimum supported release will be documented once it is available.

This is the code-agent integration for the shared transition work in fullsend#6704, building on fullsend#8920 and agents#1843. Protected harness/script changes remain subject to maintainer approval.

Configuration and behavior

Configure runner settings through a derived code harness (base: composition), following ADR 0080. The historical smoke test used:

env:
  runner:
    CODE_JIRA_STARTED_TRANSITION: "In Progress"
    CODE_JIRA_PR_READY_TRANSITION: "Refinement"

The test workflow had no Review state, so we used its Refinement transition instead. This is a test-specific choice, not a product default. Teams configure named transitions available in their workflows.

  • Started runs after accepted Jira preflight, before sandbox creation. Skips/failures do not transition; a later sandbox failure does not roll it back.
  • PR-ready runs after the Jira stage comment succeeds and the forge confirms an open, non-draft PR/MR. GitHub and GitLab targets are supported.
  • Optional transition failures warn without failing coding/publication or retrying the transition. Failure diagnostics redact the Jira token/email in-process before logging; they do not export the Jira token to a PATH-resolved redaction utility. Unconfirmed readiness produces an explicit skip message.
  • Jira credentials remain on the runner; this does not claim isolation from arbitrary same-user process inspection.

Later draft-to-ready events and merged-PR transitions remain out of scope.

Validation

Generated bundles match source. Bundled Jira preflight and complete bundled post-code tests pass on macOS with modern Bash, including GitHub/GitLab failed-transition cases with a shadowed awk and literal-pattern credentials. All-files pre-commit and make lint pass. All source test recipes passed across the original run and resumed runs. Two unchanged host-specific fixtures needed local tool setup: an isolated pinned gitleaks directory to preserve test mocks, and GNU sed for the existing scribe regexes. This was not one uninterrupted green make script-test run.

An isolated regression probe demonstrates that the old failure path exports a synthetic credential to shadowed awk despite clean logs; the fixed path emits redacted diagnostics without that exposure.

Historical live testing exercised a real local code run and open non-draft GitHub PR, with Jira moving New → In Progress → Refinement. That evidence predates this error-path fix; it is not a new live rerun. GitLab coverage is automated, not a live MR run. Internal identifiers and screenshots are omitted from this public description; detailed evidence remains local.

Upstream functional tests require a writer's /ok-to-test <latest-head-SHA> approval. A blocked authorization gate is not a functional test result.

Signed-off-by: Eder Ignatowicz <ignatowicz@gmail.com>
@ederign
ederign requested a review from a team as a code owner November 13, 2026 18:41
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add opt-in Jira transitions for code preflight and PR readiness

✨ Enhancement 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add independent, disabled-by-default Jira transitions after accepted code preflight and confirmed
 PR/MR readiness.
• Keep Jira credentials on the runner and make optional transition failures nonfatal.
• Document configuration and test both workflows across GitHub, GitLab, Linux, and macOS.
Diagram

graph TD
  Config["Runner settings"] --> Preflight["Jira preflight"] --> Started{"Started enabled?"} --> StartWrite["Jira started"] --> Sandbox["Code sandbox"] --> Post["Post-code comment"] --> Ready{"Open non-draft?"} --> ReadyWrite["Jira PR-ready"]
  Started -->|off| Sandbox
Loading
High-Level Assessment

The runner-side, opt-in approach fits the existing pre/post-script boundaries and keeps Jira credentials out of the sandbox. A later forge-event listener could detect draft-to-ready changes, but would expand the feature beyond readiness observed during this code run; central configuration would also depart from the documented harness-override model.

Files changed (8) +605 / -34

Enhancement (4) +222 / -12
post-code.shAdd PR-ready transition to bundled post-code script +51/-6

Add PR-ready transition to bundled post-code script

• After a successful Jira stage comment, checks the current PR/MR state and optionally invokes the named transition. Makes credential descriptor restoration portable beyond /proc and keeps transition failures nonfatal.

scripts/post-code.sh

post-code.src.shAdd optional PR-ready transition to post-code source +51/-6

Add optional PR-ready transition to post-code source

• Gates the transition on an explicitly open, non-draft GitHub PR or GitLab MR after the Jira comment succeeds. Uses runner-held credentials, avoids retries, and warns on failed optional writes.

scripts/post-code.src.sh

pre-code-jira.shAdd started transition to bundled Jira preflight +60/-0

Add started transition to bundled Jira preflight

• Withholds inherited Jira credentials before dependency setup and resolves the trusted CLI before PATH changes. After accepted preflight, optionally runs the named transition without failing coding if the write fails.

scripts/pre-code-jira.sh

pre-code-jira.src.shAdd optional started transition to Jira preflight source +60/-0

Add optional started transition to Jira preflight source

• Re-executes with Jira credentials removed from the inherited environment, then checks runner identity and prerequisites before an optional post-preflight transition. Skipped or failed preflight never reaches the write.

scripts/pre-code-jira.src.sh

Tests (2) +315 / -20
post-code-test.shTest PR-ready transitions across GitHub and GitLab +140/-17

Test PR-ready transitions across GitHub and GitLab

• Extends forge and CLI fixtures to exercise ready, draft, closed, malformed, existing-PR, disabled, and failure cases. Adds credential-isolation checks with platform-aware Linux /proc expectations.

scripts/post-code-test.sh

pre-code-jira-test.shCover started-transition timing and credential isolation +175/-3

Cover started-transition timing and credential isolation

• Tests opt-in behavior, preflight skips, identity conflicts, missing prerequisites, service-account auth, and nonfatal transition failures. Verifies dependency tools cannot inherit Jira credentials or shadow the trusted CLI.

scripts/pre-code-jira-test.sh

Documentation (1) +63 / -0
code.mdDocument optional Jira transitions and their limits +63/-0

Document optional Jira transitions and their limits

• Explains runner-only configuration, when each named transition runs, prerequisites, credential handling, and nonfatal failure behavior. Clarifies that later readiness events and merge transitions are out of scope.

docs/code.md

Other (1) +5 / -2
code.yamlDefault both Jira transitions to off on the runner +5/-2

Default both Jira transitions to off on the runner

• Adds independent runner settings without exposing them to the sandbox. Updates the Jira credential comment to cover the pre-code transition.

harness/code.yaml

@fullsend-ai-review

fullsend-ai-review Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:43 PM UTC · Completed 6:53 PM UTC

Commit: 6f89879 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $2.42

@qodo-code-review

qodo-code-review Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Failed started transitions give no reason why ✓ Resolved

Resolving commit: b7cfba2

Resolution reason
Failure output of the started transition is now captured, token and email are redacted in-process,
each line is sanitized and printed to the log before the existing warning, so operators can see the
actual cause (e.g., unknown subcommand, bad transition name, auth error).
Description
_jira_transition_started sends the CLI's stdout and stderr to /dev/null and logs only a generic
warning, while the post-code path redacts the token and prints the CLI output. The `issues
transition` subcommand only exists in newer fullsend releases, so a too-old runner CLI, a misspelled
transition name, a transition not allowed from the current status, and an auth error all produce the
same warning, and operators have nothing to tell them apart.


Informational

2. Non-ready PRs skip the transition with no log line ✓ Resolved

Resolving commit: b7cfba2

Resolution reason
Added an echo line before the early return in maybe_transition_jira_pr_ready in both
scripts/post-code.sh and scripts/post-code.src.sh: "PR/MR is not confirmed open and non-draft;
skipping the optional Jira PR-ready transition". This logs the skip reason, as the suggested fix
requested. The fix does not include the observed state/draft values, but the log line itself
addresses the finding. Also added a test asserting the message appears for unconfirmed readiness.
Description
When the forge reports a draft, closed, merged or malformed PR/MR, maybe_transition_jira_pr_ready
returns 0 without printing anything. That happens whenever the jq readiness filter does not match,
including an MR that is already merged because auto-merge was enabled just before this check. An
operator who configured CODE_JIRA_PR_READY_TRANSITION then sees no transition and no log
explaining why.

Grey Divider

Context sources
✅ Linked PRs:
  🌐 PR #1843
❌ Tickets: failed to load — Ticket collection could not establish complete evidence
✅ Compliance rules (platform): 55 rules
✅ Skills: 4 invoked
  code-review
  code-implementation
  pr-review
  docs-review
✅ Web pages:
  +2 more
✅ Cross-repo context — repo relationships
  Explored: repo: fullsend-ai/fullsend (sha: c74c65fd) — View relationship
Review mode: Auto: 🧠 Deep: Security-sensitive shell changes span multiple independent pre/post paths.

Grey Divider

Tip of the day
💡 Did you know, you can start a comment with 'qodo' or '@qodo' to chat about any finding

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread scripts/pre-code-jira.src.sh Resolved
Comment thread scripts/post-code.src.sh Resolved
@fullsend-ai-review fullsend-ai-review Bot added the risk/elevated PR risk: elevated label Nov 13, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Risk Assessment: elevated (3/5)

Details

Elevated risk due to extensive modifications across seven protected harness and script paths with high recent churn and multi-author contention in target scripts.

Previous run

Risk Assessment: elevated (3/5)

Details

Elevated risk due to extensive modifications across seven protected harness and script paths with high recent churn and multi-author contention in target scripts.

@fullsend-ai-review

fullsend-ai-review Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Review

Findings

Medium

  • [protected-path] harness/code.yaml — This PR modifies protected governance/infrastructure paths: harness/code.yaml, scripts/post-code.sh, scripts/post-code.src.sh, scripts/post-code-test.sh, scripts/pre-code-jira.sh, scripts/pre-code-jira.src.sh, scripts/pre-code-jira-test.sh. The description explains the rationale and cites the related work, but human approval is always required for protected-path changes regardless of context.
  • [missing-authorization] PR-level — The change adds optional Jira workflow transitions across the harness and the pre/post-code scripts. It is a non-trivial feature, and no issue in this repository is linked to authorize that scope. The description cites only external issues (fullsend#6704, fullsend#8920) and agents#1843, none of which were verified.
    Remediation: Link an approved issue in fullsend-ai/agents that authorizes the scope, or get explicit maintainer authorization.

Earlier findings

  • scripts/post-code.src.sh:624, secret-exposure — resolved. The PR-ready failure path now redacts the Jira token and email with in-process Bash substitution before any external sanitizer. The token is no longer passed to the PATH-resolved _redact_literal_token helper.
  • docs/code.md:53, doc-style — resolved. The typographic apostrophes were replaced with ASCII apostrophes.
  • scripts/post-code.src.sh:41, pattern-inconsistency — resolved. CODE_JIRA_PR_READY_TRANSITION was added to the header comment's optional-variable list.
Previous run

<!-- fullsend:review-findings-v2:eyJ2ZXJzaW9uIjoyLCJhY3Rpb24iOiJyZXF1ZXN0LWNoYW5nZXMiLCJmaW5kaW5ncyI6W3sic2V2ZXJpdHkiOiJtZWRpdW0iLCJjYXRlZ29yeSI6InNlY3JldC1leHBvc3VyZSIsImZpbGUiOiJzY3JpcHRzL3Bvc3QtY29kZS5zcmMuc2giLCJpZCI6ImZfN2NhNzIyZDBmYjEyMjI3YyIsImxpbmUiOjYyNCwiYWN0aW9uYWJsZSI6dHJ1ZSwiZGltZW5zaW9uIjoic2VjdXJpdHkifSx7InNldmVyaXR5IjoibWVkaXVtIiwiY2F0ZWdvcnkiOiJtaXNzaW5nLWF1dGhvcml6YXRpb24iLCJmaWxlIjpudWxsLCJpZCI6ImZfMDc0YWFiNDU5NmU0NjQ0NCIsImFjdGlvbmFibGUiOmZhbHNlLCJkaW1lbnNpb24iOiJpbnRlbnQtY29oZXJlbmNlIn0seyJzZXZlcml0eSI6ImxvdyIsImNhdGVnb3J5IjoiZG9jLXN0eWxlIiwiZmlsZSI6ImRvY3MvY29kZS5tZCIsImlkIjoiZl9kMjZjODk3MTlmNDcwMjc4IiwibGluZSI6NTMsImFjdGlvbmFibGUiOnRydWUsImRpbWVuc2lvbiI6InN0eWxlLWNvbnZlbnRpb25zIn0seyJzZXZlcml0eSI6ImxvdyIsImNhdGVnb3J5IjoicGF0dGVybi1pbmNvbnNpc3RlbmN5IiwiZmlsZSI6InNjcmlwdHMvcG9zdC1jb2RlLnNyYy5zaCIsImlkIjoiZl9lY2M4NDljODcxMTMxZjkwIiwibGluZSI6NDEsImFjdGlvbmFibGUiOnRydWUsImRpbWVuc2lvbiI6InN0eWxlLWNvbnZlbnRpb25zIn1dfQ== -->

Review

Findings

Medium

  • [secret-exposure] scripts/post-code.src.sh:624 — When the optional PR-ready transition fails, maybe_transition_jira_pr_ready passes _jira_token_saved to _redact_literal_token, which exports it as REDACT_LITERAL_TOKEN and runs awk by name, so PATH decides which binary runs. This happens after line 909 prepends ${HOME}/.local/bin to PATH and after repo-controlled pre-commit hooks/tool installs have run. A malicious hook can plant an awk there and capture the Jira write token whenever the (opt-in, default off) transition fails. This bypasses the script's own Jira credential isolation design (the fullsend CLI path is pinned at line 783 for this reason); before this change nothing passed the Jira token to _redact_literal_token.
    Remediation: Redact in-process in Bash without exporting the token or calling an external program (e.g. output="${output//"${_jira_token_saved}"/[REDACTED]}"), or resolve a trusted absolute awk path before repo-controlled code runs. Re-run make script-build and add a regression test that shadows awk and forces a transition failure.

  • [protected-path] harness/code.yaml, scripts/post-code.sh, scripts/post-code.src.sh, scripts/post-code-test.sh, scripts/pre-code-jira.sh, scripts/pre-code-jira.src.sh, scripts/pre-code-jira-test.sh — This PR modifies governance/infrastructure files under protected paths (harness/, scripts/). The description explains the rationale, but human approval is always required for protected-path changes, regardless of context.

  • [missing-authorization] N/A — This non-trivial change adds optional Jira workflow transitions across the harness config, pre/post scripts, tests and docs, but links no issue in fullsend-ai/agents defining its scope. The PR body cites external sources instead (Jira AISDLC-618, Write triage and code results to the Jira work item fullsend#8920 and #6704, dependency PR feat(issues): add tracker-neutral issue transitions fullsend#9437). Both features are off by default and the scope matches those references; this is an authorization-trail concern.
    Remediation: Link a tracking issue in fullsend-ai/agents that defines the scope, or confirm the upstream fullsend issue is the accepted authorization for this lockstep repo.

Low

  • [doc-style] docs/code.md:53 — Curly apostrophes (U+2019) are used at lines 53, 54, 404 and 429 (harness’s, team’s, PR/MR’s); the rest of the repo's markdown docs use straight ASCII apostrophes.
    Remediation: Replace ’ with ' at docs/code.md lines 53, 54, 404 and 429.

  • [pattern-inconsistency] scripts/post-code.src.sh:41 — CODE_JIRA_PR_READY_TRANSITION (read at line 595) is missing from the header's Optional environment variables: list (lines 40-55), whereas scripts/pre-code-jira.src.sh lists CODE_JIRA_STARTED_TRANSITION in its header (lines 29-30).
    Remediation: Add CODE_JIRA_PR_READY_TRANSITION to that header in scripts/post-code.src.sh, then run make script-build to regenerate scripts/post-code.sh.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

fullsend-ai-review[bot]

This comment was marked as outdated.

fullsend-ai-review[bot]

This comment was marked as outdated.

Redact Jira credentials in Bash before external log sanitizers, preserve
started-transition diagnostics, and log skipped PR-ready transitions.
Cover hostile PATH utilities and literal credential patterns in tests,
update environment documentation, and regenerate script bundles.

Signed-off-by: Eder Ignatowicz <ignatowicz@gmail.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 7:33 PM UTC · Completed 7:43 PM UTC

Commit: b7cfba2 · View workflow run →

Runtime: pi · Model: sonnet → claude-sonnet-5-5 · Effort: high · Cost: $1.72

@fullsend-ai-review
fullsend-ai-review Bot dismissed their stale review November 13, 2026 19:43

Superseded by updated review

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Nov 13, 2026
Comment thread docs/code.md
PR/MR's current state from GitHub or GitLab. Only an explicitly open,
non-draft PR/MR permits the shared `fullsend issues transition --transition`
command to run. It uses the same validated source issue and runner-only
Jira credentials as the comment. Both transition settings require a fullsend

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[MEDIUM] Depends on an unmerged, unreleased fullsend CLI subcommand; the docs link an issue instead of a release

Both new transitions (maybe_transition_jira_pr_ready in scripts/post-code.src.sh and _jira_transition_started in scripts/pre-code-jira.src.sh) call fullsend issues transition --tracker jira ... --transition NAME. That subcommand only exists in fullsend-ai/fullsend#9437 ("feat(issues): add tracker-neutral issue transitions"), which is still open and unmerged. The latest fullsend release, v0.55.0, does not include it.

These lines say both settings "require a fullsend release containing the shared transition command", but the link points to issue fullsend#6704 and names no version. Both test suites mock the fullsend binary, so nothing checks the real CLI contract. If #9437 renames a flag or changes behaviour before it merges, every opted-in run only logs a generic "Optional Jira ... transition failed" warning.

Suggestion:

  • Hold the merge until fullsend#9437 merges and ships in a tagged release.
  • Then replace the issue link with the minimum version (for example "requires fullsend >= vX.Y.Z").
  • Optionally, when a transition is enabled, probe for the subcommand first ("$bin" issues transition --help >/dev/null 2>&1) and print a clear "requires fullsend >= vX.Y.Z" warning instead of the generic failure.

@ederign ederign Nov 13, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agree @waynesun09 ! @fullsend-ai/maintainers please hold this PR until fullsend#9437 merges and ships, then I'll update the docs with the minimum supported version. I tested the integration locally against the #9437 build.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

9437 is merged now.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test requires-manual-review Review requires human judgment risk/elevated PR risk: elevated

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants