Skip to content
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions docs/ADRs/0071-jira-project-enrollment-via-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: "71. Jira project enrollment via fullsend CLI"

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.

[CRITICAL] ADR number 0071 collides with open PR #2791 (and #5016)

PR #2791 ("docs: ADR 0071 — Auto-merge", OPEN, last updated 2026-07-22) already adds docs/ADRs/0071-auto-merge.md. This PR's final commit (d011f220, "rescope and renumber ADR 0069 → 0071") renumbered specifically to dodge the collision with docs/ADRs/0069-ready-made-configuration-presets.md on main, but landed on a second, still-live collision that was never checked. Filenames differ (0071-jira-project-enrollment-via-cli.md vs 0071-auto-merge.md), so git raises no conflict — whichever PR merges second silently creates a duplicate ADR-71.

hack/lint-adr-numbers only finds docs/ADRs/*.md in the current checkout, so it structurally can't see other open PRs' number claims. main today has 0069, 0070, then jumps straight to 0073 — 0071 and 0072 are both already claimed by other in-flight PRs: #2791 (0071) and #5016 (0072, "pre-script output protocol"). This repo has hit this exact failure mode before — PR #5524 originally proposed ADR 0071 for a different topic and had to rename to 0077 after a prior collision.

Suggestion: Before merge, check every open PR touching docs/ADRs/ for a number that's free on both main and all open PRs, then update the filename, frontmatter title, H1 heading, and the docs/architecture.md cross-reference together. Coordinate with #2791 so only one PR keeps a given number.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — renumbered to 0079 using the inflight-adr-numbers.sh script to verify it's free on both main and all open PRs.

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.

[HIGH] PR title says "ADR 0069" but this file is ADR 0071

The PR title is "docs(adr): ADR 0069 — Jira project enrollment via fullsend CLI," but the file this PR actually adds is docs/ADRs/0071-jira-project-enrollment-via-cli.md (frontmatter title and H1 both say "71. ..."). The final commit renumbered 0069 → 0071 to avoid colliding with the existing docs/ADRs/0069-ready-made-configuration-presets.md on main, but the PR title was never updated. If this merges via GitHub's default squash (which seeds the commit subject from the PR title), main's permanent history will misidentify this as "ADR 0069" — in a repo that runs a dedicated CI check (hack/lint-adr-numbers) specifically to keep ADR identifiers unambiguous.

Suggestion: Update the PR title to "docs(adr): ADR 0071 — Jira project enrollment via fullsend CLI" before merge (or whatever number results from resolving the #2791 collision noted in the other comment on this line).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — PR title updated to "docs(adr): ADR 0079 — Jira project setup via fullsend CLI".

status: Accepted
relates_to:
- agent-infrastructure
topics:
- jira
- enrollment
- external-issue-trackers
- credentials
---

# 71. Jira project enrollment via fullsend CLI

Date: 2026-07-09

## Status

Accepted

## Context

Fullsend's dispatch model (see [agent-infrastructure](../problems/agent-infrastructure.md))
uses pluggable input drivers to normalize events from multiple sources
([ADR 0061](0061-harness-cel-dispatch.md)). For Jira, the poll driver
([ADR 0063](0063-polling-based-work-discovery.md)) discovers work items
via JQL and dispatches agents through the shared pipeline. ADR 0063
defers credential placement as an open question — Jira API tokens need
to reach the poll driver and agent pre-scripts, but no ADR specifies
how those credentials are provisioned or where enrollment metadata lives.

A proof-of-concept ([manish-jira](https://github.com/rh-hemartin-fullsendai/manish-jira))
validated end-to-end Jira-to-agent dispatch. The enrollment steps
(credential provisioning, config updates) were entirely manual; the
CLI automates them.

## Options

### Option 1: Manual credential setup per documentation

Operators follow a guide to create forge secrets and edit
`.fullsend/config.yaml` by hand. Rejected — error-prone for multi-project
setups and inconsistent across forges.

### Option 2: `fullsend jira enroll` CLI command

A CLI command provisions credentials and writes enrollment metadata.
Follows established CLI patterns (cobra subcommands, `--dry-run`).

## Decision

Add a `fullsend jira enroll <target-repo>` CLI command that provisions
Jira API credentials as forge secrets and writes enrollment metadata to
`.fullsend/config.yaml`. The command resolves Jira credentials via
environment variables or CLI flags and supports `--dry-run`.

Enrollment writes Jira project entries to the `integrations.jira` key
in `.fullsend/config.yaml` (project key, host URL). Poll driver
configuration in `poll.input_drivers[].connection` references this
metadata. Credentials are stored as forge-level secrets (not checked
into the repository), compatible with
[ADR 0017](0017-credential-isolation-for-sandboxed-agents.md)'s
credential isolation model. Ensuring credentials stay outside the agent
sandbox is the harness author's responsibility (via `runner_env` and

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.

[HIGH] Cites deprecated runner_env as the current sandbox-isolation mechanism

This line attributes credential isolation to "runner_env and pre/post scripts." runner_env is deprecated repo-wide: CONTRIBUTING.md's own deprecation-annotation example uses this exact key (runner_env: # Deprecated: use env.runner instead), and docs/ADRs/0024-harness-definitions.md carries an explicit amendment note: "Amended by ADR 0055, which introduces a unified env: key with runner/sandbox sub-maps and deprecates runner_env." A new Accepted ADR citing the deprecated key as the current mechanism bakes stale guidance into a permanent architecture record.

Suggestion: Replace runner_env with env.runner/env.sandbox (per ADR 0055), or cite the relevant ADR by number only (as this ADR already does for ADR 0017 elsewhere) so the reference doesn't go stale again if the schema changes further.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — replaced with env.runner / env.sandbox and added ADR 0055 citation in both Decision and Consequences sections.

pre/post scripts).

Enrollment is idempotent — re-running with a new token rotates the

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] Idempotent token rotation is asserted as settled behavior for a CLI command that doesn't exist yet

This states flatly: "Enrollment is idempotent — re-running with a new token rotates the secret." No forge-specific secrets API (GitHub Actions secrets vs. GitLab CI/CD variables, etc.) is named as having been verified against this claim, and the ADR's own Context says the only cited evidence — the manish-jira PoC — had enrollment steps that "were entirely manual." This is an implementation guarantee for a not-yet-built command, presented as already-proven fact.

Suggestion: Soften to an intended contract ("enrollment is designed to be idempotent...") and track per-forge verification as an open item, the way ADR 0063 tracks its own open questions in a "Resolve in" table.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — softened to "designed to be idempotent" with per-forge verification tracked as an implementation concern.

secret. The enrollment scope is credentials and config only; the dispatch
mechanism is the poll driver's responsibility
([ADR 0063](0063-polling-based-work-discovery.md)), and agent-level
Jira awareness (harness `pre_script`, `forge:` overrides via

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] ADR 0045's forge: overrides are the wrong hook for "Jira-aware" agent behavior

This attributes "agent-level Jira awareness" to "harness pre_script, forge: overrides via ADR 0045." ADR 0045's forge: block is keyed by code-hosting platform identifiers (forge.github, forge.gitlab — "Each key under forge: is a platform identifier") to select forge-specific tooling. ADR 0063 models Jira as a poll input driver (jira-poll), a separate axis from forge: a GitHub-hosted repo polling Jira still has forge: github, so this mechanism provides no hook for "Jira-specific" behavior distinct from "GitHub-specific" behavior.

Suggestion: Either drop the ADR 0045 citation and describe Jira-aware pre/post scripts as plain, driver-agnostic top-level pre_script/post_script fields, or call out a genuinely new per-input-driver override hook as a gap against ADR 0045/0063 rather than citing ADR 0045 as if it already covers it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — ADR 0045 citation removed. Jira-aware behavior is now attributed to plain pre_script / post_script fields only.

[ADR 0045](0045-forge-portable-harness-schema.md)) is the repo admin's
responsibility.

## Consequences

- Jira credential provisioning is automated and consistent across forges.
- Credentials are stored as forge secrets, compatible with
[ADR 0017](0017-credential-isolation-for-sandboxed-agents.md)'s
isolation model. Sandbox isolation is enforced downstream by harness
configuration (`runner_env`, pre/post scripts), not by enrollment.
- ADR 0063's open question on credential placement is resolved for the
enrollment path; poll drivers read connection metadata from
`integrations.jira`.
- Jira API token rotation is the repo admin's responsibility — re-running
`fullsend jira enroll` with a new token updates the secret.
- Repo-to-issue association is out of scope — the poll driver
([ADR 0063](0063-polling-based-work-discovery.md)) handles which
issues route to which repositories.
1 change: 1 addition & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ the dedicated org-level `<org>/.fullsend` config repo is deprecated
- Dispatch version-skew resolution: per-repo `reusable-dispatch.yml` inlines stage workflow jobs directly, eliminating `@v0` references to `reusable-{stage}.yml` ([ADR 0062](ADRs/0062-dispatch-version-skew.md)).
- Ready-made configuration presets: `fullsend github setup --config <path-or-url>` installs a vendor preset as `.fullsend/config.base.yaml` and a stub `.fullsend/config.yaml` overlay in the target repository; mint URL, inference backend, and related settings live in configuration files resolved through accessor methods, not CLI flags. Shared-infrastructure presets will reduce per-adopter enrollment (target state): mint via `job_workflow_ref` trust per [ADR 0059](ADRs/0059-public-mint-mode-with-wildcard-allowlists.md); inference authorization model undecided ([ADR 0069](ADRs/0069-ready-made-configuration-presets.md)); enrollment remains required until follow-on ADRs land.
- GitLab event dispatch: two-path model — native CI triggers (`merge_request_event`) for MR events, cron-based polling for issues/comments/labels. No external infrastructure (no webhook bridge). Bot PAT via OIDC/WIF from Secret Manager or protected CI/CD variable. Per-repo only ([ADR 0067](ADRs/0067-gitlab-cron-polling-event-dispatch.md)).
- Jira project enrollment: `fullsend jira enroll` CLI command provisions Jira API credentials as forge secrets and writes enrollment metadata to `.fullsend/config.yaml` under `integrations.jira` ([ADR 0071](ADRs/0071-jira-project-enrollment-via-cli.md)). Poll drivers ([ADR 0063](ADRs/0063-polling-based-work-discovery.md)) reference this metadata for connection config; repo-to-issue association is handled by the poll driver design.

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] "Enrollment" now names three distinct concepts in this document

This line adds "Jira project enrollment" alongside two pre-existing, unrelated uses of the same word a few lines above in this same living document: the installer's EnrollmentLayer/ordered-layer-stack concept ("...→ dispatch → enrollment ([ADR 0006])" and "The CLI's EnrollmentLayer.Install()...") and generic per-adopter onboarding ("Shared-infrastructure presets will reduce per-adopter enrollment"). Both the installer sense and this PR's sense involve secret/credential provisioning, which makes the three uses easy to conflate for future readers.

Suggestion: Use a more specific term for this feature (e.g., "Jira project registration/connection"), or add a one-line disambiguation in the ADR's Context distinguishing it from the ADR 0006 EnrollmentLayer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — architecture.md now uses "Jira project connection" and explicitly disambiguates from the EnrollmentLayer (ADR 0006). The ADR Decision section also includes a disambiguation line.


**Open questions:**

Expand Down