Skip to content

ci(e2e): default mention round-trips to self-mention via /myself - #796

Merged
Zious11 merged 3 commits into
developfrom
test/e2e-mention-self-target
Sep 10, 2026
Merged

ci(e2e): default mention round-trips to self-mention via /myself#796
Zious11 merged 3 commits into
developfrom
test/e2e-mention-self-target

Conversation

@Zious11

@Zious11 Zious11 commented Sep 10, 2026

Copy link
Copy Markdown
Owner

[test-infra] E2E mention round-trip: default to self-mention via /myself

Epic: N/A — test-infrastructure + CI enhancement, not a story; does not close an issue
Mode: maintenance (test-infra/CI hardening on top of #674 / #794 / #795)
Convergence: N/A — no story pipeline; changes validated by local build/test/lint + one live-Jira dry run (see Test Evidence)

Tests
Tests
Lint
Workflow

This PR makes the four live-Jira mention round-trip E2E tests (tests/e2e_live.rs, VP-674-014/015/016/017) actually run in the push/nightly e2e.yml job instead of clean-skipping. Previously they were gated on an optional JR_E2E_MENTION_ACCOUNT_ID repo variable that was never set, so the mention round trip against real Jira has never executed in CI since #674/#794/#795 landed. mention_account_id(h) now self-discovers a mention target via GET /rest/api/3/myself when the override is unset, so the tests exercise the real mention ADF-node round trip out of the box. A second, independent commit threads three already-existing optional E2E repo variables (JR_E2E_PARENT_KEY/JR_E2E_CHILD_TYPE/JR_E2E_EDIT_FIELD) plus JR_E2E_JSM_RESOLUTION through e2e.yml, which were documented and read by the test suite but never actually wired into the workflow's env: block — those tests clean-skip exactly as before until a human sets the corresponding repo variables.


Architecture Changes

No src/ production code changed. This PR touches only test infrastructure and CI wiring:

graph TD
    e2e_live["tests/e2e_live.rs\n(mention_account_id)"] -->|"GET /rest/api/3/myself\n(self-discovery, new)"| JiraAPI["Live Jira REST API"]
    e2e_live -->|"JR_E2E_MENTION_ACCOUNT_ID\n(override, unchanged)"| JiraAPI
    e2e_yml[".github/workflows/e2e.yml"] -->|"env: JR_E2E_PARENT_KEY / _CHILD_TYPE / _EDIT_FIELD / _JSM_RESOLUTION\n(newly threaded through)"| e2e_live
    style e2e_live fill:#90EE90
    style e2e_yml fill:#90EE90
Loading
Architecture Decision Record

ADR: Default mention E2E target to self-discovery via /myself rather than requiring a dedicated repo variable

Context: The mention round-trip E2E tests (added by #674/#794, hardened by #795) were gated on JR_E2E_MENTION_ACCOUNT_ID, an optional repo variable that names a controlled test account's accountId. That variable was never set in the canonical repo's jira-e2e GitHub Environment, so all four tests have clean-skipped in every nightly/push e2e.yml run to date — the real Jira mention ADF-node schema has never actually been proven end-to-end in CI.

Decision: mention_account_id(h: &E2eHarness) now takes the harness and, when JR_E2E_MENTION_ACCOUNT_ID is unset or empty, calls GET /rest/api/3/myself and uses the authenticated CI account's own accountId as the mention target (a self-mention). The env var remains a supported override for mentioning a different controlled account.

Rationale: A self-mention still fully validates what these tests exist to prove — that real Jira accepts and persists a mention ADF node with a given accountId — without requiring any additional secret/variable provisioning. It closes the "tests exist but never actually run against live Jira" gap with zero new configuration surface.

Alternatives Considered:

  1. Require a human to set JR_E2E_MENTION_ACCOUNT_ID in the jira-e2e environment — rejected because it depends on an out-of-band manual step that has already gone unset for multiple release cycles; the tests would keep silently skipping.
  2. Hardcode a specific accountId in the test — rejected: brittle across Jira sites/service-account rotations, and CLAUDE.md's "no real data" convention discourages baking in identifiers that look like production secrets.

Consequences:

  • The mention round trip now genuinely executes on every push/nightly e2e.yml run without additional setup.
  • mention_account_id now takes &E2eHarness and performs a network call — clean-skip is now defined as "override unset AND /myself fails/returns no accountId," which only happens if E2E connectivity/auth is already broken (i.e., other E2E tests would also be failing).

Story Dependencies

Not a story — no dependency graph entry. Builds on already-merged work:

graph LR
    S674["#674 / #794\nmention resolution + write-path"] --> THIS["test/e2e-mention-self-target\nthis PR"]
    S795["#795\nmention boundary fix"] --> THIS
    style THIS fill:#FFD700
Loading

Spec Traceability

No BC/AC change — this is test-infra scoped to already-shipped behavioral contracts (mention resolution, #674 line). Traceability is to the existing verification points, not new BCs:

flowchart LR
    VP1["VP-674-014..017\nmention round-trip"] --> T1["test_e2e_mention_*\n(tests/e2e_live.rs)"]
    T1 --> S1["mention_account_id()\nself-discovery via /myself"]
    S1 --> W1["e2e.yml env: block\n(JR_E2E_PARENT_KEY etc.)"]
Loading

Test Evidence

Coverage Summary

Metric Value Threshold Status
cargo build OK compiles PASS
cargo test --test e2e_live --no-run compiles (mention tests still #[ignore]+JR_RUN_E2E-gated) compiles PASS
cargo test --test e2e_cli_surface_guard 10/10 pass 100% PASS
cargo test --test claude_md_citations 61/61 pass 100% PASS
cargo clippy -- -D warnings clean 0 warnings PASS
cargo fmt --all -- --check clean 0 diffs PASS
actionlint .github/workflows/e2e.yml exit 0 0 findings PASS
Live-Jira dry run (self-mention discovery) validated manually end-to-end proof PASS (see below)

Coverage/mutation-kill-rate/holdout metrics are N/A — no src/ production logic changed, so the story-shaped coverage/mutation gates do not apply. ci.yml's sharded mutation gate runs against this PR's diff scope regardless (see Risk Assessment) and is expected to be near-zero mutants given the diff touches only tests/ and CI YAML.

Test Flow

graph LR
    Build["cargo build"]
    NoRun["e2e_live --no-run"]
    Guard["e2e_cli_surface_guard 10/10"]
    Citations["claude_md_citations 61/61"]
    Clippy["clippy -D warnings"]
    Actionlint["actionlint e2e.yml"]
    Live["Live self-mention dry run"]

    Build --> Pass1["PASS"]
    NoRun --> Pass2["PASS"]
    Guard --> Pass3["PASS"]
    Citations --> Pass4["PASS"]
    Clippy --> Pass5["PASS"]
    Actionlint --> Pass6["PASS"]
    Live --> Pass7["PASS"]

    style Pass1 fill:#90EE90
    style Pass2 fill:#90EE90
    style Pass3 fill:#90EE90
    style Pass4 fill:#90EE90
    style Pass5 fill:#90EE90
    style Pass6 fill:#90EE90
    style Pass7 fill:#90EE90
Loading
Metric Value
New tests 0 added; 4 existing tests (test_e2e_mention_*) modified to self-discover a target; helper mention_account_id signature changed (() -> Option<String> to (&E2eHarness) -> Option<String>)
Total suite offline suites unaffected; live-gated suite unchanged in count
Coverage delta N/A — test-only + CI YAML diff
Mutation kill rate N/A — no src/ diff
Regressions 0 — offline guard suites (e2e_cli_surface_guard, claude_md_citations) both green; e2e.yml change is additive env: keys only, no removed/renamed keys
Detailed Test Results

Modified Tests (this PR)

Test Result Notes
test_e2e_mention_comment_add_roundtrip compiles, #[ignore]+JR_RUN_E2E-gated (not run in ci.yml) now defaults to self-mention
test_e2e_mention_issue_create_roundtrip compiles, #[ignore]+JR_RUN_E2E-gated now defaults to self-mention
test_e2e_mention_issue_edit_roundtrip compiles, #[ignore]+JR_RUN_E2E-gated now defaults to self-mention
test_e2e_mention_jsm_create_roundtrip compiles, #[ignore]+JR_RUN_E2E-gated now defaults to self-mention; still additionally gated on JR_E2E_JSM_PROJECT

Live Validation (orchestrator-verified, not part of ci.yml)

Run against a real Jira Cloud instance using a develop-branch build authenticated via an API-token profile: mention_account_id resolved the CI account's own accountId via GET /rest/api/3/myself (no JR_E2E_MENTION_ACCOUNT_ID set), a self-mention comment was posted, the comment was re-fetched and confirmed to contain a mention ADF node with the resolved accountId + display name, and the comment was deleted as part of test cleanup. Per repo convention, no real Jira instance URL, org ID, or project key is included in this PR body.

Coverage Analysis

N/A — no src/ lines added/changed.

Mutation Testing

N/A — no src/ diff; ci.yml's sharded mutation gate (mutants-planmutants shards → mutants-aggregate) will still run per its normal in-diff scoping and is expected to find ~0 in-scope mutants for a tests/+YAML-only diff.


Demo Evidence

N/A — test-infrastructure + CI enhancement with no product UI/behavior change (per dispatch: "Step 2 verify-demo-evidence = N/A ... record as such, do not block"). There is no docs/demo-evidence/<STORY-ID>/ to populate because this PR is not a story and has no acceptance criteria to demo. In place of per-AC demo recordings, the "Live Validation" subsection under Test Evidence documents an orchestrator-run, live-Jira verification of the actual behavior change (self-mention discovery via GET /rest/api/3/myself round-tripping through a real comment).


Holdout Evaluation

N/A — evaluated at wave gate / story pipeline only. This is a maintenance-mode test-infra change, not a story delivery.


Adversarial Review

N/A — evaluated at Phase 5 / story pipeline only. Standard pr-reviewer + security-reviewer dispatch (below) substitutes for this on non-story PRs per PR Manager Step 4/5.


Security Review

Verdict: APPROVE — no findings requiring changes. Reviewed by vsdd-factory:security-reviewer against git diff cef4a021..92da86cc.

graph LR
    Critical["Critical: 0"]
    High["High: 0"]
    Medium["Medium: 0"]
    Low["Low: 0"]
    Info["Info: 2"]

    style Critical fill:#90EE90
    style High fill:#90EE90
    style Medium fill:#90EE90
    style Low fill:#90EE90
    style Info fill:#87CEEB
Loading
Security Scan Details

Findings

  • No CRITICAL, HIGH, MEDIUM, or LOW findings.
  • INFO-1 (clean data minimization): mention_account_id(h: &E2eHarness) checks JR_E2E_MENTION_ACCOUNT_ID first (explicit override preserved, unchanged precedence) and only falls back to GET /rest/api/3/myself when unset/empty. The /myself response is narrowed to exactly one field (accountId) — no other field (email, displayName, timezone) is captured, logged, or forwarded. The mentioned identity is, by construction, the same CI service account whose credentials already drive the harness — never a third party. This is a safety improvement over the prior design (which trusted, but did not mechanically enforce, that a human-supplied override named a controlled test account).
  • INFO-2 (workflow YAML correctness): the four new env: entries (JR_E2E_PARENT_KEY, JR_E2E_CHILD_TYPE, JR_E2E_EDIT_FIELD, JR_E2E_JSM_RESOLUTION) are all non-secret configuration, correctly sourced from ${{ vars.* }} (not ${{ secrets.* }}), and are only ever consumed as env: mapping values passed to cargo test — never spliced into a run: script body via ${{ }} templating, so no GitHub Actions script-injection (CWE-78) surface is introduced.
  • INFO-3 (pre-existing, out-of-scope): docs/specs/e2e-live-jira-testing.md's config table carries an example JR_E2E_MENTION_ACCOUNT_ID value with the shape of a real (24-hex-char) Atlassian accountId. git log -S confirms this predates this PR (added in feat(mentions): effectful mention resolution + write-path wiring (S-cycle5-mention-resolution-wiring) #794/0eaf4268) — this PR only edits adjoining prose in the same row and leaves that value byte-for-byte unchanged. Flagged for optional follow-up per repo convention (never include real Jira identifiers in public content); not a defect introduced by this PR and not blocking.

Dependency Audit

  • No Cargo.toml/Cargo.lock changes in this PR — cargo deny check scope unaffected.

Formal Verification

  • N/A — no src/ logic changed.

Risk Assessment & Deployment

Blast Radius

  • Systems affected: tests/e2e_live.rs (test-only), .github/workflows/e2e.yml (CI workflow), CLAUDE.md + docs/specs/e2e-live-jira-testing.md (docs).
  • User impact: None — no src/ production code changed; jr binary behavior is unaffected.
  • Data impact: The mention round-trip tests now write a real (self-)mention comment/issue/JSM-request against the E2E Jira site on every push/nightly e2e.yml run and clean up via existing Drop-guard/self-close patterns (unchanged cleanup mechanism, just now actually exercised). No change to the target Jira site's production data (E2E-only site).
  • Risk Level: LOW.

Performance Impact

Metric Before After Delta Status
e2e.yml job duration baseline +1 extra GET /myself call per mention test (×4, only when override unset) negligible (single lightweight authenticated GET) OK
CI (ci.yml) unaffected unaffected none — mention tests remain #[ignore]+JR_RUN_E2E-gated, inert in ci.yml OK
Rollback Instructions

Immediate rollback (< 5 min):

git revert <merge_commit_sha>
git push origin develop

If feature-flagged: N/A — no feature flag; behavior is entirely test-infra/CI-scoped and reverting removes the self-discovery default, reverting to permanent clean-skip (safe, non-breaking).

Verification after rollback:

  • cargo test --test e2e_live --no-run still compiles.
  • e2e.yml's env: block reverts to the pre-PR variable set; parent/child/edit-field/resolution variables stop being passed (tests continue clean-skipping as before this PR).

Feature Flags

None.


Traceability

Requirement Story AC Test Verification Status
Mention round-trip actually exercised in CI (not just clean-skipped) VP-674-014/015/016/017 (pre-existing) test_e2e_mention_* (4 tests) Live-Jira manual verification (see Test Evidence) PASS
Already-documented optional E2E vars reach the workflow N/A (test-infra follow-up, not a BC) actionlint .github/workflows/e2e.yml Static YAML lint PASS
Full VSDD Contract Chain
VP-674-014 -> test_e2e_mention_issue_create_roundtrip -> tests/e2e_live.rs -> live-verified self-mention -> N/A (no story pipeline)
VP-674-015 -> test_e2e_mention_issue_edit_roundtrip -> tests/e2e_live.rs -> live-verified self-mention -> N/A
VP-674-016 -> test_e2e_mention_comment_add_roundtrip -> tests/e2e_live.rs -> live-verified self-mention -> N/A
VP-674-017 -> test_e2e_mention_jsm_create_roundtrip -> tests/e2e_live.rs -> compiles; gated on JR_E2E_JSM_PROJECT -> N/A

AI Pipeline Metadata

Pipeline Details
ai-generated: true
pipeline-mode: maintenance
factory-version: "1.0.0"
pipeline-stages:
  spec-crystallization: skipped (not a story)
  story-decomposition: skipped (not a story)
  tdd-implementation: completed (test-infra change, pre-existing tests modified)
  holdout-evaluation: skipped (N/A for maintenance mode)
  adversarial-review: completed (pr-reviewer dispatch, this PR)
  formal-verification: skipped (no src/ diff)
  convergence: N/A
generated-at: "2026-09-09"

Pre-Merge Checklist

  • All CI status checks passing
  • Coverage delta is positive or neutral (N/A diff — no coverage-relevant src/ change)
  • No critical/high security findings unresolved
  • Rollback procedure validated (plain git revert, no data migration)
  • Feature flag configured (if applicable) — N/A, none
  • Human review completed (if autonomy level requires) — per merge guardrails, human review required if any check needs admin-bypass/force
  • Monitoring alerts configured (if production-impacting) — N/A, non-production-impacting

…R_E2E_MENTION_ACCOUNT_ID gate)

The four live-Jira mention round-trip E2E tests (VP-674-014/015/016/017)
previously clean-skipped unless JR_E2E_MENTION_ACCOUNT_ID was set,
requiring a separately-configured account seam to run in CI at all.

mention_account_id() now takes the harness and self-discovers a mention
target via GET /rest/api/3/myself when the env var is unset/empty,
mentioning the authenticated CI account's own accountId (bracket-form
[~accountid:<id>], so there's no display-name ambiguity concern). This
still fully validates the round trip: real Jira accepting and persisting
the mention node with that accountId is what's being proven, independent
of whose accountId it is. JR_E2E_MENTION_ACCOUNT_ID remains as an optional
override to mention a different controlled account.

Test-infra + docs only; no src/ changes.

Claude-Session: https://claude.ai/code/session_01FitXFyeeyQ7zUuRVTgb7hd

@Zious11 Zious11 left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Verdict: APPROVE (ready to merge). Posted as a COMMENT review rather than an APPROVE review only because GitHub refuses Can not approve your own pull request — the gh credential in this environment is the PR author. The verdict below is the reviewer's actual verdict; a formal approving review still needs a second GitHub account (code-owner approval is required by branch protection regardless).

Fresh-eyes PR review — PR #796

Verdict: APPROVE. No blocking findings. One SUGGESTION and three NITs, none of which need to hold up the merge.

Scope reviewed: git diff cef4a021..92da86cc — 4 files, +62/-32. Base (develop) is at cef4a021, identical to this PR's merge-base, so the tested tree is the merged tree (relevant given strict: false on develop).


What I verified (not a rubber stamp)

Check Result
cargo clippy --tests --all-features -- -D warnings on PR head clean
cargo test --test e2e_cli_surface_guard 10/10 pass — jr api path still declared in SURFACE; parser-consistency guard did not flag the new mention_account_id invocation
cargo test --test claude_md_citations 61/61 pass
cargo test --test e2e_live (offline guards) 30 pass / 77 ignored — incl. test_every_ignored_test_has_gate_guard and test_no_test_function_exceeds_line_budget (the latter matters: the four skip messages grew)
actionlint .github/workflows/e2e.yml exit 0
YAML duplicate-key scan (strict PyYAML loader that raises on any duplicate mapping key) none; the 4 new keys land at the correct 10-space indent inside the Run live E2E tests step's env: mapping, sourced from ${{ vars.* }} (not secrets.*) and never spliced into a run: body
Every new e2e.yml comment vs. the code it describes accurate — JR_E2E_PARENT_KEY/JR_E2E_CHILD_TYPE really are independently _ => return gated (so "both must be set" holds), JR_E2E_EDIT_FIELD really requires a = (Ok(f) if f.contains('=')), and JR_E2E_JSM_RESOLUTION really is checked first in jsm_discover_resolution before the jr issue resolutions fallback
mention_account_id precedence env override first (trimmed, non-empty) → return; only then /myself. Matches both the rustdoc and the CLAUDE.md / spec prose exactly
Clean-skip semantics still correct yes — fetch_raw returns None on spawn failure, non-zero exit, or unparseable JSON, so mention_account_idNone → early return with a [SKIP] line, never a panic or a false-green
Teardown for the now-actually-running tests unchanged and adequate — MentionCommentDropGuard on the comment path, --label e2e-<run_id> + best_effort_close on create/edit, jsm_self_close on the JSM path
Commit hygiene two cleanly-scoped Conventional Commits; commit 1 is tests+docs only, commit 2 is e2e.yml only. Diff is 94 lines total, well under the 500-line flag
PR description vs. diff accurate, including the "no src/ change" claim (git diff --stat confirms: no src/ file touched)

The core design call is sound. A self-mention proves exactly what VP-674-014/015/016/017 exist to prove — that live Jira accepts and persists a mention ADF node carrying a given accountId — and the round trip is genuinely independent of whose accountId it is. Trading an out-of-band manual variable for a runtime /myself lookup is the right call for tests that have silently never executed.


Findings

# Severity Category Finding
1 suggestion missing JR_E2E_MENTION_ACCOUNT_ID is documented as a settable jira-e2e environment variable but is not threaded through e2e.yml — the documented override is unreachable in CI
2 nit description The four [SKIP] messages describe a narrower condition than the one that actually triggers them
3 nit coherence mention_account_id runs the same /myself lookup four times per suite run
4 nit coherence In the JSM test, the harness/mention-target resolution was hoisted above the JR_E2E_JSM_PROJECT gate

1. JR_E2E_MENTION_ACCOUNT_ID override is documented but not wired into e2e.yml — SUGGESTION

docs/specs/e2e-live-jira-testing.md §8 — the table headed "Configuration inventory (GitHub Environment jira-e2e)" — now lists JR_E2E_MENTION_ACCOUNT_ID as variable (optional override) and instructs the reader in bold: "Set this var only to mention a different CONTROLLED test account instead." CLAUDE.md carries the same claim. But JR_E2E_MENTION_ACCOUNT_ID appears nowhere in .github/workflows/e2e.yml (grep MENTION → no match), so a maintainer who follows that instruction and sets the variable will see no effect: the tests will keep self-mentioning, silently.

This is a pre-existing gap (the variable was never wired), so it is not a defect this PR introduces, and I am not blocking on it. I am raising it because it is the same defect class commit 92da86cc exists to fix — its own message says these vars were "documented and read by the test suite but never actually wired into the workflow's env: block" — and because commit c0322efc strengthens the doc's assertion that the override is available. Fixing it is one line in the block this PR already edits:

          # Optional override: a CONTROLLED test account's accountId to mention instead of
          # the authenticated CI account. Unset → the four test_e2e_mention_* tests
          # self-discover the target via GET /rest/api/3/myself (self-mention default).
          JR_E2E_MENTION_ACCOUNT_ID: ${{ vars.JR_E2E_MENTION_ACCOUNT_ID }}

Alternatively, if leaving it unwired is deliberate (e.g. you want the self-mention path to be the only CI behavior), say so in the doc row so the bolded "Set this var" instruction isn't misleading. Either resolution is fine; the current state — documented-as-settable, not settable — is the one to avoid.

2. [SKIP] messages name a narrower cause than the one that fires them — NIT

All four messages read ... and GET /rest/api/3/myself returned no accountId .... mention_account_id also returns None when fetch_raw fails to spawn the subprocess, gets a non-zero exit, or cannot parse the stdout as JSON — none of which is "returned no accountId". Operationally nothing is lost, because fetch_raw already prints a [WARN] fetch_raw: ... line naming the real cause immediately above. Worth noting that the rustdoc on mention_account_id gets this exactly right ("the /myself lookup fails or carries no accountId") — it is only the four user-facing strings that narrow it. Something like ... and GET /rest/api/3/myself did not yield an accountId ... would cover both.

3. Four identical /myself subprocess calls per run — NIT

mention_account_id(&h) is called once per test, so a full live run spawns jr api /rest/api/3/myself four times with an identical result. Harmless — the suite runs --test-threads=1 and this is a trivial authenticated GET, matching the PR's own "negligible" assessment. A static OnceLock<Option<String>> would collapse it to one if you ever want it; not worth churning the diff for now.

4. JSM test: mention-target resolution hoisted above the JSM-project gate — NIT

In test_e2e_mention_jsm_create_roundtrip, let h = e2e_harness(); + mention_account_id(&h) now sit ahead of the JR_E2E_JSM_PROJECT check. When that variable is unset, the test now pays for a /myself round trip before skipping, and reports the mention-target skip reason rather than the more specific "JSM project not configured" one. Cosmetic only, and moot in the canonical repo where JR_E2E_JSM_PROJECT=EJ is set. The equivalent hoist in the other three tests is required (the harness is now a parameter) and correct; only here is the gate ordering swappable, and only here does swapping buy anything.


Checklist results

  1. Diff coherence — PASS. Two commits, cleanly separated, both on-topic. No unrelated changes; no src/ touched.
  2. Description accuracy — PASS. Every claim I spot-checked (clippy clean, 10/10 + 61/61 guards, actionlint exit 0, no src/ diff, additive-only env: keys) holds.
  3. Test coverage — PASS (with the caveat inherent to the change). No new offline test is possible here: the whole point is a live-Jira-gated path. The offline guards that can cover it (e2e_cli_surface_guard, test_every_ignored_test_has_gate_guard, test_no_test_function_exceeds_line_budget) all pass, and the PR body records an orchestrator-run live verification of the self-discovery path.
  4. Demo evidence — N/A, correctly declared. Not a story, no ACs to demo, no product behavior change. The live-Jira dry-run write-up under Test Evidence is the right substitute.
  5. Commit quality — PASS. Conventional Commits, scoped subjects, informative bodies.
  6. Diff size — PASS. 94 lines across 4 files.
  7. Missing changes — see finding 1 (the one thing the diff arguably should have included, non-blocking).
  8. Dependency status — PASS. #674/#794/#795 are all merged; branch is even with develop at cef4a021, MERGEABLE, no rebase needed.

Verdict: APPROVE. Merge when CI is green. Finding 1 is worth resolving either here or in a follow-up — your call which.

Comment thread .github/workflows/e2e.yml
# Optional: resolution name override for jsm_self_close teardown and
# test_e2e_jsm_resolution_enforcement (S-JSM-E2E-3). Auto-discovered from
# `jr issue resolutions` when unset.
JR_E2E_JSM_RESOLUTION: ${{ vars.JR_E2E_JSM_RESOLUTION }}

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[SUGGESTION] This block now threads four previously-unwired optional vars through — good, and exactly the right fix. But JR_E2E_MENTION_ACCOUNT_ID has the identical defect and is not included, even though commit c0322efc in this same PR strengthens the doc claim that it works.

docs/specs/e2e-live-jira-testing.md §8 ("Configuration inventory (GitHub Environment jira-e2e)") now lists it as variable (optional override) and tells the reader in bold: "Set this var only to mention a different CONTROLLED test account instead." CLAUDE.md says the same. But grep MENTION .github/workflows/e2e.yml returns nothing — so a maintainer who follows that instruction gets no effect at all: the tests keep self-mentioning, silently. That is the same "documented and read by the test suite but never actually wired into the workflow's env: block" condition this commit's own message describes.

Pre-existing, so not blocking. One line in the block you're already editing:

          # Optional override: a CONTROLLED test account's accountId to mention instead of
          # the authenticated CI account. Unset → the four test_e2e_mention_* tests
          # self-discover the target via GET /rest/api/3/myself (self-mention default).
          JR_E2E_MENTION_ACCOUNT_ID: ${{ vars.JR_E2E_MENTION_ACCOUNT_ID }}

If leaving it unwired is deliberate, that's fine too — but then soften the bolded "Set this var" instruction in the doc so it doesn't promise a knob that isn't connected.

Comment thread tests/e2e_live.rs
Ok(v) if !v.trim().is_empty() => return Some(v.trim().to_string()),
_ => {}
}
fetch_raw(h, "/rest/api/3/myself").and_then(|v| {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[NIT] Precedence, trimming, and the clean-skip contract all look right here, and the rustdoc above describes the None case accurately ("the /myself lookup fails or carries no accountId").

The four [SKIP] strings below are narrower than that: they all say "GET /rest/api/3/myself returned no accountId", but fetch_raw also returns None when the subprocess fails to spawn, exits non-zero, or emits unparseable JSON. Nothing is lost operationally — fetch_raw prints a [WARN] fetch_raw: ... line naming the real cause right above — so this is purely about the message matching the condition. ... did not yield an accountId ... would cover both.

[NIT, same site] mention_account_id(&h) is called once per test, so a full live run spawns jr api /rest/api/3/myself four times for an identical answer. Harmless at --test-threads=1 for a trivial GET (your "negligible" call in the PR body is right); a static OnceLock<Option<String>> would make it one if you ever care.

Comment thread tests/e2e_live.rs
return;
}
let Some(account_id) = mention_account_id() else {
let h = e2e_harness();

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

[NIT] The harness hoist is required in the other three tests (the harness is now a parameter to mention_account_id), but here it also moves the /myself lookup ahead of the JR_E2E_JSM_PROJECT gate on line 13738. Consequence when that var is unset: the test pays for a /myself round trip before skipping, and reports "could not determine a mention target" instead of the more specific "JR_E2E_JSM_PROJECT not set".

Cosmetic, and moot in the canonical repo where JR_E2E_JSM_PROJECT=EJ. Moving the jsm_project match above the mention_account_id call would restore the cheaper/more precise ordering, since the JSM gate needs no harness.

@Zious11

Zious11 commented Sep 10, 2026

Copy link
Copy Markdown
Owner Author

Review Cycle 1 Triage (PR Manager)

pr-reviewer verdict: APPROVE (0 blocking findings). Posted as GitHub review #5161821110 — see that review for the full findings with file/line references.

Finding Severity Routed To Status
JR_E2E_MENTION_ACCOUNT_ID documented as a settable override but never threaded into e2e.yml's env: block (same defect class this PR already fixes for JR_E2E_PARENT_KEY/_CHILD_TYPE/_EDIT_FIELD/_JSM_RESOLUTION) Suggestion (non-blocking) Fixing in this PR (in scope, mirrors existing pattern) In progress
3 nits (see inline review comments) Nit Accepted as-is, no action No action needed

Note on review mechanics: the reviewing agent's gh credential is the same account that authored this PR, so GitHub rejected a formal APPROVE-type review (422: Review Can not approve your own pull request — a platform rule, not a tooling limitation). The verdict above was instead posted as a COMMENT-type review with the APPROVE assessment stated in the body. This means no code-owner approval currently exists on this PR, and per this repo's branch protection (develop requires code owner approval), an actual human (or different-account) approval is still required before merge — independent of CI outcome. Flagging this now for the human who dispatched this pipeline.

Security review (Step 4): APPROVE, 0 critical/high/medium/low findings (2 info-level notes, one pre-existing/out-of-scope). See PR description's Security Review section.

JR_E2E_MENTION_ACCOUNT_ID is documented in CLAUDE.md and
docs/specs/e2e-live-jira-testing.md as an optional override for the
mention round-trip tests' self-mention default, and
tests/e2e_live.rs's mention_account_id() helper already reads it via
env::var — but it was never added to e2e.yml's "Run live E2E tests"
env: block. The repo variable could be set in the jira-e2e GitHub
Environment but would never reach the test process, making the
documented override unreachable from CI.

Add JR_E2E_MENTION_ACCOUNT_ID: ${{ vars.JR_E2E_MENTION_ACCOUNT_ID }}
next to the related JR_E2E_JSM_RESOLUTION entry, following this PR's
existing pattern for optional vars.

Claude-Session: https://claude.ai/code/session_01FitXFyeeyQ7zUuRVTgb7hd
@Zious11
Zious11 merged commit 6e125b7 into develop Sep 10, 2026
24 checks passed
@Zious11
Zious11 deleted the test/e2e-mention-self-target branch September 10, 2026 12:25
Zious11 added a commit that referenced this pull request Sep 10, 2026
Records a completed MAINTENANCE bookkeeping event in STATE.md — no
phase transition, no cycle change, pipeline stays PAUSED. Root
CLAUDE.md was compacted and merged to develop @ a1f3799 via PR #797
(163,850->89,634 bytes, -45%; 458->397 lines); CI-gate round-1->16 +
S-CIGATE-3 history extracted verbatim to docs/specs/ci-gate-completeness.md;
ADF/attachment/JR_* gotchas condensed to operative-rule+pointer;
live-state markers preserved; 2 MEDIUM operative-loss findings caught
and fixed pre-merge.

Appended a Phase Progress row, a Historical Content pointer row, and 3
open (not resolved) Drift/Standing-Items follow-ups: E2E-dynamic WIP
branch redundancy-vs-#796 decision pending, STATE.md size-budget
/compact-state candidate, and a vsdd-factory compact-claude-md
engine-gap candidate. Recomputed wc -l and refreshed the SIZE BUDGET
banner (428 lines). version: 4.00->4.01 (exactly one bump). No count
change (754 BCs/76 VPs/118 holdouts/175 stories).

Folds in concurrent benign churn already present in the worktree
(regression-state.json command/timestamp update, sidecar-learning.md
session-ended log lines, and the CLAUDE.md-compaction research file +
its RESEARCH-INDEX.md entry, referenced by this STATE.md update),
matching this repo's established precedent for reconciling such
churn into the same atomic burst rather than committing separately.

Claude-Session: https://claude.ai/code/session_01RT2HKoqmH3Yf9Dyn5v5oeX
Zious11 added a commit that referenced this pull request Sep 10, 2026
…namic, no static vars)

Mirrors the self-mention `/myself` default (PR #796): JR_E2E_PARENT_KEY,
JR_E2E_CHILD_TYPE, and JR_E2E_EDIT_FIELD become optional overrides instead
of required pairings.

- test_e2e_issue_parent_roundtrip: discovers the project's sub-task issue
  type via GET /rest/api/3/project/<key> when JR_E2E_CHILD_TYPE is unset,
  and seeds a fresh throwaway parent via seed_issue when JR_E2E_PARENT_KEY
  is unset. New ParentChildDropGuard closes the seeded parent (never a
  caller-supplied override) plus the created child on teardown. Asserts
  fields.parent.key via a fresh fetch_raw GET rather than the create
  response.
- test_e2e_issue_edit_custom_field: discovers a safe string field via
  GET .../editmeta when JR_E2E_EDIT_FIELD is unset — preferring the
  standard "Environment" field, else the first other editable string
  field excluding summary/description — writes a benign generated value,
  and verifies it via a fresh GET. The override path is unchanged.

Docs: docs/specs/e2e-live-jira-testing.md §8 and CLAUDE.md's E2E env-var
reference now describe all three vars as optional overrides with dynamic
defaults, matching JR_E2E_MENTION_ACCOUNT_ID's documented pattern.

Claude-Session: https://claude.ai/code/session_01FitXFyeeyQ7zUuRVTgb7hd
Zious11 added a commit that referenced this pull request Sep 10, 2026
…namic, no static vars) (#798)

Mirrors the self-mention `/myself` default (PR #796): JR_E2E_PARENT_KEY,
JR_E2E_CHILD_TYPE, and JR_E2E_EDIT_FIELD become optional overrides instead
of required pairings.

- test_e2e_issue_parent_roundtrip: discovers the project's sub-task issue
  type via GET /rest/api/3/project/<key> when JR_E2E_CHILD_TYPE is unset,
  and seeds a fresh throwaway parent via seed_issue when JR_E2E_PARENT_KEY
  is unset. New ParentChildDropGuard closes the seeded parent (never a
  caller-supplied override) plus the created child on teardown. Asserts
  fields.parent.key via a fresh fetch_raw GET rather than the create
  response.
- test_e2e_issue_edit_custom_field: discovers a safe string field via
  GET .../editmeta when JR_E2E_EDIT_FIELD is unset — preferring the
  standard "Environment" field, else the first other editable string
  field excluding summary/description — writes a benign generated value,
  and verifies it via a fresh GET. The override path is unchanged.

Docs: docs/specs/e2e-live-jira-testing.md §8 and CLAUDE.md's E2E env-var
reference now describe all three vars as optional overrides with dynamic
defaults, matching JR_E2E_MENTION_ACCOUNT_ID's documented pattern.

Claude-Session: https://claude.ai/code/session_01FitXFyeeyQ7zUuRVTgb7hd
Zious11 added a commit that referenced this pull request Sep 10, 2026
…nding item (v4.01->4.02)

WIP branch test/e2e-dynamic-parent-editfield was confirmed NOT redundant
with #796 (distinct area: create --parent / edit --field self-configuring
live-E2E tests, built atop #796); rebased onto develop, exit-gates
verified green, local code-reviewer CLEAN, and MERGED to develop @
3a874d9 via PR #798. Worktree .worktrees/E2E-DYNAMIC and both
local+remote branches cleaned up; local develop fast-forwarded to
3a874d9.

- Marked E2E-CI-DYNAMIC-TESTS-WIP-UNVERIFIED RESOLVED in Drift/Standing
  Items (SESSION-WRAP PAUSE table) and its cross-note under
  MAINTENANCE-CLAUDE-MD-COMPACTION-2026-09-10 item 1
- Appended Phase Progress row E2E-CI-DYNAMIC-TESTS-DELIVERED-2026-09-10
  (COMPLETE, no quality gate)
- Added one new OPEN follow-up: E2E-DISCOVER-SAFE-EDIT-FIELD-VALIDATED-SUBTYPE
  (LOW/MEDIUM, non-blocking, from PR #798 code review)
- Left the other two MAINTENANCE follow-ups intact (STATE.md /compact-state
  candidate; vsdd-factory compact-claude-md engine-gap)

Pipeline stays PAUSED throughout -- no phase transition, no cycle change.
Counts unchanged (754 BCs / 76 VPs / 118 holdouts / 175 stories).
Recomputed wc -l and refreshed the SIZE BUDGET banner: 428 -> 444 lines.

Folds in benign concurrent churn (regression-state.json command/timestamp
bump, sidecar-learning.md routine session-ended log lines) per the
established single-atomic-commit pattern.

Claude-Session: https://claude.ai/code/session_01RT2HKoqmH3Yf9Dyn5v5oeX
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